diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10130,7 +10130,7 @@ // transforms in the other direction (create a select from a zext/sext). There // is also a target-independent combine here in DAGCombiner in the other // direction for (select Cond, -1, 0) when the condition is not i1. - if (CondVT == MVT::i1 && !LegalOperations) { + if (!LegalOperations && CondVT == MVT::i1) { if (C1->isZero() && C2->isOne()) { // select Cond, 0, 1 --> zext (!Cond) SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1); @@ -10178,13 +10178,40 @@ return DAG.getNode(ISD::ADD, DL, VT, Cond, N2); } - // select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2) - if (C1Val.isPowerOf2() && C2Val.isZero()) { - if (VT != MVT::i1) - Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Cond); - SDValue ShAmtC = - DAG.getShiftAmountConstant(C1Val.exactLogBase2(), VT, DL); - return DAG.getNode(ISD::SHL, DL, VT, Cond, ShAmtC); + // Avoid more complex combination if we expect to fold into a select_cc. + if (Cond.getOpcode() != ISD::SETCC || + !TLI.isOperationLegal(ISD::SELECT_CC, VT)) { + // select Cond, 0, C2 --> (zext(not Cond) << log2(C2)) + if (C1Val.isZero() && C2Val.isPowerOf2()) { + SDValue R = DAG.getNOT(DL, Cond, MVT::i1); + R = DAG.getZExtOrTrunc(R, DL, VT); + if (!C2Val.isOne()) { + SDValue ShAmtC = + DAG.getShiftAmountConstant(C2Val.exactLogBase2(), VT, DL); + R = DAG.getNode(ISD::SHL, DL, VT, R, ShAmtC); + } + + return R; + } + + // select Cond, C1, C2 --> (zext(Cond) << log2(C1 - C2)) + C2 + bool OV; + APInt Diff = C1Val.ssub_ov(C2Val, OV); + if (!OV && Diff.isPowerOf2()) { + SDValue R = DAG.getZExtOrTrunc(Cond, DL, VT); + + if (!Diff.isOne()) { + SDValue ShAmtC = + DAG.getShiftAmountConstant(Diff.exactLogBase2(), VT, DL); + R = DAG.getNode(ISD::SHL, DL, VT, R, ShAmtC); + } + + // Add the base if non-zero. + if (!C2Val.isZero()) + R = DAG.getNode(ISD::ADD, DL, VT, R, N2); + + return R; + } } if (SDValue V = foldSelectOfConstantsUsingSra(N, DAG)) diff --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll --- a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll +++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll @@ -617,14 +617,15 @@ ; P8-NEXT: xxlxor f3, f3, f3 ; P8-NEXT: std r30, 112(r1) # 8-byte Folded Spill ; P8-NEXT: lfs f0, .LCPI13_0@toc@l(r3) -; P8-NEXT: lis r3, -32768 +; P8-NEXT: li r3, 1 ; P8-NEXT: fcmpo cr0, f2, f3 ; P8-NEXT: xxlxor f3, f3, f3 ; P8-NEXT: fcmpo cr1, f1, f0 ; P8-NEXT: crand 4*cr5+lt, 4*cr1+eq, lt ; P8-NEXT: crandc 4*cr5+gt, 4*cr1+lt, 4*cr1+eq ; P8-NEXT: cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt -; P8-NEXT: isel r30, 0, r3, 4*cr5+lt +; P8-NEXT: isel r3, 0, r3, 4*cr5+lt +; P8-NEXT: slwi r30, r3, 31 ; P8-NEXT: bc 12, 4*cr5+lt, .LBB13_2 ; P8-NEXT: # %bb.1: # %entry ; P8-NEXT: fmr f3, f0 @@ -660,13 +661,14 @@ ; P9-NEXT: xxlxor f3, f3, f3 ; P9-NEXT: lfs f0, .LCPI13_0@toc@l(r3) ; P9-NEXT: fcmpo cr1, f2, f3 -; P9-NEXT: lis r3, -32768 +; P9-NEXT: li r3, 1 ; P9-NEXT: fcmpo cr0, f1, f0 ; P9-NEXT: xxlxor f3, f3, f3 ; P9-NEXT: crand 4*cr5+lt, eq, 4*cr1+lt ; P9-NEXT: crandc 4*cr5+gt, lt, eq ; P9-NEXT: cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt -; P9-NEXT: isel r30, 0, r3, 4*cr5+lt +; P9-NEXT: isel r3, 0, r3, 4*cr5+lt +; P9-NEXT: slwi r30, r3, 31 ; P9-NEXT: bc 12, 4*cr5+lt, .LBB13_2 ; P9-NEXT: # %bb.1: # %entry ; P9-NEXT: fmr f3, f0 @@ -723,9 +725,10 @@ ; NOVSX-NEXT: mtfsf 1, f0 ; NOVSX-NEXT: fctiwz f0, f1 ; NOVSX-NEXT: stfiwx f0, 0, r3 -; NOVSX-NEXT: lis r3, -32768 -; NOVSX-NEXT: lwz r4, 44(r1) +; NOVSX-NEXT: li r3, 1 ; NOVSX-NEXT: isel r3, 0, r3, 4*cr2+lt +; NOVSX-NEXT: lwz r4, 44(r1) +; NOVSX-NEXT: slwi r3, r3, 31 ; NOVSX-NEXT: xor r3, r4, r3 ; NOVSX-NEXT: clrldi r3, r3, 32 ; NOVSX-NEXT: addi r1, r1, 48 diff --git a/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll b/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll --- a/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll +++ b/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll @@ -1293,14 +1293,15 @@ ; PC64LE-NEXT: addis 3, 2, .LCPI31_0@toc@ha ; PC64LE-NEXT: xxlxor 3, 3, 3 ; PC64LE-NEXT: lfs 0, .LCPI31_0@toc@l(3) -; PC64LE-NEXT: lis 3, -32768 +; PC64LE-NEXT: li 3, 1 ; PC64LE-NEXT: fcmpo 0, 2, 3 ; PC64LE-NEXT: xxlxor 3, 3, 3 ; PC64LE-NEXT: fcmpo 1, 1, 0 ; PC64LE-NEXT: crand 20, 6, 0 ; PC64LE-NEXT: crandc 21, 4, 6 ; PC64LE-NEXT: cror 20, 21, 20 -; PC64LE-NEXT: isel 30, 0, 3, 20 +; PC64LE-NEXT: isel 3, 0, 3, 20 +; PC64LE-NEXT: slwi 30, 3, 31 ; PC64LE-NEXT: bc 12, 20, .LBB31_2 ; PC64LE-NEXT: # %bb.1: # %entry ; PC64LE-NEXT: fmr 3, 0 @@ -1332,13 +1333,14 @@ ; PC64LE9-NEXT: xxlxor 3, 3, 3 ; PC64LE9-NEXT: lfs 0, .LCPI31_0@toc@l(3) ; PC64LE9-NEXT: fcmpo 1, 2, 3 -; PC64LE9-NEXT: lis 3, -32768 +; PC64LE9-NEXT: li 3, 1 ; PC64LE9-NEXT: fcmpo 0, 1, 0 ; PC64LE9-NEXT: xxlxor 3, 3, 3 ; PC64LE9-NEXT: crand 20, 2, 4 ; PC64LE9-NEXT: crandc 21, 0, 2 ; PC64LE9-NEXT: cror 20, 21, 20 -; PC64LE9-NEXT: isel 30, 0, 3, 20 +; PC64LE9-NEXT: isel 3, 0, 3, 20 +; PC64LE9-NEXT: slwi 30, 3, 31 ; PC64LE9-NEXT: bc 12, 20, .LBB31_2 ; PC64LE9-NEXT: # %bb.1: # %entry ; PC64LE9-NEXT: fmr 3, 0 @@ -1385,13 +1387,14 @@ ; PC64-NEXT: nop ; PC64-NEXT: mffs 0 ; PC64-NEXT: mtfsb1 31 -; PC64-NEXT: lis 4, -32768 +; PC64-NEXT: li 4, 1 ; PC64-NEXT: bc 12, 8, .LBB31_3 ; PC64-NEXT: b .LBB31_4 ; PC64-NEXT: .LBB31_3: # %entry ; PC64-NEXT: li 4, 0 ; PC64-NEXT: .LBB31_4: # %entry ; PC64-NEXT: mtfsb0 30 +; PC64-NEXT: slwi 4, 4, 31 ; PC64-NEXT: fadd 1, 2, 1 ; PC64-NEXT: mtfsf 1, 0 ; PC64-NEXT: fctiwz 0, 1 diff --git a/llvm/test/CodeGen/PowerPC/pr49509.ll b/llvm/test/CodeGen/PowerPC/pr49509.ll --- a/llvm/test/CodeGen/PowerPC/pr49509.ll +++ b/llvm/test/CodeGen/PowerPC/pr49509.ll @@ -16,39 +16,31 @@ ; CHECK-NEXT: .LBB0_2: # %bb1 ; CHECK-NEXT: bclr 4, 20, 0 ; CHECK-NEXT: # %bb.3: # %bb66 +; CHECK-NEXT: lbz 3, 0(3) ; CHECK-NEXT: lwz 4, 12(0) ; CHECK-NEXT: lwz 5, 8(0) +; CHECK-NEXT: cmpwi 3, 0 ; CHECK-NEXT: lwz 6, 0(0) +; CHECK-NEXT: li 3, 1 ; CHECK-NEXT: lwz 7, 4(0) -; CHECK-NEXT: lbz 3, 0(3) -; CHECK-NEXT: and 5, 5, 6 -; CHECK-NEXT: and 4, 4, 7 -; CHECK-NEXT: and 4, 4, 5 -; CHECK-NEXT: cmpwi 3, 0 -; CHECK-NEXT: lis 3, 256 -; CHECK-NEXT: lis 7, 512 ; CHECK-NEXT: bc 12, 2, .LBB0_4 ; CHECK-NEXT: b .LBB0_5 ; CHECK-NEXT: .LBB0_4: # %bb66 ; CHECK-NEXT: li 3, 0 ; CHECK-NEXT: .LBB0_5: # %bb66 -; CHECK-NEXT: cmpwi 1, 4, -1 -; CHECK-NEXT: cmpwi 5, 4, -1 +; CHECK-NEXT: and 5, 5, 6 ; CHECK-NEXT: li 6, 0 -; CHECK-NEXT: bc 12, 6, .LBB0_6 +; CHECK-NEXT: and 4, 4, 7 +; CHECK-NEXT: and 4, 4, 5 +; CHECK-NEXT: lis 7, 512 +; CHECK-NEXT: slwi 3, 3, 24 +; CHECK-NEXT: cmpwi 4, -1 +; CHECK-NEXT: stw 6, 0(3) +; CHECK-NEXT: bc 12, 2, .LBB0_6 ; CHECK-NEXT: b .LBB0_7 ; CHECK-NEXT: .LBB0_6: # %bb66 ; CHECK-NEXT: addi 3, 7, 0 ; CHECK-NEXT: .LBB0_7: # %bb66 -; CHECK-NEXT: cror 20, 22, 2 -; CHECK-NEXT: stw 3, 0(3) -; CHECK-NEXT: bc 12, 20, .LBB0_9 -; CHECK-NEXT: # %bb.8: # %bb66 -; CHECK-NEXT: ori 3, 6, 0 -; CHECK-NEXT: b .LBB0_10 -; CHECK-NEXT: .LBB0_9: # %bb66 -; CHECK-NEXT: li 3, 0 -; CHECK-NEXT: .LBB0_10: # %bb66 ; CHECK-NEXT: stw 3, 0(3) ; CHECK-NEXT: blr bb: diff --git a/llvm/test/CodeGen/PowerPC/pzero-fp-xored.ll b/llvm/test/CodeGen/PowerPC/pzero-fp-xored.ll --- a/llvm/test/CodeGen/PowerPC/pzero-fp-xored.ll +++ b/llvm/test/CodeGen/PowerPC/pzero-fp-xored.ll @@ -37,7 +37,7 @@ ; CHECK-NEXT: xxlxor 0, 0, 0 ; CHECK-NEXT: li 3, 11 ; CHECK-NEXT: li 4, 43 -; CHECK-NEXT: xscmpudp 0, 1, 0 +; CHECK-NEXT: fcmpu 0, 1, 0 ; CHECK-NEXT: iselgt 3, 4, 3 ; CHECK-NEXT: blr ; diff --git a/llvm/test/CodeGen/PowerPC/select_const.ll b/llvm/test/CodeGen/PowerPC/select_const.ll --- a/llvm/test/CodeGen/PowerPC/select_const.ll +++ b/llvm/test/CodeGen/PowerPC/select_const.ll @@ -354,22 +354,11 @@ } define i8 @sel_constants_sdiv_constant(i1 %cond) { -; ISEL-LABEL: sel_constants_sdiv_constant: -; ISEL: # %bb.0: -; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 3, 4 -; ISEL-NEXT: iselgt 3, 0, 3 -; ISEL-NEXT: blr -; -; NO_ISEL-LABEL: sel_constants_sdiv_constant: -; NO_ISEL: # %bb.0: -; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 3, 4 -; NO_ISEL-NEXT: bc 12, 1, .LBB25_1 -; NO_ISEL-NEXT: blr -; NO_ISEL-NEXT: .LBB25_1: -; NO_ISEL-NEXT: li 3, 0 -; NO_ISEL-NEXT: blr +; ALL-LABEL: sel_constants_sdiv_constant: +; ALL: # %bb.0: +; ALL-NEXT: not 3, 3 +; ALL-NEXT: rlwinm 3, 3, 2, 29, 29 +; ALL-NEXT: blr %sel = select i1 %cond, i8 -4, i8 23 %bo = sdiv i8 %sel, 5 ret i8 %bo @@ -658,24 +647,11 @@ } define i8 @lshr_constant_sel_constants(i1 %cond) { -; ISEL-LABEL: lshr_constant_sel_constants: -; ISEL: # %bb.0: -; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 4, 16 -; ISEL-NEXT: li 3, 8 -; ISEL-NEXT: iselgt 3, 4, 3 -; ISEL-NEXT: blr -; -; NO_ISEL-LABEL: lshr_constant_sel_constants: -; NO_ISEL: # %bb.0: -; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 4, 16 -; NO_ISEL-NEXT: li 3, 8 -; NO_ISEL-NEXT: bc 12, 1, .LBB39_1 -; NO_ISEL-NEXT: blr -; NO_ISEL-NEXT: .LBB39_1: -; NO_ISEL-NEXT: addi 3, 4, 0 -; NO_ISEL-NEXT: blr +; ALL-LABEL: lshr_constant_sel_constants: +; ALL: # %bb.0: +; ALL-NEXT: rlwinm 3, 3, 3, 28, 28 +; ALL-NEXT: addi 3, 3, 8 +; ALL-NEXT: blr %sel = select i1 %cond, i8 2, i8 3 %bo = lshr i8 64, %sel ret i8 %bo diff --git a/llvm/test/CodeGen/X86/select.ll b/llvm/test/CodeGen/X86/select.ll --- a/llvm/test/CodeGen/X86/select.ll +++ b/llvm/test/CodeGen/X86/select.ll @@ -990,26 +990,25 @@ ; CHECK-LABEL: PR53006: ; CHECK: ## %bb.0: ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: negl %edi -; CHECK-NEXT: sbbl %eax, %eax -; CHECK-NEXT: orl $1, %eax +; CHECK-NEXT: testl %edi, %edi +; CHECK-NEXT: sete %al +; CHECK-NEXT: leal -1(%rax,%rax), %eax ; CHECK-NEXT: retq ; ; ATHLON-LABEL: PR53006: ; ATHLON: ## %bb.0: ; ATHLON-NEXT: xorl %eax, %eax -; ATHLON-NEXT: cmpl {{[0-9]+}}(%esp), %eax -; ATHLON-NEXT: sbbl %eax, %eax -; ATHLON-NEXT: orl $1, %eax +; ATHLON-NEXT: cmpl $0, {{[0-9]+}}(%esp) +; ATHLON-NEXT: sete %al +; ATHLON-NEXT: leal -1(%eax,%eax), %eax ; ATHLON-NEXT: retl ; ; MCU-LABEL: PR53006: ; MCU: # %bb.0: ; MCU-NEXT: xorl %ecx, %ecx -; MCU-NEXT: negl %eax -; MCU-NEXT: sbbl %ecx, %ecx -; MCU-NEXT: orl $1, %ecx -; MCU-NEXT: movl %ecx, %eax +; MCU-NEXT: testl %eax, %eax +; MCU-NEXT: sete %cl +; MCU-NEXT: leal -1(%ecx,%ecx), %eax ; MCU-NEXT: retl %z = icmp eq i32 %x, 0 %r = select i1 %z, i32 1, i32 -1 diff --git a/llvm/test/CodeGen/X86/zext-sext.ll b/llvm/test/CodeGen/X86/zext-sext.ll --- a/llvm/test/CodeGen/X86/zext-sext.ll +++ b/llvm/test/CodeGen/X86/zext-sext.ll @@ -16,26 +16,26 @@ ; CHECK-NEXT: movq (%rdx), %rax ; CHECK-NEXT: movswl 8(%rdi), %edx ; CHECK-NEXT: movswl (%rax,%rsi,2), %eax -; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: imull %edx, %eax -; CHECK-NEXT: xorl %edx, %edx ; CHECK-NEXT: addl $2138875574, %eax # imm = 0x7F7CA6B6 +; CHECK-NEXT: cmpl $2138875574, %eax # imm = 0x7F7CA6B6 +; CHECK-NEXT: setge %sil ; CHECK-NEXT: cmpl $-8608074, %eax # imm = 0xFF7CA6B6 -; CHECK-NEXT: movslq %eax, %rdi ; CHECK-NEXT: setl %dl -; CHECK-NEXT: cmpl $2138875574, %eax # imm = 0x7F7CA6B6 -; CHECK-NEXT: movq %rdi, %r8 -; CHECK-NEXT: leal -1(%rdx,%rdx), %edx -; CHECK-NEXT: cmovll %edx, %esi -; CHECK-NEXT: subq %rax, %r8 +; CHECK-NEXT: orb %sil, %dl +; CHECK-NEXT: movslq %eax, %rsi +; CHECK-NEXT: movzbl %dl, %edx +; CHECK-NEXT: movq %rsi, %rdi +; CHECK-NEXT: subq %rax, %rdi +; CHECK-NEXT: addl %edx, %edx ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpl $1, %esi -; CHECK-NEXT: cmovneq %rax, %r8 -; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: cmovnsq %rax, %r8 +; CHECK-NEXT: cmpl $2, %edx +; CHECK-NEXT: cmovneq %rax, %rdi +; CHECK-NEXT: testl %esi, %esi +; CHECK-NEXT: cmovnsq %rax, %rdi ; CHECK-NEXT: movq (%rcx), %rax -; CHECK-NEXT: subq %r8, %rdi -; CHECK-NEXT: leaq -2138875574(%rax,%rdi), %rax +; CHECK-NEXT: subq %rdi, %rsi +; CHECK-NEXT: leaq -2138875574(%rax,%rsi), %rax ; CHECK-NEXT: movq %rax, (%rcx) ; CHECK-NEXT: retq entry: