[llvm] r297682 - [Thumb1] combine ADDC/SUBC with a negative immediate

Artyom Skrobov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 13 15:36:14 PDT 2017


Author: askrobov
Date: Mon Mar 13 17:36:14 2017
New Revision: 297682

URL: http://llvm.org/viewvc/llvm-project?rev=297682&view=rev
Log:
[Thumb1] combine ADDC/SUBC with a negative immediate

Summary: This simple optimization has been split out of https://reviews.llvm.org/D30400

Reviewers: efriedma, jmolloy

Subscribers: llvm-commits, rengolin

Differential Revision: https://reviews.llvm.org/D30829

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/test/CodeGen/Thumb/long.ll

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=297682&r1=297681&r2=297682&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 13 17:36:14 2017
@@ -9660,6 +9660,24 @@ static SDValue PerformUMLALCombine(SDNod
     return SDValue();
 }
 
+static SDValue PerformAddcSubcCombine(SDNode *N, SelectionDAG &DAG,
+                                      const ARMSubtarget *Subtarget) {
+  if (Subtarget->isThumb1Only()) {
+    SDValue RHS = N->getOperand(1);
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {
+      int64_t imm = C->getSExtValue();
+      if (imm < 0) {
+        SDLoc DL(N);
+        RHS = DAG.getConstant(-imm, DL, MVT::i32);
+        unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
+                                                           : ARMISD::ADDC;
+        return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
+      }
+    }
+  }
+  return SDValue();
+}
+
 static SDValue PerformAddeSubeCombine(SDNode *N, SelectionDAG &DAG,
                                       const ARMSubtarget *Subtarget) {
   if (Subtarget->isThumb1Only()) {
@@ -11729,6 +11747,8 @@ SDValue ARMTargetLowering::PerformDAGCom
   case ISD::OR:         return PerformORCombine(N, DCI, Subtarget);
   case ISD::XOR:        return PerformXORCombine(N, DCI, Subtarget);
   case ISD::AND:        return PerformANDCombine(N, DCI, Subtarget);
+  case ARMISD::ADDC:
+  case ARMISD::SUBC:    return PerformAddcSubcCombine(N, DCI.DAG, Subtarget);
   case ARMISD::SUBE:    return PerformAddeSubeCombine(N, DCI.DAG, Subtarget);
   case ARMISD::BFI:     return PerformBFICombine(N, DCI);
   case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=297682&r1=297681&r2=297682&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Mar 13 17:36:14 2017
@@ -1453,12 +1453,6 @@ def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:
 def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
             (tCMPr   tGPR:$Rn, tGPR:$Rm)>;
 
-// Subtract with carry
-def : T1Pat<(ARMaddc tGPR:$lhs, imm0_7_neg:$rhs),
-            (tSUBSi3 tGPR:$lhs, imm0_7_neg:$rhs)>;
-def : T1Pat<(ARMaddc tGPR:$lhs, imm8_255_neg:$rhs),
-            (tSUBSi8 tGPR:$lhs, imm8_255_neg:$rhs)>;
-
 // Bswap 16 with load/store
 def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)),
             (tREV16 (tLDRHi t_addrmode_is2:$addr))>;

Modified: llvm/trunk/test/CodeGen/Thumb/long.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/long.ll?rev=297682&r1=297681&r2=297682&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb/long.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb/long.ll Mon Mar 13 17:36:14 2017
@@ -132,8 +132,7 @@ entry:
 ; CHECK: sbcs r1, r2
 }
 
-define i64 @f9d(i64 %x, i32 %y) { ; SUBS with small negative imm => SUBS reg
-; FIXME: this would be better lowered as an `ADDS imm`
+define i64 @f9d(i64 %x, i32 %y) { ; SUBS with small negative imm => ADDS imm
 entry:
         %conv = sext i32 %y to i64
         %shl = shl i64 %conv, 32
@@ -141,9 +140,7 @@ entry:
         %sub = sub nsw i64 %x, %or
         ret i64 %sub
 ; CHECK-LABEL: f9d:
-; CHECK: movs r3, #0
-; CHECK: mvns r3, r3
-; CHECK: subs r0, r0, r3
+; CHECK: adds r0, r0, #1
 ; CHECK: sbcs r1, r2
 }
 
@@ -187,11 +184,12 @@ entry:
         %tmp2 = add i64 %tmp1, -1000
         ret i64 %tmp2
 ; CHECK-LABEL: f11:
+; CHECK: movs r0, #125
+; CHECK: lsls r0, r0, #3
 ; CHECK: movs r1, #0
-; CHECK: ldr  r0,
-; CHECK: adds r2, r2, r0
+; CHECK: subs r2, r2, r0
 ; CHECK: sbcs r3, r1
-; CHECK: adds r0, r2, r0
+; CHECK: subs r0, r2, r0
 ; CHECK: sbcs r3, r1
 ; CHECK: movs r1, r3
 }




More information about the llvm-commits mailing list