From 2c5b9e376bbad446971f308b526b18fefcf8d304 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 27 Feb 2017 21:30:54 +0000 Subject: [PATCH] [ARM] don't transform an add(ext Cond), C to select unless there's a setcc of the condition The transform in question claims to be doing: // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c)) ...starting in PerformADDCombineWithOperands(), but it wasn't actually checking for a setcc node for the sext/zext patterns. This is exactly the opposite of a transform I'd like to add to DAGCombiner's foldSelectOfConstants(), so I was seeing infinite loops with my draft of a patch applied. The changes in select_const.ll look positive (less instructions). The change in arm-and-tst-peephole.ll is unrelated. We're changing the input IR in that test to preserve the intent of the test, but that's not affected by this code change. Differential Revision: https://reviews.llvm.org/D30355 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296389 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 2 +- test/CodeGen/ARM/arm-and-tst-peephole.ll | 22 +++++++++++++--------- test/CodeGen/ARM/select_const.ll | 8 +++----- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index ccebf465fc55..76df9a570157 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -9163,7 +9163,7 @@ static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDLoc dl(N); EVT VT = N->getValueType(0); CC = N->getOperand(0); - if (CC.getValueType() != MVT::i1) + if (CC.getValueType() != MVT::i1 || CC.getOpcode() != ISD::SETCC) return false; Invert = !AllOnes; if (AllOnes) diff --git a/test/CodeGen/ARM/arm-and-tst-peephole.ll b/test/CodeGen/ARM/arm-and-tst-peephole.ll index 76dfb11d44da..eed21b6b4d4c 100644 --- a/test/CodeGen/ARM/arm-and-tst-peephole.ll +++ b/test/CodeGen/ARM/arm-and-tst-peephole.ll @@ -140,7 +140,7 @@ return: ; preds = %bb2, %bb, %entry ; folding of unrelated tests (in this case, a TST against r1 was eliminated in ; favour of an AND of r0). -define i32 @test_tst_assessment(i1 %lhs, i1 %rhs) { +define i32 @test_tst_assessment(i32 %a, i32 %b) { ; ARM-LABEL: test_tst_assessment: ; ARM: @ BB#0: ; ARM-NEXT: and r0, r0, #1 @@ -150,11 +150,13 @@ define i32 @test_tst_assessment(i1 %lhs, i1 %rhs) { ; ; THUMB-LABEL: test_tst_assessment: ; THUMB: @ BB#0: -; THUMB-NEXT: movs r2, #1 -; THUMB-NEXT: ands r2, r0 -; THUMB-NEXT: subs r0, r2, #1 +; THUMB-NEXT: push {r0} +; THUMB-NEXT: pop {r2} +; THUMB-NEXT: movs r0, #1 +; THUMB-NEXT: ands r0, r2 +; THUMB-NEXT: subs r2, r0, #1 ; THUMB-NEXT: lsls r1, r1, #31 -; THUMB-NEXT: bne .LBB2_2 +; THUMB-NEXT: beq .LBB2_2 ; THUMB-NEXT: @ BB#1: ; THUMB-NEXT: push {r2} ; THUMB-NEXT: pop {r0} @@ -176,10 +178,12 @@ define i32 @test_tst_assessment(i1 %lhs, i1 %rhs) { ; V8-NEXT: it ne ; V8-NEXT: subne r0, #1 ; V8-NEXT: bx lr - %lhs32 = zext i1 %lhs to i32 - %rhs32 = zext i1 %rhs to i32 - %diff = sub nsw i32 %lhs32, %rhs32 - ret i32 %diff + %and1 = and i32 %a, 1 + %sub = sub i32 %and1, 1 + %and2 = and i32 %b, 1 + %cmp = icmp eq i32 %and2, 0 + %sel = select i1 %cmp, i32 %and1, i32 %sub + ret i32 %sel } !1 = !{!"branch_weights", i32 1, i32 1, i32 3, i32 2 } diff --git a/test/CodeGen/ARM/select_const.ll b/test/CodeGen/ARM/select_const.ll index 50c36310b2ce..52d9af0399c2 100644 --- a/test/CodeGen/ARM/select_const.ll +++ b/test/CodeGen/ARM/select_const.ll @@ -98,9 +98,8 @@ define i32 @select_0_or_neg1_signext(i1 signext %cond) { define i32 @select_0_or_neg1_alt(i1 %cond) { ; CHECK-LABEL: select_0_or_neg1_alt: ; CHECK: @ BB#0: -; CHECK-NEXT: mov r1, #1 -; CHECK-NEXT: bic r0, r1, r0 -; CHECK-NEXT: rsb r0, r0, #0 +; CHECK-NEXT: and r0, r0, #1 +; CHECK-NEXT: sub r0, r0, #1 ; CHECK-NEXT: mov pc, lr %z = zext i1 %cond to i32 %add = add i32 %z, -1 @@ -110,8 +109,7 @@ define i32 @select_0_or_neg1_alt(i1 %cond) { define i32 @select_0_or_neg1_alt_zeroext(i1 zeroext %cond) { ; CHECK-LABEL: select_0_or_neg1_alt_zeroext: ; CHECK: @ BB#0: -; CHECK-NEXT: eor r0, r0, #1 -; CHECK-NEXT: rsb r0, r0, #0 +; CHECK-NEXT: sub r0, r0, #1 ; CHECK-NEXT: mov pc, lr %z = zext i1 %cond to i32 %add = add i32 %z, -1