diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -419,6 +419,7 @@ void clear(); MachineFunction &getMachineFunction() const { return *MF; } + MachineBasicBlock *getMachineBasicBlock() const { return FLI->MBB; } const Pass *getPass() const { return SDAGISelPass; } const DataLayout &getDataLayout() const { return MF->getDataLayout(); } diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -122,6 +122,28 @@ return ~Zero; } + /// Return the minimal signed value possible given these KnownBits. + APInt getSignedMinValue() const { + // Assume that all bits that aren't known-ones are zeros. + // If the sign bit is unknown, assume it is set + APInt Val = One; + if (!isNonNegative()) + Val.setSignBit(); + + return Val; + } + + /// Return the maximal signed value possible given these KnownBits. + APInt getSignedMaxValue() const { + // Assume that all bits that aren't known-zeros are ones. + // If the sign bit is unknown, assume it is cleared + APInt Val = ~Zero; + if (!isNegative()) + Val.clearSignBit(); + + return Val; + } + /// Return known bits for a truncation of the value we're tracking. KnownBits trunc(unsigned BitWidth) const { return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth)); 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 @@ -14051,6 +14051,25 @@ // Instcombine/SimplifyCFG should have handled the available opportunities. // If we did this folding here, it would be necessary to update the // MachineBasicBlock CFG, which is awkward. + if (auto *N1C = dyn_cast(N1.getNode())) { + auto *TgtMBB = cast(N2)->getBasicBlock(); + auto *CurMBB = DAG.getMachineBasicBlock(); + if (!N1C->isNullValue()) { + // unconditionally take the branch, remove all other successors of CurBB + auto SuccMBB = CurMBB->succ_begin(); + while (SuccMBB != CurMBB->succ_end()) { + if (*SuccMBB != TgtMBB) { + SuccMBB = CurMBB->removeSuccessor(SuccMBB); + } + } + return DAG.getNode(ISD::BR, SDLoc(N), MVT::Other, Chain, + N2.getOperand(0)); + } else { + // do not take the branch, remove it from the CFG + CurMBB->removeSuccessor(TgtMBB); + return Chain; + } + } // fold a brcond with a setcc condition into a BR_CC node if BR_CC is legal // on the target. diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3379,6 +3379,91 @@ isCondCodeLegal(SwappedCC, N0.getSimpleValueType()))) return DAG.getSetCC(dl, VT, N1, N0, SwappedCC); + // If we can guarantee that the known bits of the operands restricts the range + // of values that each can take such that the comparison is guaranteed to be + // true or false, replace the setcc with the respective constant + if (OpVT.isInteger()) { + KnownBits LHSKnown = DAG.computeKnownBits(N0); + KnownBits RHSKnown = DAG.computeKnownBits(N1); + + switch (Cond) { + default: + llvm_unreachable("Unknown integer setcc!"); + case ISD::SETEQ: + if (LHSKnown.Zero.intersects(RHSKnown.One) || + LHSKnown.One.intersects(RHSKnown.Zero)) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETNE: + if (LHSKnown.Zero.intersects(RHSKnown.One) || + LHSKnown.One.intersects(RHSKnown.Zero)) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } + break; + case ISD::SETGT: + if (LHSKnown.getSignedMinValue().sgt(RHSKnown.getSignedMaxValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getSignedMaxValue().sle( + RHSKnown.getSignedMinValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETGE: + if (LHSKnown.getSignedMinValue().sge(RHSKnown.getSignedMaxValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getSignedMaxValue().slt( + RHSKnown.getSignedMinValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETLT: + if (LHSKnown.getSignedMaxValue().slt(RHSKnown.getSignedMinValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getSignedMinValue().sge( + RHSKnown.getSignedMaxValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETLE: + if (LHSKnown.getSignedMaxValue().sle(RHSKnown.getSignedMinValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getSignedMinValue().sgt( + RHSKnown.getSignedMaxValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETUGT: + if (LHSKnown.getMinValue().ugt(RHSKnown.getMaxValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getMaxValue().ule(RHSKnown.getMinValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETUGE: + if (LHSKnown.getMinValue().uge(RHSKnown.getMaxValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getMaxValue().ult(RHSKnown.getMinValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETULT: + if (LHSKnown.getMaxValue().ult(RHSKnown.getMinValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getMinValue().uge(RHSKnown.getMaxValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + case ISD::SETULE: + if (LHSKnown.getMaxValue().ule(RHSKnown.getMinValue())) { + return DAG.getBoolConstant(true, dl, VT, OpVT); + } else if (LHSKnown.getMinValue().ugt(RHSKnown.getMaxValue())) { + return DAG.getBoolConstant(false, dl, VT, OpVT); + } + break; + } + } + // If we have a subtract with the same 2 non-constant operands as this setcc // -- but in reverse order -- then try to commute the operands of this setcc // to match. A matching pair of setcc (cmp) and sub may be combined into 1 @@ -3910,9 +3995,8 @@ // SETULT X, SINTMIN -> SETGT X, -1 if (Cond == ISD::SETULT && C1 == APInt::getSignedMinValue(OperandBitSize)) { - SDValue ConstMinusOne = - DAG.getConstant(APInt::getAllOnesValue(OperandBitSize), dl, - N1.getValueType()); + SDValue ConstMinusOne = DAG.getConstant( + APInt::getAllOnesValue(OperandBitSize), dl, N1.getValueType()); return DAG.getSetCC(dl, VT, N0, ConstMinusOne, ISD::SETGT); } } diff --git a/llvm/test/CodeGen/X86/combine-known-bits-vector.ll b/llvm/test/CodeGen/X86/combine-known-bits-vector.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/combine-known-bits-vector.ll @@ -0,0 +1,55 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s + +%vi32 = type <4 x i32> +%vi1 = type <4 x i1> + +; CHECK-LABEL: @test_eq +; CHECK: ## %bb.0 +; CHECK-NEXT: xorps %xmm0, %xmm0 +; CHECK-NEXT: retq +define %vi1 @test_eq(%vi32 %a0) { + %1 = and %vi32 %a0, + %2 = icmp eq %vi32 %1, + ret %vi1 %2 +} + +; CHECK-LABEL: @test_ne +; CHECK: ## %bb.0 +; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 +; CHECK-NEXT: retq +define %vi1 @test_ne(%vi32 %a0) { + %1 = and %vi32 %a0, + %2 = icmp ne %vi32 %1, + ret %vi1 %2 +} + +; CHECK-LABEL: @test_slt +; CHECK: ## %bb.0 +; CHECK-NEXT: por LCPI2_0(%rip), %xmm0 +;; first element can be combined, rest cannot +define %vi1 @test_slt(%vi32 %a0) { + %1 = or %vi32 %a0, + %2 = icmp slt %vi32 , %1 + ret %vi1 %2 +} + +; CHECK-LABEL: @test_sgt +; CHECK: ## %bb.0 +; CHECK-NEXT: por LCPI3_0(%rip), %xmm0 +;; first element can be combined, rest cannot +define %vi1 @test_sgt(%vi32 %a0) { + %1 = or %vi32 %a0, + %2 = icmp sgt %vi32 %1, + ret %vi1 %2 +} + + +; CHECK-LABEL: @test_sgt2 +; CHECK: ## %bb.0 +; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 +; CHECK-NEXT: retq +define %vi1 @test_sgt2(%vi32 %a0) { + %1 = or %vi32 %a0, + %2 = icmp sgt %vi32 %1, + ret %vi1 %2 +} \ No newline at end of file diff --git a/llvm/test/CodeGen/X86/combine-known-bits.ll b/llvm/test/CodeGen/X86/combine-known-bits.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/combine-known-bits.ll @@ -0,0 +1,267 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s + +;; EQ +; CHECK-LABEL: @test_eq +; CHECK: ## %bb.0: +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_eq(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp eq i32 %1, -2 + ret i1 %2 +} + +;; NE +; CHECK-LABEL: @test_ne +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_ne(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp ne i32 %1, -2 + ret i1 %2 +} + +;; UGE +; CHECK-LABEL: @test_uge1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_uge1(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp uge i32 %1, 242 + ret i1 %2 +} + +; CHECK-LABEL: @test_uge2 +; CHECK: ## %bb.0 +; CHECK-NEXT: andl $127, %edi +define i1 @test_uge2(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp uge i32 %1, 127 + ret i1 %2 +} + +; CHECK-LABEL: @test_uge3 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_uge3(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = icmp uge i32 %1, 127 + ret i1 %2 +} + +;; ULE +; CHECK-LABEL: @test_ule1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_ule1(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = icmp ule i32 %1, 17 + ret i1 %2 +} + +; CHECK-LABEL: @test_ule2 +; CHECK: ## %bb.0 +; CHECK-NEXT: andl $242, %edi +define i1 @test_ule2(i32 %a0) { + %1 = and i32 %a0, 242 + %2 = icmp ule i32 %1, 127 + ret i1 %2 +} + +; CHECK-LABEL: @test_ule3 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_ule3(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp ule i32 %1, 127 + ret i1 %2 +} + +;; SGE +; CHECK-LABEL: @test_sge1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_sge1(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp sge i32 %1, 128 + ret i1 %2 +} + +; CHECK-LABEL: @test_sge2 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_sge2(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = and i32 %1, 2147483647 ; i32_MAX + %3 = icmp sge i32 %2, 127 + ret i1 %3 +} + +; CHECK-LABEL: @test_sge3 +; CHECK: ## %bb.0 +; CHECK-NEXT: orl $127, %edi +define i1 @test_sge3(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = icmp sge i32 %1, 0 + ret i1 %2 +} + +;; SLE +; CHECK-LABEL: @test_sle1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_sle1(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp sle i32 128, %1 + ret i1 %2 +} + +; CHECK-LABEL: @test_sle2 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_sle2(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = and i32 %1, 2147483647 ; i32_MAX + %3 = icmp sle i32 126, %2 + ret i1 %3 +} + +; CHECK-LABEL: @test_sle3 +; CHECK: ## %bb.0 +; CHECK-NEXT: andl $242, %edi +define i1 @test_sle3(i32 %a0) { + %1 = and i32 %a0, 242 + %2 = icmp sle i32 %1, 127 + ret i1 %2 +} + +;; SLT +; CHECK-LABEL: @test_slt1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_slt1(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp slt i32 %1, -42 + ret i1 %2 +} + +; CHECK-LABEL: @test_slt2 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_slt2(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = and i32 %1, 2147483647 ; i32_MAX + %3 = icmp slt i32 126, %2 + ret i1 %3 +} + +; CHECK-LABEL: @test_slt3 +; CHECK: ## %bb.0 +; CHECK-NEXT: orl $242, %edi +define i1 @test_slt3(i32 %a0) { + %1 = or i32 %a0, 242 + %2 = icmp slt i32 127, %1 + ret i1 %2 +} + +;; ULT +; CHECK-LABEL: @test_ult1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_ult1(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = icmp ult i32 %1, 42 + ret i1 %2 +} + +; CHECK-LABEL: @test_ult2 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_ult2(i32 %a0) { + %1 = and i32 %a0, 17 + %2 = icmp ult i32 %1, 42 + ret i1 %2 +} + +; CHECK-LABEL: @test_ult3 +; CHECK: ## %bb.0 +; CHECK-NEXT: andl $242, %edi +define i1 @test_ult3(i32 %a0) { + %1 = and i32 %a0, 242 + %2 = icmp ult i32 %1, 127 + ret i1 %2 +} + + +;; UGT +; CHECK-LABEL: @test_ugt1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_ugt1(i32 %a0) { + %1 = or i32 %a0, 127 + %2 = icmp ugt i32 42, %1 + ret i1 %2 +} + +; CHECK-LABEL: @test_ugt2 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_ugt2(i32 %a0) { + %1 = and i32 %a0, 17 + %2 = icmp ugt i32 42, %1 + ret i1 %2 +} + +; CHECK-LABEL: @test_ugt3 +; CHECK: ## %bb.0 +; CHECK-NEXT: andl $242, %edi +define i1 @test_ugt3(i32 %a0) { + %1 = and i32 %a0, 242 + %2 = icmp ugt i32 %1, 127 + ret i1 %2 +} + +;; SGT +; CHECK-LABEL: @test_sgt1 +; CHECK: ## %bb.0 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +define i1 @test_sgt1(i32 %a0) { + %1 = and i32 %a0, 127 + %2 = icmp sgt i32 -17, %1 + ret i1 %2 +} + +; CHECK-LABEL: @test_sgt2 +; CHECK: ## %bb.0 +; CHECK-NEXT: movb $1, %al +; CHECK-NEXT: retq +define i1 @test_sgt2(i32 %a0) { + %1 = and i32 %a0, 17 + %2 = icmp sgt i32 42, %1 + ret i1 %2 +} + +; CHECK-LABEL: @test_sgt3 +; CHECK: ## %bb.0 +; CHECK-NEXT: orl $242, %edi +define i1 @test_sgt3(i32 %a0) { + %1 = or i32 %a0, 242 + %2 = icmp sgt i32 %1, 127 + ret i1 %2 +} diff --git a/llvm/test/CodeGen/X86/test-shrink.ll b/llvm/test/CodeGen/X86/test-shrink.ll --- a/llvm/test/CodeGen/X86/test-shrink.ll +++ b/llvm/test/CodeGen/X86/test-shrink.ll @@ -579,7 +579,7 @@ ; CHECK-LINUX64-LABEL: and16_trunc_8_sign: ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: testb $-128, %dil -; CHECK-LINUX64-NEXT: jg .LBB13_2 +; CHECK-LINUX64-NEXT: js .LBB13_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -591,7 +591,7 @@ ; CHECK-WIN32-64: # %bb.0: ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: testb $-128, %cl -; CHECK-WIN32-64-NEXT: jg .LBB13_2 +; CHECK-WIN32-64-NEXT: js .LBB13_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB13_2: # %no @@ -601,14 +601,14 @@ ; CHECK-X86-LABEL: and16_trunc_8_sign: ; CHECK-X86: # %bb.0: ; CHECK-X86-NEXT: testb $-128, {{[0-9]+}}(%esp) -; CHECK-X86-NEXT: jg .LBB13_2 +; CHECK-X86-NEXT: js .LBB13_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB13_2: # %no ; CHECK-X86-NEXT: retl %t = and i16 %x, 128 %r = trunc i16 %t to i8 - %s = icmp sle i8 %r, 0 + %s = icmp sge i8 %r, 0 br i1 %s, label %yes, label %no yes: @@ -622,7 +622,7 @@ ; CHECK-LINUX64-LABEL: and32_trunc_8_sign: ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: testb $-128, %dil -; CHECK-LINUX64-NEXT: jg .LBB14_2 +; CHECK-LINUX64-NEXT: js .LBB14_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -634,7 +634,7 @@ ; CHECK-WIN32-64: # %bb.0: ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: testb $-128, %cl -; CHECK-WIN32-64-NEXT: jg .LBB14_2 +; CHECK-WIN32-64-NEXT: js .LBB14_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB14_2: # %no @@ -644,14 +644,14 @@ ; CHECK-X86-LABEL: and32_trunc_8_sign: ; CHECK-X86: # %bb.0: ; CHECK-X86-NEXT: testb $-128, {{[0-9]+}}(%esp) -; CHECK-X86-NEXT: jg .LBB14_2 +; CHECK-X86-NEXT: js .LBB14_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB14_2: # %no ; CHECK-X86-NEXT: retl %t = and i32 %x, 128 %r = trunc i32 %t to i8 - %s = icmp sle i8 %r, 0 + %s = icmp sge i8 %r, 0 br i1 %s, label %yes, label %no yes: @@ -665,7 +665,7 @@ ; CHECK-LINUX64-LABEL: and64_trunc_8_sign: ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: testb $-128, %dil -; CHECK-LINUX64-NEXT: jg .LBB15_2 +; CHECK-LINUX64-NEXT: js .LBB15_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -677,7 +677,7 @@ ; CHECK-WIN32-64: # %bb.0: ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: testb $-128, %cl -; CHECK-WIN32-64-NEXT: jg .LBB15_2 +; CHECK-WIN32-64-NEXT: js .LBB15_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB15_2: # %no @@ -687,14 +687,14 @@ ; CHECK-X86-LABEL: and64_trunc_8_sign: ; CHECK-X86: # %bb.0: ; CHECK-X86-NEXT: testb $-128, {{[0-9]+}}(%esp) -; CHECK-X86-NEXT: jg .LBB15_2 +; CHECK-X86-NEXT: js .LBB15_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB15_2: # %no ; CHECK-X86-NEXT: retl %t = and i64 %x, 128 %r = trunc i64 %t to i8 - %s = icmp sle i8 %r, 0 + %s = icmp sge i8 %r, 0 br i1 %s, label %yes, label %no yes: @@ -709,7 +709,7 @@ ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: andl $32768, %edi # imm = 0x8000 ; CHECK-LINUX64-NEXT: testw %di, %di -; CHECK-LINUX64-NEXT: jg .LBB16_2 +; CHECK-LINUX64-NEXT: js .LBB16_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -722,7 +722,7 @@ ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: andl $32768, %ecx # imm = 0x8000 ; CHECK-WIN32-64-NEXT: testw %cx, %cx -; CHECK-WIN32-64-NEXT: jg .LBB16_2 +; CHECK-WIN32-64-NEXT: js .LBB16_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB16_2: # %no @@ -734,14 +734,14 @@ ; CHECK-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax ; CHECK-X86-NEXT: andl $32768, %eax # imm = 0x8000 ; CHECK-X86-NEXT: testw %ax, %ax -; CHECK-X86-NEXT: jg .LBB16_2 +; CHECK-X86-NEXT: js .LBB16_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB16_2: # %no ; CHECK-X86-NEXT: retl %t = and i32 %x, 32768 %r = trunc i32 %t to i16 - %s = icmp sle i16 %r, 0 + %s = icmp sge i16 %r, 0 br i1 %s, label %yes, label %no yes: @@ -755,7 +755,7 @@ ; CHECK-LINUX64-LABEL: and32_trunc_16_sign_minsize: ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: testw $-32768, %di # imm = 0x8000 -; CHECK-LINUX64-NEXT: jg .LBB17_2 +; CHECK-LINUX64-NEXT: js .LBB17_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -767,7 +767,7 @@ ; CHECK-WIN32-64: # %bb.0: ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: testw $-32768, %cx # imm = 0x8000 -; CHECK-WIN32-64-NEXT: jg .LBB17_2 +; CHECK-WIN32-64-NEXT: js .LBB17_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB17_2: # %no @@ -778,14 +778,14 @@ ; CHECK-X86: # %bb.0: ; CHECK-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax ; CHECK-X86-NEXT: testw $-32768, %ax # imm = 0x8000 -; CHECK-X86-NEXT: jg .LBB17_2 +; CHECK-X86-NEXT: js .LBB17_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB17_2: # %no ; CHECK-X86-NEXT: retl %t = and i32 %x, 32768 %r = trunc i32 %t to i16 - %s = icmp sle i16 %r, 0 + %s = icmp sge i16 %r, 0 br i1 %s, label %yes, label %no yes: @@ -800,7 +800,7 @@ ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: andl $32768, %edi # imm = 0x8000 ; CHECK-LINUX64-NEXT: testw %di, %di -; CHECK-LINUX64-NEXT: jg .LBB18_2 +; CHECK-LINUX64-NEXT: js .LBB18_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -813,7 +813,7 @@ ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: andl $32768, %ecx # imm = 0x8000 ; CHECK-WIN32-64-NEXT: testw %cx, %cx -; CHECK-WIN32-64-NEXT: jg .LBB18_2 +; CHECK-WIN32-64-NEXT: js .LBB18_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB18_2: # %no @@ -825,14 +825,14 @@ ; CHECK-X86-NEXT: movl $32768, %eax # imm = 0x8000 ; CHECK-X86-NEXT: andl {{[0-9]+}}(%esp), %eax ; CHECK-X86-NEXT: testw %ax, %ax -; CHECK-X86-NEXT: jg .LBB18_2 +; CHECK-X86-NEXT: js .LBB18_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB18_2: # %no ; CHECK-X86-NEXT: retl %t = and i64 %x, 32768 %r = trunc i64 %t to i16 - %s = icmp sle i16 %r, 0 + %s = icmp sge i16 %r, 0 br i1 %s, label %yes, label %no yes: @@ -846,7 +846,7 @@ ; CHECK-LINUX64-LABEL: and64_trunc_16_sign_minsize: ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: testw $-32768, %di # imm = 0x8000 -; CHECK-LINUX64-NEXT: jg .LBB19_2 +; CHECK-LINUX64-NEXT: js .LBB19_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -858,7 +858,7 @@ ; CHECK-WIN32-64: # %bb.0: ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: testw $-32768, %cx # imm = 0x8000 -; CHECK-WIN32-64-NEXT: jg .LBB19_2 +; CHECK-WIN32-64-NEXT: js .LBB19_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB19_2: # %no @@ -868,14 +868,14 @@ ; CHECK-X86-LABEL: and64_trunc_16_sign_minsize: ; CHECK-X86: # %bb.0: ; CHECK-X86-NEXT: testw $-32768, {{[0-9]+}}(%esp) # imm = 0x8000 -; CHECK-X86-NEXT: jg .LBB19_2 +; CHECK-X86-NEXT: js .LBB19_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB19_2: # %no ; CHECK-X86-NEXT: retl %t = and i64 %x, 32768 %r = trunc i64 %t to i16 - %s = icmp sle i16 %r, 0 + %s = icmp sge i16 %r, 0 br i1 %s, label %yes, label %no yes: @@ -889,7 +889,7 @@ ; CHECK-LINUX64-LABEL: and64_trunc_32_sign: ; CHECK-LINUX64: # %bb.0: ; CHECK-LINUX64-NEXT: testl $-2147483648, %edi # imm = 0x80000000 -; CHECK-LINUX64-NEXT: jg .LBB20_2 +; CHECK-LINUX64-NEXT: js .LBB20_2 ; CHECK-LINUX64-NEXT: # %bb.1: # %yes ; CHECK-LINUX64-NEXT: pushq %rax ; CHECK-LINUX64-NEXT: callq bar @@ -901,7 +901,7 @@ ; CHECK-WIN32-64: # %bb.0: ; CHECK-WIN32-64-NEXT: subq $40, %rsp ; CHECK-WIN32-64-NEXT: testl $-2147483648, %ecx # imm = 0x80000000 -; CHECK-WIN32-64-NEXT: jg .LBB20_2 +; CHECK-WIN32-64-NEXT: js .LBB20_2 ; CHECK-WIN32-64-NEXT: # %bb.1: # %yes ; CHECK-WIN32-64-NEXT: callq bar ; CHECK-WIN32-64-NEXT: .LBB20_2: # %no @@ -911,14 +911,14 @@ ; CHECK-X86-LABEL: and64_trunc_32_sign: ; CHECK-X86: # %bb.0: ; CHECK-X86-NEXT: testl $-2147483648, {{[0-9]+}}(%esp) # imm = 0x80000000 -; CHECK-X86-NEXT: jg .LBB20_2 +; CHECK-X86-NEXT: js .LBB20_2 ; CHECK-X86-NEXT: # %bb.1: # %yes ; CHECK-X86-NEXT: calll bar ; CHECK-X86-NEXT: .LBB20_2: # %no ; CHECK-X86-NEXT: retl %t = and i64 %x, 2147483648 %r = trunc i64 %t to i32 - %s = icmp sle i32 %r, 0 + %s = icmp sge i32 %r, 0 br i1 %s, label %yes, label %no yes: