diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 93248cb078cd6b..38fd9742d2d3ea 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -19911,8 +19911,13 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, // when the condition can be materialized as an all-ones register. Any // single bit-test can be materialized as an all-ones register with // shift-left and shift-right-arith. + // TODO: The operation legality checks could be loosened to include "custom", + // but that may cause regressions for targets that do not have shift + // instructions. if (CC == ISD::SETEQ && N0->getOpcode() == ISD::AND && - N0->getValueType(0) == VT && isNullConstant(N1) && isNullConstant(N2)) { + N0->getValueType(0) == VT && isNullConstant(N1) && isNullConstant(N2) && + TLI.isOperationLegal(ISD::SHL, VT) && + TLI.isOperationLegal(ISD::SRA, VT)) { SDValue AndLHS = N0->getOperand(0); auto *ConstAndRHS = dyn_cast(N0->getOperand(1)); if (ConstAndRHS && ConstAndRHS->getAPIntValue().countPopulation() == 1) { diff --git a/llvm/test/CodeGen/MSP430/selectcc.ll b/llvm/test/CodeGen/MSP430/selectcc.ll index c72079eac27695..28b90f0131703e 100644 --- a/llvm/test/CodeGen/MSP430/selectcc.ll +++ b/llvm/test/CodeGen/MSP430/selectcc.ll @@ -4,24 +4,13 @@ define i16 @select_to_shifts_i16(i16 %a, i16 %b) { ; CHECK-LABEL: select_to_shifts_i16: ; CHECK: ; %bb.0: -; CHECK-NEXT: mov.b r12, r12 -; CHECK-NEXT: swpb r12 -; CHECK-NEXT: add r12, r12 -; CHECK-NEXT: add r12, r12 -; CHECK-NEXT: add r12, r12 -; CHECK-NEXT: add r12, r12 -; CHECK-NEXT: add r12, r12 -; CHECK-NEXT: add r12, r12 -; CHECK-NEXT: swpb r12 -; CHECK-NEXT: sxt r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: rra r12 -; CHECK-NEXT: and r13, r12 +; CHECK-NEXT: mov r12, r14 +; CHECK-NEXT: clr r12 +; CHECK-NEXT: bit #2, r14 +; CHECK-NEXT: jeq .LBB0_2 +; CHECK-NEXT: ; %bb.1: +; CHECK-NEXT: mov r13, r12 +; CHECK-NEXT: .LBB0_2: ; CHECK-NEXT: ret %and = and i16 %a, 2 %tobool = icmp eq i16 %and, 0 @@ -32,27 +21,23 @@ define i16 @select_to_shifts_i16(i16 %a, i16 %b) { define i32 @select_to_shifts_i32(i32 %a, i32 %b) { ; CHECK-LABEL: select_to_shifts_i32: ; CHECK: ; %bb.0: -; CHECK-NEXT: mov r12, r13 -; CHECK-NEXT: mov.b r13, r13 -; CHECK-NEXT: swpb r13 -; CHECK-NEXT: add r13, r13 -; CHECK-NEXT: add r13, r13 -; CHECK-NEXT: add r13, r13 -; CHECK-NEXT: add r13, r13 -; CHECK-NEXT: add r13, r13 -; CHECK-NEXT: add r13, r13 -; CHECK-NEXT: swpb r13 -; CHECK-NEXT: sxt r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: rra r13 -; CHECK-NEXT: and r13, r14 -; CHECK-NEXT: and r15, r13 +; CHECK-NEXT: mov r12, r11 +; CHECK-NEXT: and #2, r11 +; CHECK-NEXT: clr r13 +; CHECK-NEXT: tst r11 +; CHECK-NEXT: clr r12 +; CHECK-NEXT: jne .LBB1_3 +; CHECK-NEXT: ; %bb.1: +; CHECK-NEXT: tst r11 +; CHECK-NEXT: jne .LBB1_4 +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB1_3: ; CHECK-NEXT: mov r14, r12 +; CHECK-NEXT: tst r11 +; CHECK-NEXT: jeq .LBB1_2 +; CHECK-NEXT: .LBB1_4: +; CHECK-NEXT: mov r15, r13 ; CHECK-NEXT: ret %and = and i32 %a, 2 %tobool = icmp eq i32 %and, 0