ART: Transform Sub+Sub into Sub+Add to merge Shl

In the instruction sequence like the following:
  t1 = Shl(a, n)
  t2 = Sub(t1, *)
  r  = Sub(*, t2)
Shl cannot be merged with Sub. However it can be done when the first Sub
operands are reordered and the second Sub is replaced with Add:
  t1 = Shl(a, n)
  t2 = Sub(*, t1)
  r  = Add(*, t2)

This CL implements this transformation in the ARM/ARM64 instruction simplifiers.

Test: 411-checker-instruct-simplifier-hrem
Test: test.py --host --optimizing --jit --gtest --interpreter
Test: test.py --target --optimizing --jit --interpreter
Test: run-gtests.sh
Change-Id: I24fde29d307f3ad53a8df8bbafe945b4f733ce6c
diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc
index 0f30f66..dc60ba6 100644
--- a/compiler/optimizing/instruction_simplifier_shared.cc
+++ b/compiler/optimizing/instruction_simplifier_shared.cc
@@ -336,4 +336,26 @@
   return true;
 }
 
+bool TryReplaceSubSubWithSubAdd(HSub* last_sub) {
+  DCHECK(last_sub->GetRight()->IsSub());
+  HBasicBlock* basic_block = last_sub->GetBlock();
+  ArenaAllocator* allocator = basic_block->GetGraph()->GetAllocator();
+  HInstruction* last_sub_right = last_sub->GetRight();
+  HInstruction* last_sub_left = last_sub->GetLeft();
+  if (last_sub_right->GetUses().HasExactlyOneElement()) {
+    // Reorder operands of last_sub_right: Sub(a, b) -> Sub(b, a).
+    HInstruction* a = last_sub_right->InputAt(0);
+    HInstruction* b = last_sub_right->InputAt(1);
+    last_sub_right->ReplaceInput(b, 0);
+    last_sub_right->ReplaceInput(a, 1);
+
+    // Replace Sub(c, Sub(a, b)) with Add(c, Sub(b, a).
+    HAdd* add = new (allocator) HAdd(last_sub->GetType(), last_sub_left, last_sub_right);
+    basic_block->ReplaceAndRemoveInstructionWith(last_sub, add);
+    return true;
+  } else {
+    return false;
+  }
+}
+
 }  // namespace art