[ARM] Prevent continuous folding of SUBC
authorDavid Green <david.green@arm.com>
Wed, 15 Sep 2021 10:23:32 +0000 (11:23 +0100)
committerDavid Green <david.green@arm.com>
Wed, 15 Sep 2021 10:23:32 +0000 (11:23 +0100)
Under some situations under Thumb1, we could be stuck in an infinite
loop recombining the same instruction. This puts a limit on that, not
combining SUBC with SUBE repeatedly.

llvm/lib/Target/ARM/ARMISelLowering.cpp
llvm/test/CodeGen/ARM/select_const.ll

index 0f7c58b..3585921 100644 (file)
@@ -12774,7 +12774,7 @@ static SDValue PerformAddcSubcCombine(SDNode *N,
                                       const ARMSubtarget *Subtarget) {
   SelectionDAG &DAG(DCI.DAG);
 
-  if (N->getOpcode() == ARMISD::SUBC) {
+  if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
     // (SUBC (ADDE 0, 0, C), 1) -> C
     SDValue LHS = N->getOperand(0);
     SDValue RHS = N->getOperand(1);
index 03f538e..e12dd02 100644 (file)
@@ -758,3 +758,52 @@ define i64 @opaque_constant2(i1 %cond, i64 %x) {
   ret i64 %bo
 }
 
+define i64 @func(i64 %arg) {
+; ARM-LABEL: func:
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    adds r0, r0, #1
+; ARM-NEXT:    mov r2, #0
+; ARM-NEXT:    adcs r0, r1, #0
+; ARM-NEXT:    mov r1, #0
+; ARM-NEXT:    adcs r0, r2, #0
+; ARM-NEXT:    movne r0, #8
+; ARM-NEXT:    mov pc, lr
+;
+; THUMB2-LABEL: func:
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    adds r0, #1
+; THUMB2-NEXT:    mov.w r2, #0
+; THUMB2-NEXT:    adcs r0, r1, #0
+; THUMB2-NEXT:    mov.w r1, #0
+; THUMB2-NEXT:    adcs r0, r2, #0
+; THUMB2-NEXT:    it ne
+; THUMB2-NEXT:    movne r0, #8
+; THUMB2-NEXT:    bx lr
+;
+; THUMB-LABEL: func:
+; THUMB:       @ %bb.0: @ %entry
+; THUMB-NEXT:    .save {r4, lr}
+; THUMB-NEXT:    push {r4, lr}
+; THUMB-NEXT:    movs r2, #0
+; THUMB-NEXT:    adds r3, r0, #1
+; THUMB-NEXT:    push {r1}
+; THUMB-NEXT:    pop {r3}
+; THUMB-NEXT:    adcs r3, r2
+; THUMB-NEXT:    push {r2}
+; THUMB-NEXT:    pop {r3}
+; THUMB-NEXT:    adcs r3, r2
+; THUMB-NEXT:    subs r4, r3, #1
+; THUMB-NEXT:    adds r0, r0, #1
+; THUMB-NEXT:    adcs r1, r2
+; THUMB-NEXT:    sbcs r3, r4
+; THUMB-NEXT:    lsls r0, r3, #3
+; THUMB-NEXT:    movs r1, r2
+; THUMB-NEXT:    pop {r4}
+; THUMB-NEXT:    pop {r2}
+; THUMB-NEXT:    bx r2
+entry:
+  %0 = add i64 %arg, 1
+  %1 = icmp ult i64 %0, 1
+  %2 = select i1 %1, i64 8, i64 0
+  ret i64 %2
+}