diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -42,9 +42,41 @@ "Controls which conditions are eliminated"); static int64_t MaxConstraintValue = std::numeric_limits::max(); +static int64_t MinSignedConstraintValue = std::numeric_limits::min(); namespace { +/// Wrapper encapsulating separate constraint systems and corresponding value +/// mappings for both unsigned and signed information. Facts are added to and +/// conditions are checked against the corresponding system depending on the +/// signed-ness of their predicates. While the information is kept separate +/// based on signed-ness, certain conditions can be transferred between the two +/// systems. +class ConstraintInfo { + DenseMap UnsignedValue2Index; + DenseMap SignedValue2Index; + + ConstraintSystem UnsignedCS; + ConstraintSystem SignedCS; + +public: + DenseMap &getValue2Index(bool Signed) { + return Signed ? SignedValue2Index : UnsignedValue2Index; + } + const DenseMap &getValue2Index(bool Signed) const { + return Signed ? SignedValue2Index : UnsignedValue2Index; + } + + ConstraintSystem &getCS(bool Signed) { + return Signed ? SignedCS : UnsignedCS; + } + const ConstraintSystem &getCS(bool Signed) const { + return Signed ? SignedCS : UnsignedCS; + } + + void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); } +}; + /// Struct to express a pre-condition of the form %Op0 Pred %Op1. struct PreconditionTy { CmpInst::Predicate Pred; @@ -58,8 +90,10 @@ struct ConstraintTy { SmallVector Coefficients; - ConstraintTy(SmallVector Coefficients) - : Coefficients(Coefficients) {} + bool IsSigned; + + ConstraintTy(SmallVector Coefficients, bool IsSigned) + : Coefficients(Coefficients), IsSigned(IsSigned) {} unsigned size() const { return Coefficients.size(); } }; @@ -104,13 +138,14 @@ /// Returns true if all preconditions for this list of constraints are /// satisfied given \p CS and the corresponding \p Value2Index mapping. - bool isValid(const ConstraintSystem &CS, - DenseMap &Value2Index) const; + bool isValid(const ConstraintInfo &Info) const; + /// Returns true if there is exactly one constraint in the list and isValid is /// also true. - bool isValidSingle(const ConstraintSystem &CS, - DenseMap &Value2Index) const { - return size() == 1 && isValid(CS, Value2Index); + bool isValidSingle(const ConstraintInfo &Info) const { + if (size() != 1) + return false; + return isValid(Info); } }; @@ -121,7 +156,21 @@ // must be nullptr. If the expression cannot be decomposed, returns an empty // vector. static SmallVector, 4> -decompose(Value *V, SmallVector &Preconditions) { +decompose(Value *V, SmallVector &Preconditions, + bool IsSigned) { + + // Decompose \p V used with a signed predicate. + if (IsSigned) { + if (auto *CI = dyn_cast(V)) { + const APInt &Val = CI->getValue(); + if (Val.sle(MinSignedConstraintValue) || Val.sge(MaxConstraintValue)) + return {}; + return {{CI->getSExtValue(), nullptr}}; + } + + return {{0, nullptr}, {1, V}}; + } + if (auto *CI = dyn_cast(V)) { if (CI->isNegative() || CI->uge(MaxConstraintValue)) return {}; @@ -216,7 +265,8 @@ return Insert.first->second; }; - if (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE) + if (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE || + Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE) return getConstraint(CmpInst::getSwappedPredicate(Pred), Op1, Op0, Value2Index, NewIndices); @@ -238,13 +288,15 @@ } // Only ULE and ULT predicates are supported at the moment. - if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT) + if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT && + Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT) return {}; - auto ADec = - decompose(Op0->stripPointerCastsSameRepresentation(), Preconditions); - auto BDec = - decompose(Op1->stripPointerCastsSameRepresentation(), Preconditions); + bool IsSigned = CmpInst::isSigned(Pred); + auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), + Preconditions, IsSigned); + auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), + Preconditions, IsSigned); // Skip if decomposing either of the values failed. if (ADec.empty() || BDec.empty()) return {}; @@ -275,25 +327,28 @@ for (const auto &KV : VariablesB) R[GetOrAddIndex(KV.second)] -= KV.first; - R[0] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0); - return {{R}, Preconditions}; + R[0] = Offset1 + Offset2 + + (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT) ? -1 : 0); + return {{{R, IsSigned}}, Preconditions}; } -static ConstraintListTy getConstraint(CmpInst *Cmp, - DenseMap &Value2Index, +static ConstraintListTy getConstraint(CmpInst *Cmp, ConstraintInfo &Info, DenseMap &NewIndices) { - return getConstraint(Cmp->getPredicate(), Cmp->getOperand(0), - Cmp->getOperand(1), Value2Index, NewIndices); + return getConstraint( + Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1), + Info.getValue2Index(CmpInst::isSigned(Cmp->getPredicate())), NewIndices); } -bool ConstraintListTy::isValid(const ConstraintSystem &CS, - DenseMap &Value2Index) const { - return all_of(Preconditions, [&CS, &Value2Index](const PreconditionTy &C) { +bool ConstraintListTy::isValid(const ConstraintInfo &Info) const { + return all_of(Preconditions, [&Info](const PreconditionTy &C) { DenseMap NewIndices; - auto R = getConstraint(C.Pred, C.Op0, C.Op1, Value2Index, NewIndices); + auto R = getConstraint(C.Pred, C.Op0, C.Op1, + Info.getValue2Index(CmpInst::isSigned(C.Pred)), + NewIndices); // TODO: properly check NewIndices. return NewIndices.empty() && R.Preconditions.empty() && R.size() == 1 && - CS.isConditionImplied(R.get(0).Coefficients); + Info.getCS(CmpInst::isSigned(C.Pred)) + .isConditionImplied(R.get(0).Coefficients); }); } @@ -321,11 +376,14 @@ struct StackEntry { unsigned NumIn; unsigned NumOut; - CmpInst *Condition; + Instruction *Condition; bool IsNot; + bool IsSigned = false; - StackEntry(unsigned NumIn, unsigned NumOut, CmpInst *Condition, bool IsNot) - : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot) {} + StackEntry(unsigned NumIn, unsigned NumOut, Instruction *Condition, + bool IsNot, bool IsSigned) + : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot), + IsSigned(IsSigned) {} }; } // namespace @@ -345,7 +403,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) { bool Changed = false; DT.updateDFSNumbers(); - ConstraintSystem CS; + + ConstraintInfo Info; SmallVector WorkList; @@ -447,7 +506,6 @@ // Finally, process ordered worklist and eliminate implied conditions. SmallVector DFSInStack; - DenseMap Value2Index; for (ConstraintOrBlock &CB : WorkList) { // First, pop entries from the stack that are out-of-scope for CB. Remove // the corresponding entry from the constraint system. @@ -462,7 +520,7 @@ LLVM_DEBUG(dbgs() << "Removing " << *E.Condition << " " << E.IsNot << "\n"); DFSInStack.pop_back(); - CS.popLastConstraint(); + Info.popLastConstraint(E.IsSigned); } LLVM_DEBUG({ @@ -483,12 +541,12 @@ continue; DenseMap NewIndices; - auto R = getConstraint(Cmp, Value2Index, NewIndices); - - if (!R.isValidSingle(CS, Value2Index) || R.needsNewIndices(NewIndices)) + auto R = getConstraint(Cmp, Info, NewIndices); + if (!R.isValidSingle(Info) || R.needsNewIndices(NewIndices)) continue; - if (CS.isConditionImplied(R.get(0).Coefficients)) { + auto &CSToUse = Info.getCS(R.get(0).IsSigned); + if (CSToUse.isConditionImplied(R.get(0).Coefficients)) { if (!DebugCounter::shouldExecute(EliminatedCounter)) continue; @@ -508,7 +566,7 @@ NumCondsRemoved++; Changed = true; } - if (CS.isConditionImplied( + if (CSToUse.isConditionImplied( ConstraintSystem::negate(R.get(0).Coefficients))) { if (!DebugCounter::shouldExecute(EliminatedCounter)) continue; @@ -547,31 +605,45 @@ // Otherwise, add the condition to the system and stack, if we can transform // it into a constraint. DenseMap NewIndices; - auto R = getConstraint(CB.Condition, Value2Index, NewIndices); - if (!R.isValid(CS, Value2Index)) + auto R = getConstraint(CB.Condition, Info, NewIndices); + if (!R.isValid(Info)) continue; for (auto &KV : NewIndices) - Value2Index.insert(KV); + Info.getValue2Index(CmpInst::isSigned(CB.Condition->getPredicate())) + .insert(KV); LLVM_DEBUG(dbgs() << "Adding " << *CB.Condition << " " << CB.Not << "\n"); bool Added = false; - for (auto &C : R.Constraints) { - auto Coeffs = C.Coefficients; + for (auto &E : R.Constraints) { + auto &CSToUse = Info.getCS(E.IsSigned); + if (E.Coefficients.empty()) + continue; + LLVM_DEBUG({ dbgs() << " constraint: "; - dumpWithNames(C, Value2Index); + dumpWithNames(E, Info.getValue2Index(E.IsSigned)); }); - Added |= CS.addVariableRowFill(Coeffs); + + Added |= CSToUse.addVariableRowFill(E.Coefficients); + // If R has been added to the system, queue it for removal once it goes // out-of-scope. if (Added) - DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not); + DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not, + E.IsSigned); } } - assert(CS.size() == DFSInStack.size() && +#ifndef NDEBUG + unsigned SignedEntries = + count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; }); + assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries && "updates to CS and DFSInStack are out of sync"); + assert(Info.getCS(true).size() == SignedEntries && + "updates to CS and DFSInStack are out of sync"); +#endif + return Changed; } diff --git a/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll b/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll --- a/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll +++ b/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll @@ -259,7 +259,7 @@ ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 1 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]] ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]] -; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]] +; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret i4 3 @@ -374,7 +374,7 @@ ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 1 ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]] ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]] -; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]] +; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret i4 3 diff --git a/llvm/test/Transforms/ConstraintElimination/i128.ll b/llvm/test/Transforms/ConstraintElimination/i128.ll --- a/llvm/test/Transforms/ConstraintElimination/i128.ll +++ b/llvm/test/Transforms/ConstraintElimination/i128.ll @@ -35,3 +35,37 @@ bb2: ret void } + + +define void @test_signed_too_large(i128 %x) { +; CHECK-LABEL: @test_signed_too_large( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[C_1:%.*]] = icmp sle i128 [[X:%.*]], 12345678901234123123123 +; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[C_2:%.*]] = icmp slt i128 [[X]], -12345678901234123123123 +; CHECK-NEXT: call void @use(i1 [[C_2]]) +; CHECK-NEXT: [[C_3:%.*]] = icmp sge i128 [[X]], -12345678901234123123123 +; CHECK-NEXT: call void @use(i1 [[C_3]]) +; CHECK-NEXT: [[C_4:%.*]] = icmp sge i128 [[X]], -12345678901234123123123 +; CHECK-NEXT: call void @use(i1 [[C_4]]) +; CHECK-NEXT: ret void +; CHECK: bb2: +; CHECK-NEXT: ret void +; +entry: + %c.1 = icmp sle i128 %x, 12345678901234123123123 + br i1 %c.1, label %bb1, label %bb2 + +bb1: + %c.2 = icmp slt i128 %x, -12345678901234123123123 + call void @use(i1 %c.2) + %c.3 = icmp sge i128 %x, -12345678901234123123123 + call void @use(i1 %c.3) + %c.4 = icmp sge i128 %x, -12345678901234123123123 + call void @use(i1 %c.4) + ret void + +bb2: + ret void +} diff --git a/llvm/test/Transforms/ConstraintElimination/loops-header-tested-base.ll b/llvm/test/Transforms/ConstraintElimination/loops-header-tested-base.ll --- a/llvm/test/Transforms/ConstraintElimination/loops-header-tested-base.ll +++ b/llvm/test/Transforms/ConstraintElimination/loops-header-tested-base.ll @@ -13,9 +13,9 @@ ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]] ; CHECK: loop.latch: ; CHECK-NEXT: [[F_1:%.*]] = icmp sle i32 [[X]], [[N]] -; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]] -; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], 10 ; CHECK-NEXT: call void @use(i1 [[T_2]]) ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9 @@ -77,9 +77,9 @@ ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]] ; CHECK: loop.latch: ; CHECK-NEXT: [[F_1:%.*]] = icmp sle i32 [[X]], [[N]] -; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]] -; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], -10 ; CHECK-NEXT: call void @use(i1 [[T_2]]) ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9 @@ -145,9 +145,9 @@ ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]] ; CHECK-NEXT: call void @use(i1 [[T_1]]) ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], 0 -; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 [[X]], -1 -; CHECK-NEXT: call void @use(i1 [[T_3]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9 ; CHECK-NEXT: call void @use(i1 [[C_2]]) ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9 diff --git a/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll b/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll --- a/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll +++ b/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll @@ -261,7 +261,7 @@ ; CHECK-NEXT: [[SC_2:%.*]] = icmp sle i32 [[X]], [[Y]] ; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[SC_2]] ; CHECK-NEXT: [[SC_3:%.*]] = icmp sle i32 [[Y]], [[Z]] -; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[SC_3]] +; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true ; CHECK-NEXT: [[SC_4:%.*]] = icmp sle i32 [[X]], [[A]] ; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], [[SC_4]] ; CHECK-NEXT: ret i1 [[RES_8]] diff --git a/llvm/test/Transforms/ConstraintElimination/sge.ll b/llvm/test/Transforms/ConstraintElimination/sge.ll --- a/llvm/test/Transforms/ConstraintElimination/sge.ll +++ b/llvm/test/Transforms/ConstraintElimination/sge.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: ; CHECK-NEXT: [[T_1:%.*]] = icmp sge i32 [[X]], [[Y]] -; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[C_2:%.*]] = icmp sge i32 [[X]], 10 ; CHECK-NEXT: call void @use(i1 [[C_2]]) ; CHECK-NEXT: [[C_3:%.*]] = icmp sge i32 [[Y]], [[X]] @@ -20,9 +20,9 @@ ; CHECK-NEXT: ret void ; CHECK: bb2: ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[Y]], [[X]] -; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[F_1:%.*]] = icmp sge i32 [[X]], [[Y]] -; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 10 ; CHECK-NEXT: call void @use(i1 [[C_5]]) ; CHECK-NEXT: [[C_6:%.*]] = icmp sge i32 10, [[X]] @@ -63,9 +63,9 @@ ; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: ; CHECK-NEXT: [[T_1:%.*]] = icmp sge i32 [[X]], 10 -; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], 9 -; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[C_2:%.*]] = icmp sge i32 [[X]], 11 ; CHECK-NEXT: call void @use(i1 [[C_2]]) ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 10, [[X]] @@ -73,11 +73,11 @@ ; CHECK-NEXT: ret void ; CHECK: bb2: ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 11, [[X]] -; CHECK-NEXT: call void @use(i1 [[T_3]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[F_1:%.*]] = icmp sge i32 [[X]], 10 -; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[F_1_1:%.*]] = icmp sge i32 [[X]], 10 -; CHECK-NEXT: call void @use(i1 [[F_1_1]]) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 9 ; CHECK-NEXT: call void @use(i1 [[C_5]]) ; CHECK-NEXT: [[C_6:%.*]] = icmp sge i32 1, [[X]] @@ -125,7 +125,7 @@ ; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]] ; CHECK: bb2: ; CHECK-NEXT: [[C_3:%.*]] = icmp sge i32 [[X]], [[Z]] -; CHECK-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] +; CHECK-NEXT: br i1 true, label [[BB3:%.*]], label [[EXIT]] ; CHECK: bb3: ; CHECK-NEXT: ret i32 10 ; CHECK: exit: @@ -224,7 +224,7 @@ ; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]] ; CHECK: bb2: ; CHECK-NEXT: [[T_1:%.*]] = icmp sge i32 [[X]], [[Z]] -; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[U_1:%.*]] = icmp eq i32 [[X]], [[Z]] ; CHECK-NEXT: call void @use(i1 [[U_1]]) ; CHECK-NEXT: ret i32 10 diff --git a/llvm/test/Transforms/ConstraintElimination/zext.ll b/llvm/test/Transforms/ConstraintElimination/zext.ll --- a/llvm/test/Transforms/ConstraintElimination/zext.ll +++ b/llvm/test/Transforms/ConstraintElimination/zext.ll @@ -169,7 +169,7 @@ ; CHECK: bb1: ; CHECK-NEXT: [[T_1:%.*]] = icmp sge i16 [[X_EXT]], [[Y]] ; CHECK-NEXT: [[C_2:%.*]] = icmp sge i16 [[X_EXT]], 10 -; CHECK-NEXT: [[R_1:%.*]] = xor i1 [[T_1]], [[C_2]] +; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, [[C_2]] ; CHECK-NEXT: [[C_3:%.*]] = icmp sge i16 [[Y]], [[X_EXT]] ; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]] ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i16 10, [[X_EXT]] @@ -178,7 +178,7 @@ ; CHECK: bb2: ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i16 [[Y]], [[X_EXT]] ; CHECK-NEXT: [[F_1:%.*]] = icmp sge i16 [[X_EXT]], [[Y]] -; CHECK-NEXT: [[R_4:%.*]] = xor i1 [[T_2]], [[F_1]] +; CHECK-NEXT: [[R_4:%.*]] = xor i1 true, false ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i16 [[X_EXT]], 10 ; CHECK-NEXT: [[R_5:%.*]] = xor i1 [[R_4]], [[C_5]] ; CHECK-NEXT: [[C_6:%.*]] = icmp sge i16 10, [[X_EXT]]