diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index f06f9f1b99b57d..d8721cbebd2dc2 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -5621,6 +5621,10 @@ def t2CSINC : CS<"csinc", 0b1001>; def t2CSINV : CS<"csinv", 0b1010>; def t2CSNEG : CS<"csneg", 0b1011>; +def ARMcsinc_su : PatFrag<(ops node:$lhs, node:$rhs, node:$cond), + (ARMcsinc node:$lhs, node:$rhs, node:$cond), [{ + return N->hasOneUse(); +}]>; let Predicates = [HasV8_1MMainline] in { multiclass CSPats { @@ -5660,7 +5664,7 @@ let Predicates = [HasV8_1MMainline] in { def : T2Pat<(ARMcmov (topbitsallzero32:$Rn), (i32 1), cmovpred:$imm), (t2CSINC $Rn, ZR, $imm)>; - def : T2Pat<(and (topbitsallzero32:$Rn), (ARMcsinc (i32 0), (i32 0), cmovpred:$imm)), + def : T2Pat<(and (topbitsallzero32:$Rn), (ARMcsinc_su (i32 0), (i32 0), cmovpred:$imm)), (t2CSEL ZR, $Rn, $imm)>; } diff --git a/llvm/test/CodeGen/Thumb2/csel-andor-onebit.ll b/llvm/test/CodeGen/Thumb2/csel-andor-onebit.ll index d9e18b5c0942e8..759a8169389cca 100644 --- a/llvm/test/CodeGen/Thumb2/csel-andor-onebit.ll +++ b/llvm/test/CodeGen/Thumb2/csel-andor-onebit.ll @@ -170,3 +170,28 @@ define i64 @andi64_ne(i8 %x, i8 %y) { %a = and i64 %xa, %cz ret i64 %a } + +; Check for multiple uses on the csinc +define i32 @t5(i32 %f.0, i32 %call) { +; CHECK-LABEL: t5: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: cmp r1, #0 +; CHECK-NEXT: cset r1, ne +; CHECK-NEXT: cmp r0, #13 +; CHECK-NEXT: cset r0, eq +; CHECK-NEXT: and.w r2, r0, r1 +; CHECK-NEXT: orrs r0, r1 +; CHECK-NEXT: eor r0, r0, #1 +; CHECK-NEXT: orrs r0, r2 +; CHECK-NEXT: bx lr +entry: + %tobool1.i = icmp ne i32 %call, 0 + %cmp = icmp eq i32 %f.0, 13 + %or.cond = select i1 %cmp, i1 %tobool1.i, i1 false + %or.cond7.not = select i1 %cmp, i1 true, i1 %tobool1.i + %or.cond7.not.not = xor i1 %or.cond7.not, true + %not.or.cond12 = select i1 %or.cond, i1 true, i1 %or.cond7.not.not + %g.0 = zext i1 %not.or.cond12 to i32 + ret i32 %g.0 +} +