[ARM] ADD with a negative offset can become SUB for free
authorJames Molloy <james.molloy@arm.com>
Fri, 9 Sep 2016 13:35:36 +0000 (13:35 +0000)
committerJames Molloy <james.molloy@arm.com>
Fri, 9 Sep 2016 13:35:36 +0000 (13:35 +0000)
So model that directly in TTI::getIntImmCost().

llvm-svn: 281044

llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
llvm/test/CodeGen/ARM/immcost.ll

index 13d57c0..10e6297 100644 (file)
@@ -73,6 +73,10 @@ int ARMTTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
       // Conversion to BIC is free, and means we can use ~Imm instead.
       return std::min(getIntImmCost(Imm, Ty), getIntImmCost(~Imm, Ty));
 
+  if (Opcode == Instruction::Add)
+    // Conversion to SUB is free, and means we can use -Imm instead.
+    return std::min(getIntImmCost(Imm, Ty), getIntImmCost(-Imm, Ty));
+
   if (Opcode == Instruction::ICmp && Imm.isNegative() &&
       Ty->getIntegerBitWidth() == 32) {
     int64_t NegImm = -Imm.getSExtValue();
index 43a4989..1b05ffb 100644 (file)
@@ -71,3 +71,20 @@ true:
 ret:
   ret void
 }
+
+; CHECK: Function: test_add_neg
+; CHECK-NOT: Collect constant i32 -5
+define void @test_add_neg(i1 %cond, i32 %arg, i32 %arg2) {
+entry:
+  %a = add i32 %arg, -5
+  call void @g(i32 %a)
+  br i1 %cond, label %true, label %ret
+
+true:
+  %b = add i32 %arg2, -5
+  call void @g(i32 %b)
+  br label %ret
+
+ret:
+  ret void
+}