diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index dcdc3483a9088c..e1a2ec2b93f089 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -352,7 +352,7 @@ class SCCPSolver : public InstVisitor { // pushToWorkList - Helper for markConstant/markOverdefined void pushToWorkList(LatticeVal &IV, Value *V) { - if (isOverdefined(IV)) + if (IV.isOverdefined()) return OverdefinedInstWorkList.push_back(V); InstWorkList.push_back(V); } @@ -361,7 +361,7 @@ class SCCPSolver : public InstVisitor { // prints a debug message with the updated value. void pushToWorkListMsg(LatticeVal &IV, Value *V) { LLVM_DEBUG(dbgs() << "updated " << IV << ": " << *V << '\n'); - if (isOverdefined(IV)) + if (IV.isOverdefined()) return OverdefinedInstWorkList.push_back(V); InstWorkList.push_back(V); } @@ -779,7 +779,7 @@ void SCCPSolver::visitReturnInst(ReturnInst &I) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. if (isOverdefined(ValueState[&I])) - return; + return (void)markOverdefined(&I); Function *F = I.getParent()->getParent(); Value *ResultOp = I.getOperand(0); @@ -820,7 +820,7 @@ void SCCPSolver::visitCastInst(CastInst &I) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. if (isOverdefined(ValueState[&I])) - return; + return (void)markOverdefined(&I); LatticeVal OpSt = getValueState(I.getOperand(0)); if (Constant *OpC = getConstant(OpSt)) { @@ -838,7 +838,7 @@ void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. if (isOverdefined(ValueState[&EVI])) - return; + return (void)markOverdefined(&EVI); // If this returns a struct, mark all elements over defined, we don't track // structs in structs. @@ -868,7 +868,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. if (isOverdefined(ValueState[&IVI])) - return; + return (void)markOverdefined(&IVI); // If this has more than one index, we can't handle it, drive all results to // undef. @@ -906,8 +906,8 @@ void SCCPSolver::visitSelectInst(SelectInst &I) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. - if (isOverdefined(ValueState[&I])) - return; + if (ValueState[&I].isOverdefined()) + return (void)markOverdefined(&I); LatticeVal CondValue = getValueState(I.getCondition()); if (CondValue.isUnknownOrUndef()) @@ -944,7 +944,8 @@ void SCCPSolver::visitUnaryOperator(Instruction &I) { LatticeVal &IV = ValueState[&I]; // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. - if (isOverdefined(IV)) return; + if (isOverdefined(IV)) + return (void)markOverdefined(&I); if (isConstant(V0State)) { Constant *C = ConstantExpr::get(I.getOpcode(), getConstant(V0State)); @@ -968,10 +969,8 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) { LatticeVal V2State = getValueState(I.getOperand(1)); LatticeVal &IV = ValueState[&I]; - if (isOverdefined(IV)) { - markOverdefined(&I); - return; - } + if (isOverdefined(IV)) + return (void)markOverdefined(&I); if (isConstant(V1State) && isConstant(V2State)) { Constant *C = ConstantExpr::get(I.getOpcode(), getConstant(V1State), @@ -1032,10 +1031,8 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) { void SCCPSolver::visitCmpInst(CmpInst &I) { // Do not cache this lookup, getValueState calls later in the function might // invalidate the reference. - if (isOverdefined(ValueState[&I])) { - markOverdefined(&I); - return; - } + if (isOverdefined(ValueState[&I])) + return (void)markOverdefined(&I); Value *Op1 = I.getOperand(0); Value *Op2 = I.getOperand(1); @@ -1066,7 +1063,8 @@ void SCCPSolver::visitCmpInst(CmpInst &I) { // Handle getelementptr instructions. If all operands are constants then we // can turn this into a getelementptr ConstantExpr. void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) { - if (isOverdefined(ValueState[&I])) return; + if (isOverdefined(ValueState[&I])) + return (void)markOverdefined(&I); SmallVector Operands; Operands.reserve(I.getNumOperands()); @@ -1107,7 +1105,7 @@ void SCCPSolver::visitStoreInst(StoreInst &SI) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. if (isOverdefined(ValueState[&SI])) - return; + return (void)markOverdefined(&SI); GlobalVariable *GV = cast(SI.getOperand(1)); DenseMap::iterator I = TrackedGlobals.find(GV); @@ -1130,7 +1128,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) { // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would // discover a concrete value later. if (isOverdefined(ValueState[&I])) - return; + return (void)markOverdefined(&I); LatticeVal PtrVal = getValueState(I.getOperand(0)); if (PtrVal.isUnknownOrUndef()) @@ -1267,7 +1265,7 @@ void SCCPSolver::visitCallSite(CallSite CS) { } if (isOverdefined(getValueState(I))) - return; + return (void)markOverdefined(I); // If we can constant fold this, mark the result of the call as a // constant. @@ -1365,7 +1363,7 @@ void SCCPSolver::Solve() { // since all of its users will have already been marked as overdefined. // Update all of the users of this instruction's value. // - if (I->getType()->isStructTy() || !isOverdefined(getValueState(I))) + if (I->getType()->isStructTy() || !getValueState(I).isOverdefined()) markUsersAsChanged(I); } diff --git a/llvm/test/Transforms/SCCP/ip-ranges-select.ll b/llvm/test/Transforms/SCCP/ip-ranges-select.ll new file mode 100644 index 00000000000000..b19dc43352625f --- /dev/null +++ b/llvm/test/Transforms/SCCP/ip-ranges-select.ll @@ -0,0 +1,37 @@ +; RUN: opt -ipsccp -S %s -o -| FileCheck %s + +define void @caller.1(i8* %arg) { +; CHECK-LABEL: define void @caller.1(i8* %arg) { +; CHECK-NEXT: %r.1 = tail call i32 @callee.1(i32 4) +; CHECK-NEXT: %r.2 = tail call i32 @callee.1(i32 2) +; CHECK-NEXT: call void @use(i32 20) +; CHECK-NEXT: ret void +; + %r.1 = tail call i32 @callee.1(i32 4) + %r.2 = tail call i32 @callee.1(i32 2) + %r.3 = add i32 %r.1, %r.2 + call void @use(i32 %r.3) + ret void +} + +define internal i32 @callee.1(i32 %arg) { +; CHECK-LABEL: define internal i32 @callee.1(i32 %arg) { +; CHECK-NEXT: %sel = select i1 false, i32 16, i32 %arg +; CHECK-NEXT: br label %bb10 +; +; CHECK-LABEL: bb10: +; CHECK-NEXT: ret i32 undef +; + %c.1 = icmp slt i32 %arg, 0 + %sel = select i1 %c.1, i32 16, i32 %arg + %c.2 = icmp eq i32 %sel, 0 + br i1 %c.2, label %bb12, label %bb10 + +bb10: ; preds = %bb8 + ret i32 10 + +bb12: ; preds = %bb8, %bb3, %bb + ret i32 12 +} + +declare void @use(i32)