diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -74,91 +74,26 @@ namespace { -/// LatticeVal class - This class represents the different lattice values that -/// an LLVM value may occupy. It is a simple class with value semantics. -/// -class LatticeVal { - enum LatticeValueTy { - /// unknown - This LLVM Value has no known value yet. - unknown, - - /// constant - This LLVM Value has a specific constant value. - constant, - - /// overdefined - This instruction is not known to be constant, and we know - /// it has a value. - overdefined - }; - - /// Val: This stores the current lattice value along with the Constant* for - /// the constant if this is a 'constant' value. - PointerIntPair Val; - - LatticeValueTy getLatticeValue() const { - return Val.getInt(); - } - -public: - LatticeVal() : Val(nullptr, unknown) {} - - bool isUnknown() const { return getLatticeValue() == unknown; } - - bool isConstant() const { return getLatticeValue() == constant; } - - bool isOverdefined() const { return getLatticeValue() == overdefined; } - - Constant *getConstant() const { - assert(isConstant() && "Cannot get the constant of a non-constant!"); - return Val.getPointer(); - } - - /// markOverdefined - Return true if this is a change in status. - bool markOverdefined() { - if (isOverdefined()) - return false; - - Val.setInt(overdefined); - return true; - } - - /// markConstant - Return true if this is a change in status. - bool markConstant(Constant *V) { - if (getLatticeValue() == constant) { // Constant - assert(getConstant() == V && "Marking constant with different value"); - return false; - } - - assert(isUnknown()); - Val.setInt(constant); - assert(V && "Marking constant with NULL"); - Val.setPointer(V); - return true; - } - - /// getConstantInt - If this is a constant with a ConstantInt value, return it - /// otherwise return null. - ConstantInt *getConstantInt() const { - if (isConstant()) - return dyn_cast(getConstant()); - return nullptr; - } - - /// getBlockAddress - If this is a constant with a BlockAddress value, return - /// it, otherwise return null. - BlockAddress *getBlockAddress() const { - if (isConstant()) - return dyn_cast(getConstant()); - return nullptr; - } +// Use ValueLatticeElement as LatticeVal. +using LatticeVal = ValueLatticeElement; + +// Helper to check if \p LV is either a constant or a constant +// range with a single element. This should cover exactly the same cases as the +// old LatticeVal::isConstant() and is intended to be used in the transition +// from LatticeVal to LatticeValueElement. +bool isConstant(const LatticeVal &LV) { + return LV.isConstant() || + (LV.isConstantRange() && LV.getConstantRange().isSingleElement()); +} - ValueLatticeElement toValueLattice() const { - if (isOverdefined()) - return ValueLatticeElement::getOverdefined(); - if (isConstant()) - return ValueLatticeElement::get(getConstant()); - return ValueLatticeElement(); - } -}; +// Helper to check if \p LV is either overdefined or a constant range with more +// than a single element. This should cover exactly the same cases as the old +// LatticeVal::isOverdefined() and is intended to be used in the transition from +// LatticeVal to LatticeValueElement. +bool isOverdefined(const LatticeVal &LV) { + return LV.isOverdefined() || + (LV.isConstantRange() && !LV.getConstantRange().isSingleElement()); +} //===----------------------------------------------------------------------===// // @@ -170,8 +105,6 @@ std::function GetTLI; SmallPtrSet BBExecutable; // The BBs that are executable. DenseMap ValueState; // The state each value is in. - // The state each parameter is in. - DenseMap ParamState; /// StructValueState - This maintains ValueState for values that have /// StructType, for example for formal arguments, calls, insertelement, etc. @@ -226,6 +159,8 @@ DenseMap AnalysisResults; DenseMap> AdditionalUsers; + LLVMContext &Ctx; + public: void addAnalysis(Function &F, AnalysisResultsForFn A) { AnalysisResults.insert({&F, std::move(A)}); @@ -245,8 +180,9 @@ } SCCPSolver(const DataLayout &DL, - std::function GetTLI) - : DL(DL), GetTLI(std::move(GetTLI)) {} + std::function GetTLI, + LLVMContext &Ctx) + : DL(DL), GetTLI(std::move(GetTLI)), Ctx(Ctx) {} /// MarkBlockExecutable - This method can be used by clients to mark all of /// the blocks that are known to be intrinsically live in the processed unit. @@ -382,20 +318,38 @@ } // isStructLatticeConstant - Return true if all the lattice values - // corresponding to elements of the structure are not overdefined, + // corresponding to elements of the structure are constants, // false otherwise. bool isStructLatticeConstant(Function *F, StructType *STy) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i)); assert(It != TrackedMultipleRetVals.end()); LatticeVal LV = It->second; - if (LV.isOverdefined()) + if (!isConstant(LV)) return false; } return true; } + /// Helper to return a Constant if \p LV is either a constant or a constant + /// range with a single element. + Constant *getConstant(const LatticeVal &LV) const { + if (LV.isConstant()) + return LV.getConstant(); + + if (LV.isConstantRange()) { + auto &CR = LV.getConstantRange(); + if (CR.getSingleElement()) + return ConstantInt::get(Ctx, *CR.getSingleElement()); + } + return nullptr; + } + private: + ConstantInt *getConstantInt(const LatticeVal &IV) const { + return dyn_cast_or_null(getConstant(IV)); + } + // pushToWorkList - Helper for markConstant/markOverdefined void pushToWorkList(LatticeVal &IV, Value *V) { if (IV.isOverdefined()) @@ -403,6 +357,15 @@ InstWorkList.push_back(V); } + // Helper to push \p V to the worklist, after updating it to \p IV. Also + // prints a debug message with the updated value. + void pushToWorkListMsg(LatticeVal &IV, Value *V) { + LLVM_DEBUG(dbgs() << "updated " << IV << ": " << *V << '\n'); + if (IV.isOverdefined()) + return OverdefinedInstWorkList.push_back(V); + InstWorkList.push_back(V); + } + // markConstant - Make a value be marked as "constant". If the value // is not already a constant, add it to the instruction work list so that // the users of the instruction are updated later. @@ -433,22 +396,29 @@ return true; } - bool mergeInValue(LatticeVal &IV, Value *V, LatticeVal MergeWithV) { - if (IV.isOverdefined() || MergeWithV.isUnknown()) - return false; // Noop. - if (MergeWithV.isOverdefined()) - return markOverdefined(IV, V); - if (IV.isUnknown()) - return markConstant(IV, V, MergeWithV.getConstant()); - if (IV.getConstant() != MergeWithV.getConstant()) - return markOverdefined(IV, V); + bool mergeInValue(LatticeVal &IV, Value *V, LatticeVal MergeWithV, + bool Widen = true) { + // Do a simple form of widening, to avoid extending a range repeatedly in a + // loop. If IV is a constant range, it means we already set it once. If + // MergeWithV would extend IV, mark V as overdefined. + if (Widen && IV.isConstantRange() && MergeWithV.isConstantRange() && + !IV.getConstantRange().contains(MergeWithV.getConstantRange())) { + markOverdefined(IV, V); + return true; + } + if (IV.mergeIn(MergeWithV, DL)) { + pushToWorkList(IV, V); + LLVM_DEBUG(dbgs() << "Merged " << MergeWithV << " into " << *V << " : " + << IV << "\n"); + return true; + } return false; } - bool mergeInValue(Value *V, LatticeVal MergeWithV) { + bool mergeInValue(Value *V, LatticeVal MergeWithV, bool Widen = true) { assert(!V->getType()->isStructTy() && "non-structs should use markConstant"); - return mergeInValue(ValueState[V], V, MergeWithV); + return mergeInValue(ValueState[V], V, MergeWithV, Widen); } /// getValueState - Return the LatticeVal object that corresponds to the @@ -492,18 +462,6 @@ return Res; } - ValueLatticeElement &getParamState(Value *V) { - assert(!V->getType()->isStructTy() && "Should use getStructValueState"); - - std::pair::iterator, bool> - PI = ParamState.insert(std::make_pair(V, ValueLatticeElement())); - ValueLatticeElement &LV = PI.first->second; - if (PI.second) - LV = getValueState(V).toValueLattice(); - - return LV; - } - /// getStructValueState - Return the LatticeVal object that corresponds to the /// value/field pair. This function handles the case when the value hasn't /// been seen yet by properly seeding constants etc. @@ -659,7 +617,7 @@ } LatticeVal BCValue = getValueState(BI->getCondition()); - ConstantInt *CI = BCValue.getConstantInt(); + ConstantInt *CI = getConstantInt(BCValue); if (!CI) { // Overdefined condition variables, and branches on unfoldable constant // conditions, mean the branch could go either way. @@ -685,7 +643,7 @@ return; } LatticeVal SCValue = getValueState(SI->getCondition()); - ConstantInt *CI = SCValue.getConstantInt(); + ConstantInt *CI = getConstantInt(SCValue); if (!CI) { // Overdefined or unknown condition? // All destinations are executable! @@ -703,7 +661,7 @@ if (auto *IBR = dyn_cast(&TI)) { // Casts are folded by visitCastInst. LatticeVal IBRValue = getValueState(IBR->getAddress()); - BlockAddress *Addr = IBRValue.getBlockAddress(); + BlockAddress *Addr = dyn_cast_or_null(getConstant(IBRValue)); if (!Addr) { // Overdefined or unknown condition? // All destinations are executable! if (!IBRValue.isUnknown()) @@ -770,8 +728,9 @@ if (PN.getType()->isStructTy()) return (void)markOverdefined(&PN); - if (getValueState(&PN).isOverdefined()) - return; // Quick exit + if (isOverdefined(getValueState(&PN))) { + return (void)markOverdefined(&PN); + } // Super-extra-high-degree PHI nodes are unlikely to ever be marked constant, // and slow us down a lot. Just mark them overdefined. @@ -791,11 +750,11 @@ if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) continue; - if (IV.isOverdefined()) // PHI node becomes overdefined! + if (isOverdefined(IV)) // PHI node becomes overdefined! return (void)markOverdefined(&PN); if (!OperandVal) { // Grab the first value. - OperandVal = IV.getConstant(); + OperandVal = getConstant(IV); continue; } @@ -805,7 +764,7 @@ // Check to see if there are two different constants merging, if so, the PHI // node is overdefined. - if (IV.getConstant() != OperandVal) + if (getConstant(IV) != OperandVal) return (void)markOverdefined(&PN); } @@ -867,17 +826,15 @@ return; LatticeVal OpSt = getValueState(I.getOperand(0)); - if (OpSt.isOverdefined()) // Inherit overdefinedness of operand - markOverdefined(&I); - else if (OpSt.isConstant()) { + if (Constant *OpC = getConstant(OpSt)) { // Fold the constant as we build. - Constant *C = ConstantFoldCastOperand(I.getOpcode(), OpSt.getConstant(), - I.getType(), DL); + Constant *C = ConstantFoldCastOperand(I.getOpcode(), OpC, I.getType(), DL); if (isa(C)) return; // Propagate constant value markConstant(&I, C); - } + } else if (!OpSt.isUnknown()) + markOverdefined(&I); } void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { @@ -959,7 +916,7 @@ if (CondValue.isUnknown()) return; - if (ConstantInt *CondCB = CondValue.getConstantInt()) { + if (ConstantInt *CondCB = getConstantInt(CondValue)) { Value *OpVal = CondCB->isZero() ? I.getFalseValue() : I.getTrueValue(); mergeInValue(&I, getValueState(OpVal)); return; @@ -972,9 +929,9 @@ LatticeVal FVal = getValueState(I.getFalseValue()); // select ?, C, C -> C. - if (TVal.isConstant() && FVal.isConstant() && - TVal.getConstant() == FVal.getConstant()) - return (void)markConstant(&I, FVal.getConstant()); + if (isConstant(TVal) && isConstant(FVal) && + getConstant(TVal) == getConstant(FVal)) + return (void)markConstant(&I, getConstant(FVal)); if (TVal.isUnknown()) // select ?, undef, X -> X. return (void)mergeInValue(&I, FVal); @@ -992,8 +949,8 @@ // discover a concrete value later. if (IV.isOverdefined()) return; - if (V0State.isConstant()) { - Constant *C = ConstantExpr::get(I.getOpcode(), V0State.getConstant()); + if (isConstant(V0State)) { + Constant *C = ConstantExpr::get(I.getOpcode(), getConstant(V0State)); // op Y -> undef. if (isa(C)) @@ -1014,11 +971,14 @@ LatticeVal V2State = getValueState(I.getOperand(1)); LatticeVal &IV = ValueState[&I]; - if (IV.isOverdefined()) return; + if (isOverdefined(IV)) { + markOverdefined(&I); + return; + } - if (V1State.isConstant() && V2State.isConstant()) { - Constant *C = ConstantExpr::get(I.getOpcode(), V1State.getConstant(), - V2State.getConstant()); + if (isConstant(V1State) && isConstant(V2State)) { + Constant *C = ConstantExpr::get(I.getOpcode(), getConstant(V1State), + getConstant(V2State)); // X op Y -> undef. if (isa(C)) return; @@ -1026,18 +986,16 @@ } // If something is undef, wait for it to resolve. - if (!V1State.isOverdefined() && !V2State.isOverdefined()) { - + if (V1State.isUnknown() || V2State.isUnknown()) return; - } // Otherwise, one of our operands is overdefined. Try to produce something // better than overdefined with some tricks. // If this is 0 / Y, it doesn't matter that the second operand is // overdefined, and we can replace it with zero. if (I.getOpcode() == Instruction::UDiv || I.getOpcode() == Instruction::SDiv) - if (V1State.isConstant() && V1State.getConstant()->isNullValue()) - return (void)markConstant(IV, &I, V1State.getConstant()); + if (isConstant(V1State) && getConstant(V1State)->isNullValue()) + return (void)markConstant(IV, &I, getConstant(V1State)); // If this is: // -> AND/MUL with 0 @@ -1046,9 +1004,10 @@ if (I.getOpcode() == Instruction::And || I.getOpcode() == Instruction::Mul || I.getOpcode() == Instruction::Or) { LatticeVal *NonOverdefVal = nullptr; - if (!V1State.isOverdefined()) + if (!isOverdefined(V1State)) NonOverdefVal = &V1State; - else if (!V2State.isOverdefined()) + + else if (!isOverdefined(V2State)) NonOverdefVal = &V2State; if (NonOverdefVal) { if (NonOverdefVal->isUnknown()) @@ -1058,13 +1017,13 @@ I.getOpcode() == Instruction::Mul) { // X and 0 = 0 // X * 0 = 0 - if (NonOverdefVal->getConstant()->isNullValue()) - return (void)markConstant(IV, &I, NonOverdefVal->getConstant()); + if (getConstant(*NonOverdefVal)->isNullValue()) + return (void)markConstant(IV, &I, getConstant(*NonOverdefVal)); } else { // X or -1 = -1 - if (ConstantInt *CI = NonOverdefVal->getConstantInt()) + if (ConstantInt *CI = getConstantInt(*NonOverdefVal)) if (CI->isMinusOne()) - return (void)markConstant(IV, &I, NonOverdefVal->getConstant()); + return (void)markConstant(IV, &I, CI); } } } @@ -1076,22 +1035,18 @@ void SCCPSolver::visitCmpInst(CmpInst &I) { // Do not cache this lookup, getValueState calls later in the function might // invalidate the reference. - if (ValueState[&I].isOverdefined()) return; + if (isOverdefined(ValueState[&I])) { + markOverdefined(&I); + return; + } Value *Op1 = I.getOperand(0); Value *Op2 = I.getOperand(1); // For parameters, use ParamState which includes constant range info if // available. - auto V1Param = ParamState.find(Op1); - ValueLatticeElement V1State = (V1Param != ParamState.end()) - ? V1Param->second - : getValueState(Op1).toValueLattice(); - - auto V2Param = ParamState.find(Op2); - ValueLatticeElement V2State = V2Param != ParamState.end() - ? V2Param->second - : getValueState(Op2).toValueLattice(); + auto V1State = getValueState(Op1); + auto V2State = getValueState(Op2); Constant *C = V1State.getCompare(I.getPredicate(), I.getType(), V2State); if (C) { @@ -1104,8 +1059,8 @@ } // If operands are still unknown, wait for it to resolve. - if (!V1State.isOverdefined() && !V2State.isOverdefined() && - !ValueState[&I].isConstant()) + if ((V1State.isUnknown() || V2State.isUnknown()) && + !isConstant(ValueState[&I])) return; markOverdefined(&I); @@ -1127,8 +1082,12 @@ if (State.isOverdefined()) return (void)markOverdefined(&I); - assert(State.isConstant() && "Unknown state!"); - Operands.push_back(State.getConstant()); + if (Constant *C = getConstant(State)) { + Operands.push_back(C); + continue; + } + + return (void)markOverdefined(&I); } Constant *Ptr = Operands[0]; @@ -1155,7 +1114,8 @@ GlobalVariable *GV = cast(SI.getOperand(1)); DenseMap::iterator I = TrackedGlobals.find(GV); - if (I == TrackedGlobals.end() || I->second.isOverdefined()) return; + if (I == TrackedGlobals.end()) + return; // Get the value we are storing into the global, then merge it. mergeInValue(I->second, GV, getValueState(SI.getOperand(0))); @@ -1180,10 +1140,10 @@ LatticeVal &IV = ValueState[&I]; - if (!PtrVal.isConstant() || I.isVolatile()) + if (!isConstant(PtrVal) || I.isVolatile()) return (void)markOverdefined(IV, &I); - Constant *Ptr = PtrVal.getConstant(); + Constant *Ptr = getConstant(PtrVal); // load null is undefined. if (isa(Ptr)) { @@ -1224,7 +1184,7 @@ if (auto *II = dyn_cast(I)) { if (II->getIntrinsicID() == Intrinsic::ssa_copy) { - if (ValueState[I].isOverdefined()) + if (isOverdefined(ValueState[I])) return; auto *PI = getPredicateInfoFor(I); @@ -1262,7 +1222,7 @@ LatticeVal &IV = ValueState[I]; if (PBranch->TrueEdge && Cmp->getPredicate() == CmpInst::ICMP_EQ) { addAdditionalUser(CmpOp1, I); - if (OriginalVal.isConstant()) + if (isConstant(OriginalVal)) mergeInValue(IV, I, OriginalVal); else mergeInValue(IV, I, EqVal); @@ -1270,7 +1230,7 @@ } if (!PBranch->TrueEdge && Cmp->getPredicate() == CmpInst::ICMP_NE) { addAdditionalUser(CmpOp1, I); - if (OriginalVal.isConstant()) + if (isConstant(OriginalVal)) mergeInValue(IV, I, OriginalVal); else mergeInValue(IV, I, EqVal); @@ -1302,13 +1262,13 @@ if (State.isUnknown()) return; // Operands are not resolved yet. - if (State.isOverdefined()) + if (isOverdefined(State)) return (void)markOverdefined(I); - assert(State.isConstant() && "Unknown state!"); - Operands.push_back(State.getConstant()); + assert(isConstant(State) && "Unknown state!"); + Operands.push_back(getConstant(State)); } - if (getValueState(I).isOverdefined()) + if (isOverdefined(getValueState(I))) return; // If we can constant fold this, mark the result of the call as a @@ -1346,24 +1306,10 @@ if (auto *STy = dyn_cast(AI->getType())) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { LatticeVal CallArg = getStructValueState(*CAI, i); - mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg); + mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg, false); } - } else { - // Most other parts of the Solver still only use the simpler value - // lattice, so we propagate changes for parameters to both lattices. - ValueLatticeElement ConcreteArgument = - isa(*CAI) ? getParamState(*CAI) - : getValueState(*CAI).toValueLattice(); - bool ParamChanged = getParamState(&*AI).mergeIn(ConcreteArgument, DL); - bool ValueChanged = - mergeInValue(&*AI, toLatticeVal(ConcreteArgument, AI->getType())); - // Add argument to work list, if the state of a parameter changes but - // ValueState does not change (because it is already overdefined there), - // We have to take changes in ParamState into account, as it is used - // when evaluating Cmp instructions. - if (!ValueChanged && ParamChanged) - pushToWorkList(ValueState[&*AI], &*AI); - } + } else + mergeInValue(&*AI, getValueState(*CAI), false); } } @@ -1600,24 +1546,24 @@ Constant *Const = nullptr; if (V->getType()->isStructTy()) { std::vector IVs = Solver.getStructLatticeValueFor(V); - if (llvm::any_of(IVs, - [](const LatticeVal &LV) { return LV.isOverdefined(); })) + if (any_of(IVs, [](const LatticeVal &LV) { return isOverdefined(LV); })) return false; std::vector ConstVals; auto *ST = cast(V->getType()); for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { LatticeVal V = IVs[i]; - ConstVals.push_back(V.isConstant() - ? V.getConstant() + ConstVals.push_back(isConstant(V) + ? Solver.getConstant(V) : UndefValue::get(ST->getElementType(i))); } Const = ConstantStruct::get(ST, ConstVals); } else { const LatticeVal &IV = Solver.getLatticeValueFor(V); - if (IV.isOverdefined()) + if (isOverdefined(IV)) return false; - Const = IV.isConstant() ? IV.getConstant() : UndefValue::get(V->getType()); + Const = + isConstant(IV) ? Solver.getConstant(IV) : UndefValue::get(V->getType()); } assert(Const && "Constant is nullptr here!"); @@ -1650,7 +1596,8 @@ const TargetLibraryInfo *TLI) { LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n"); SCCPSolver Solver( - DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; }); + DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; }, + F.getContext()); // Mark the first block of the function as being executable. Solver.MarkBlockExecutable(&F.front()); @@ -1852,7 +1799,7 @@ Module &M, const DataLayout &DL, std::function GetTLI, function_ref getAnalysis) { - SCCPSolver Solver(DL, GetTLI); + SCCPSolver Solver(DL, GetTLI, M.getContext()); // Loop over all functions, marking arguments to those with their addresses // taken or that are external as overdefined. @@ -2038,7 +1985,7 @@ const MapVector &RV = Solver.getTrackedRetVals(); for (const auto &I : RV) { Function *F = I.first; - if (I.second.isOverdefined() || F->getReturnType()->isVoidTy()) + if (isOverdefined(I.second) || F->getReturnType()->isVoidTy()) continue; findReturnsToZap(*F, ReturnsToZap, Solver); } @@ -2063,8 +2010,8 @@ for (DenseMap::const_iterator I = TG.begin(), E = TG.end(); I != E; ++I) { GlobalVariable *GV = I->first; - assert(!I->second.isOverdefined() && - "Overdefined values should have been taken out of the map!"); + if (isOverdefined(I->second)) + continue; LLVM_DEBUG(dbgs() << "Found that GV '" << GV->getName() << "' is constant!\n"); while (!GV->use_empty()) { diff --git a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll --- a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll +++ b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll @@ -230,7 +230,7 @@ ; CHECK-NEXT: %call.1 = call i32 @callee6.1(i32 30) ; CHECK-NEXT: %call.2 = call i32 @callee6.1(i32 43) ; CHECK-NEXT: ret i32 2 - +; %call.1 = call i32 @callee6.1(i32 30) %call.2 = call i32 @callee6.1(i32 43) %res = add i32 %call.1, %call.2 diff --git a/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll b/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll --- a/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll +++ b/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll @@ -40,9 +40,7 @@ ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = inttoptr i64 [[CONV]] to %t1* ; CHECK-NEXT: [[CALL:%.*]] = call i1 @test1_g(%t1* [[TMP1]], i32 0) -; CHECK-NEXT: [[FROMBOOL_1:%.*]] = zext i1 false to i8 -; CHECK-NEXT: [[TOBOOL_1:%.*]] = trunc i8 [[FROMBOOL_1]] to i1 -; CHECK-NEXT: call void @use.1(i1 [[TOBOOL_1]]) +; CHECK-NEXT: call void @use.1(i1 false) ; CHECK-NEXT: ret i32 undef ; entry: @@ -119,9 +117,7 @@ ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = inttoptr i64 [[CONV]] to %t1* ; CHECK-NEXT: [[CALL:%.*]] = call i1 @test3_g(%t1* [[TMP1]], i32 0) -; CHECK-NEXT: [[FROMBOOL:%.*]] = icmp slt i1 false, true -; CHECK-NEXT: [[ADD:%.*]] = add i1 [[FROMBOOL]], [[FROMBOOL]] -; CHECK-NEXT: call void @use.1(i1 [[FROMBOOL]]) +; CHECK-NEXT: call void @use.1(i1 false) ; CHECK-NEXT: ret i32 undef ; entry: @@ -393,7 +389,6 @@ ; CHECK-NEXT: [[CMP25474:%.*]] = icmp sgt i32 [[TMP2]], 0 ; CHECK-NEXT: br i1 [[CMP25474]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] ; CHECK: for.body: -; CHECK-NEXT: [[DIV30:%.*]] = sdiv i32 0, [[SUB19]] ; CHECK-NEXT: ret void ; CHECK: for.end: ; CHECK-NEXT: ret void