diff --git a/llvm/include/llvm/Analysis/ValueLattice.h b/llvm/include/llvm/Analysis/ValueLattice.h --- a/llvm/include/llvm/Analysis/ValueLattice.h +++ b/llvm/include/llvm/Analysis/ValueLattice.h @@ -44,6 +44,10 @@ /// overdefined undef, + /// The same as undef state except it is an PoisonValue constant or produces + /// poison. + poison, + /// This Value has a specific constant value. The constant cannot be undef. /// (For constant integers, constantrange is used instead. Integer typed /// constantexprs can appear as constant.) Note that the constant state @@ -96,6 +100,7 @@ case overdefined: case unknown: case undef: + case poison: case constant: case notconstant: break; @@ -164,6 +169,7 @@ case overdefined: case unknown: case undef: + case poison: break; } } @@ -183,6 +189,7 @@ case overdefined: case unknown: case undef: + case poison: break; } Other.Tag = unknown; @@ -238,8 +245,11 @@ } bool isUndef() const { return Tag == undef; } + bool isPoison() const { return Tag == poison; } bool isUnknown() const { return Tag == unknown; } - bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; } + bool isUnknownOrUndefOrPoison() const { + return Tag == unknown || Tag == undef || Tag == poison; + } bool isConstant() const { return Tag == constant; } bool isNotConstant() const { return Tag == notconstant; } bool isConstantRangeIncludingUndef() const { @@ -292,6 +302,15 @@ return true; } + bool markPoison() { + if (isPoison()) + return false; + + assert(isUnknown()); + Tag = poison; + return true; + } + bool markUndef() { if (isUndef()) return false; @@ -302,6 +321,9 @@ } bool markConstant(Constant *V, bool MayIncludeUndef = false) { + if (isa(V)) + return markPoison(); + if (isa(V)) return markUndef(); @@ -375,7 +397,7 @@ return true; } - assert(isUnknown() || isUndef()); + assert(isUnknownOrUndefOrPoison()); NumRangeExtensions = 0; Tag = NewTag; @@ -394,9 +416,11 @@ return true; } - if (isUndef()) { + if (isUndef() || isPoison()) { assert(!RHS.isUnknown()); - if (RHS.isUndef()) + if (isPoison() && RHS.isUndef()) + return markUndef(); + if (RHS.isUndef() || RHS.isPoison()) return false; if (RHS.isConstant()) return markConstant(RHS.getConstant(), true); diff --git a/llvm/lib/Analysis/ValueLattice.cpp b/llvm/lib/Analysis/ValueLattice.cpp --- a/llvm/lib/Analysis/ValueLattice.cpp +++ b/llvm/lib/Analysis/ValueLattice.cpp @@ -57,6 +57,8 @@ return OS << "unknown"; if (Val.isUndef()) return OS << "undef"; + if (Val.isPoison()) + return OS << "poison"; if (Val.isOverdefined()) return OS << "overdefined"; diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp --- a/llvm/lib/Transforms/IPO/SCCP.cpp +++ b/llvm/lib/Transforms/IPO/SCCP.cpp @@ -311,7 +311,8 @@ } if (F->getReturnType()->isVoidTy()) continue; - if (SCCPSolver::isConstant(ReturnValue) || ReturnValue.isUnknownOrUndef()) + if (SCCPSolver::isConstant(ReturnValue) || + ReturnValue.isUnknownOrUndefOrPoison()) findReturnsToZap(*F, ReturnsToZap, Solver); } diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -53,12 +53,12 @@ namespace llvm { bool SCCPSolver::isConstant(const ValueLatticeElement &LV) { - return LV.isConstant() || + return LV.isConstant() || LV.isPoison() || LV.isUndef() || (LV.isConstantRange() && LV.getConstantRange().isSingleElement()); } bool SCCPSolver::isOverdefined(const ValueLatticeElement &LV) { - return !LV.isUnknownOrUndef() && !SCCPSolver::isConstant(LV); + return !LV.isUnknownOrUndefOrPoison() && !SCCPSolver::isConstant(LV); } static bool canRemoveInstruction(Instruction *I) { @@ -887,6 +887,12 @@ Constant *SCCPInstVisitor::getConstant(const ValueLatticeElement &LV, Type *Ty) const { + if (LV.isPoison()) + return PoisonValue::get(Ty); + + if (LV.isUndef()) + return UndefValue::get(Ty); + if (LV.isConstant()) { Constant *C = LV.getConstant(); assert(C->getType() == Ty && "Type mismatch"); @@ -1019,7 +1025,7 @@ if (!CI) { // Overdefined condition variables, and branches on unfoldable constant // conditions, mean the branch could go either way. - if (!BCValue.isUnknownOrUndef()) + if (!BCValue.isUnknownOrUndefOrPoison()) Succs[0] = Succs[1] = true; return; } @@ -1063,7 +1069,7 @@ } // Overdefined or unknown condition? All destinations are executable! - if (!SCValue.isUnknownOrUndef()) + if (!SCValue.isUnknownOrUndefOrPoison()) Succs.assign(TI.getNumSuccessors(), true); return; } @@ -1077,7 +1083,7 @@ getConstant(IBRValue, IBR->getAddress()->getType())); if (!Addr) { // Overdefined or unknown condition? // All destinations are executable! - if (!IBRValue.isUnknownOrUndef()) + if (!IBRValue.isUnknownOrUndefOrPoison()) Succs.assign(TI.getNumSuccessors(), true); return; } @@ -1226,7 +1232,7 @@ return; ValueLatticeElement OpSt = getValueState(I.getOperand(0)); - if (OpSt.isUnknownOrUndef()) + if (OpSt.isUnknown()) return; if (Constant *OpC = getConstant(OpSt, I.getOperand(0)->getType())) { @@ -1264,7 +1270,7 @@ ValueLatticeElement R = getValueState(RHS); addAdditionalUser(LHS, &EVI); addAdditionalUser(RHS, &EVI); - if (L.isUnknownOrUndef() || R.isUnknownOrUndef()) + if (L.isUnknownOrUndefOrPoison() || R.isUnknownOrUndefOrPoison()) return; // Wait to resolve. Type *Ty = LHS->getType(); @@ -1361,7 +1367,7 @@ return (void)markOverdefined(&I); ValueLatticeElement CondValue = getValueState(I.getCondition()); - if (CondValue.isUnknownOrUndef()) + if (CondValue.isUnknownOrUndefOrPoison()) return; if (ConstantInt *CondCB = @@ -1394,7 +1400,7 @@ return (void)markOverdefined(&I); // If something is unknown/undef, wait for it to resolve. - if (V0State.isUnknownOrUndef()) + if (V0State.isUnknown()) return; if (SCCPSolver::isConstant(V0State)) @@ -1419,7 +1425,7 @@ return (void)markOverdefined(&I); // If something is unknown/undef, wait for it to resolve. - if (V0State.isUnknownOrUndef()) + if (V0State.isUnknownOrUndefOrPoison()) return; if (SCCPSolver::isConstant(V0State) && @@ -1439,7 +1445,7 @@ return; // If something is undef, wait for it to resolve. - if (V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef()) + if (V1State.isUnknownOrUndefOrPoison() || V2State.isUnknownOrUndefOrPoison()) return; if (V1State.isOverdefined() && V2State.isOverdefined()) @@ -1447,7 +1453,7 @@ // If either of the operands is a constant, try to fold it to a constant. // TODO: Use information from notconstant better. - if ((V1State.isConstant() || V2State.isConstant())) { + if ((SCCPSolver::isConstant(V1State) || SCCPSolver::isConstant(V2State))) { Value *V1 = SCCPSolver::isConstant(V1State) ? getConstant(V1State, I.getOperand(0)->getType()) : I.getOperand(0); @@ -1507,7 +1513,8 @@ } // If operands are still unknown, wait for it to resolve. - if ((V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef()) && + if ((V1State.isUnknownOrUndefOrPoison() || + V2State.isUnknownOrUndefOrPoison()) && !SCCPSolver::isConstant(ValueState[&I])) return; @@ -1525,7 +1532,7 @@ for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { ValueLatticeElement State = getValueState(I.getOperand(i)); - if (State.isUnknownOrUndef()) + if (State.isUnknownOrUndefOrPoison()) return; // Operands are not resolved yet. if (SCCPSolver::isOverdefined(State)) @@ -1591,7 +1598,7 @@ return (void)markOverdefined(&I); ValueLatticeElement PtrVal = getValueState(I.getOperand(0)); - if (PtrVal.isUnknownOrUndef()) + if (PtrVal.isUnknownOrUndefOrPoison()) return; // The pointer is not resolved yet! ValueLatticeElement &IV = ValueState[&I]; @@ -1655,7 +1662,7 @@ continue; // Carried in CB, not allowed in Operands. ValueLatticeElement State = getValueState(A); - if (State.isUnknownOrUndef()) + if (State.isUnknownOrUndefOrPoison()) return; // Operands are not resolved yet. if (SCCPSolver::isOverdefined(State)) return (void)markOverdefined(&CB); @@ -1792,7 +1799,7 @@ SmallVector OpRanges; for (Value *Op : II->args()) { const ValueLatticeElement &State = getValueState(Op); - if (State.isUnknownOrUndef()) + if (State.isUnknownOrUndefOrPoison()) return; OpRanges.push_back(getConstantRange(State, Op->getType())); } diff --git a/llvm/test/Transforms/SCCP/PR16052.ll b/llvm/test/Transforms/SCCP/PR16052.ll --- a/llvm/test/Transforms/SCCP/PR16052.ll +++ b/llvm/test/Transforms/SCCP/PR16052.ll @@ -5,11 +5,9 @@ target triple = "x86_64-unknown-linux-gnu" define i64 @fn2() { -; CHECK-LABEL: define {{[^@]+}}@fn2() +; CHECK-LABEL: define {{[^@]+}}@fn2() { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CONV:%.*]] = sext i32 undef to i64 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) +; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 poison) ; CHECK-NEXT: ret i64 [[CALL2]] ; entry: @@ -21,10 +19,10 @@ define internal i64 @fn1(i64 %p1) { ; CHECK-LABEL: define {{[^@]+}}@fn1 -; CHECK-SAME: (i64 [[P1:%.*]]) +; CHECK-SAME: (i64 [[P1:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0 -; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 poison, 0 +; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 poison, i64 poison ; CHECK-NEXT: ret i64 [[COND]] ; entry: diff --git a/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll b/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll --- a/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll +++ b/llvm/test/Transforms/SCCP/binaryops-range-special-cases.ll @@ -102,8 +102,7 @@ ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) -; CHECK-NEXT: [[UREM_3:%.*]] = urem i16 12704, 0 -; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[UREM_3]], 1 +; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 poison, 1 ; CHECK-NEXT: call void @use(i1 [[C_5]]) ; CHECK-NEXT: ret void ; @@ -130,8 +129,7 @@ ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) -; CHECK-NEXT: [[SREM_3:%.*]] = urem i16 12704, 0 -; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 [[SREM_3]], 1 +; CHECK-NEXT: [[C_5:%.*]] = icmp eq i16 poison, 1 ; CHECK-NEXT: call void @use(i1 [[C_5]]) ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/SCCP/ip-ranges-phis.ll b/llvm/test/Transforms/SCCP/ip-ranges-phis.ll --- a/llvm/test/Transforms/SCCP/ip-ranges-phis.ll +++ b/llvm/test/Transforms/SCCP/ip-ranges-phis.ll @@ -56,11 +56,11 @@ ; CHECK-NEXT: [[V_2:%.*]] = select i1 [[C_2]], i32 20, i32 200 ; CHECK-NEXT: [[V_3:%.*]] = select i1 [[C_3]], i32 30, i32 300 ; CHECK-NEXT: [[R_1:%.*]] = add nuw nsw i32 [[V_1]], [[V_2]] -; CHECK-NEXT: [[R_2:%.*]] = add nuw nsw i32 [[R_1]], [[V_3]] -; CHECK-NEXT: [[R_3:%.*]] = add nuw nsw i32 [[R_2]], 400 -; CHECK-NEXT: [[R_4:%.*]] = add nuw nsw i32 [[R_3]], 50 -; CHECK-NEXT: [[R_5:%.*]] = add nuw nsw i32 [[R_4]], 60 -; CHECK-NEXT: [[R_6:%.*]] = add nuw nsw i32 [[R_4]], 700 +; CHECK-NEXT: [[R_2:%.*]] = add i32 [[R_1]], [[V_3]] +; CHECK-NEXT: [[R_3:%.*]] = add i32 [[R_2]], 400 +; CHECK-NEXT: [[R_4:%.*]] = add i32 [[R_3]], 50 +; CHECK-NEXT: [[R_5:%.*]] = add i32 [[R_4]], 60 +; CHECK-NEXT: [[R_6:%.*]] = add i32 [[R_4]], 700 ; CHECK-NEXT: ret i32 [[R_6]] ; @@ -204,7 +204,7 @@ ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 5, [[IF_TRUE]] ] -; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @f3(i32 [[P1]], i32 [[Y]], i1 [[CMP_1]]) +; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @f3(i32 [[P1]], i32 [[Y]], i1 [[CMP_1]]), !range [[RNG0:![0-9]+]] ; CHECK-NEXT: ret i32 [[CALL1]] ; diff --git a/llvm/test/Transforms/SCCP/ipsccp-cycles.ll b/llvm/test/Transforms/SCCP/ipsccp-cycles.ll --- a/llvm/test/Transforms/SCCP/ipsccp-cycles.ll +++ b/llvm/test/Transforms/SCCP/ipsccp-cycles.ll @@ -89,12 +89,12 @@ define i32 @test3b(i32 %a) { ; CHECK-LABEL: @test3b( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[V1:%.*]] = call i32 @test3a(i32 0) +; CHECK-NEXT: [[V1:%.*]] = call i32 @test3a(i32 0), !range [[RNG0:![0-9]+]] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[V2:%.*]] = call i32 @test3a(i32 [[V1]]) +; CHECK-NEXT: [[V2:%.*]] = call i32 @test3a(i32 [[V1]]), !range [[RNG0]] ; CHECK-NEXT: [[V3:%.*]] = add i32 [[V2]], 1 -; CHECK-NEXT: [[V4:%.*]] = call i32 @test3a(i32 [[V3]]) +; CHECK-NEXT: [[V4:%.*]] = call i32 @test3a(i32 [[V3]]), !range [[RNG0]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[V4]], [[A:%.*]] ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[LOOP]] ; CHECK: exit: @@ -120,14 +120,14 @@ ; Check for a range extension cycle through a struct argument. define internal i32 @test4a(%struct.S %s) { ; CHECK-LABEL: @test4a( -; CHECK-NEXT: [[A:%.*]] = extractvalue [[STRUCT_S:%.*]] %s, 0 -; CHECK-NEXT: [[B:%.*]] = extractvalue [[STRUCT_S]] %s, 1 +; CHECK-NEXT: [[A:%.*]] = extractvalue [[STRUCT_S:%.*]] [[S:%.*]], 0 +; CHECK-NEXT: [[B:%.*]] = extractvalue [[STRUCT_S]] [[S]], 1 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A]], 1 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X]], [[B]] ; CHECK-NEXT: br i1 [[C]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]] ; CHECK: bb.true: -; CHECK-NEXT: [[S2:%.*]] = insertvalue [[STRUCT_S]] %s, i32 [[X]], 0 -; CHECK-NEXT: [[R:%.*]] = call i32 @test4a(%struct.S [[S2]]) +; CHECK-NEXT: [[S2:%.*]] = insertvalue [[STRUCT_S]] [[S]], i32 [[X]], 0 +; CHECK-NEXT: [[R:%.*]] = call i32 @test4a([[STRUCT_S]] [[S2]]) ; CHECK-NEXT: ret i32 [[R]] ; CHECK: bb.false: ; CHECK-NEXT: ret i32 [[A]] @@ -151,7 +151,7 @@ define i32 @test4b(i32 %b) { ; CHECK-LABEL: @test4b( ; CHECK-NEXT: [[S2:%.*]] = insertvalue [[STRUCT_S:%.*]] { i32 17, i32 undef }, i32 [[B:%.*]], 1 -; CHECK-NEXT: [[X:%.*]] = call i32 @test4a(%struct.S [[S2]]) +; CHECK-NEXT: [[X:%.*]] = call i32 @test4a([[STRUCT_S]] [[S2]]) ; CHECK-NEXT: ret i32 [[X]] ; %s1 = insertvalue %struct.S undef, i32 17, 0 @@ -207,10 +207,10 @@ ; CHECK-NEXT: br i1 [[TMP]], label [[BB6:%.*]], label [[BB3:%.*]] ; CHECK: bb3: ; CHECK-NEXT: [[S1:%.*]] = tail call [[STRUCT:%.*]] @test6a(ptr [[ARG]], i32 0, i32 -1) -; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[STRUCT]] %s1, 0 +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[STRUCT]] [[S1]], 0 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw i32 [[TMP4]], -1 -; CHECK-NEXT: [[S2:%.*]] = insertvalue [[STRUCT]] %s1, i32 [[TMP5]], 0 -; CHECK-NEXT: ret [[STRUCT]] %s2 +; CHECK-NEXT: [[S2:%.*]] = insertvalue [[STRUCT]] [[S1]], i32 [[TMP5]], 0 +; CHECK-NEXT: ret [[STRUCT]] [[S2]] ; CHECK: bb6: ; CHECK-NEXT: ret [[STRUCT]] { i32 0, i32 undef } ; diff --git a/llvm/test/Transforms/SCCP/loadtest2.ll b/llvm/test/Transforms/SCCP/loadtest2.ll --- a/llvm/test/Transforms/SCCP/loadtest2.ll +++ b/llvm/test/Transforms/SCCP/loadtest2.ll @@ -1,12 +1,14 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt < %s -data-layout="E-p:32:32" -passes=ipsccp -S | FileCheck %s @j = internal global i32 undef, align 4 ; Make sure we do not mark loads from undef as overdefined. define i32 @test5(i32 %b) { -; CHECK-LABEL: define i32 @test5(i32 %b) -; CHECK-NEXT: %add = add nsw i32 undef, %b -; CHECK-NEXT: ret i32 %add +; CHECK-LABEL: define i32 @test5 +; CHECK-SAME: (i32 [[B:%.*]]) { +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 undef, [[B]] +; CHECK-NEXT: ret i32 [[ADD]] ; %l = load i32, ptr @j, align 4 %add = add nsw i32 %l, %b diff --git a/llvm/test/Transforms/SCCP/overdefined-div.ll b/llvm/test/Transforms/SCCP/overdefined-div.ll --- a/llvm/test/Transforms/SCCP/overdefined-div.ll +++ b/llvm/test/Transforms/SCCP/overdefined-div.ll @@ -25,8 +25,7 @@ define i32 @test3(i32 %foo) { ; CHECK-LABEL: define i32 @test3 ; CHECK-SAME: (i32 [[FOO:%.*]]) { -; CHECK-NEXT: [[TINKYWINKY:%.*]] = udiv i32 [[FOO]], 0 -; CHECK-NEXT: ret i32 [[TINKYWINKY]] +; CHECK-NEXT: ret i32 poison ; %tinkywinky = udiv i32 %foo, 0 ret i32 %tinkywinky @@ -35,8 +34,7 @@ define i32 @test4(i32 %foo) { ; CHECK-LABEL: define i32 @test4 ; CHECK-SAME: (i32 [[FOO:%.*]]) { -; CHECK-NEXT: [[TINKYWINKY:%.*]] = sdiv i32 [[FOO]], 0 -; CHECK-NEXT: ret i32 [[TINKYWINKY]] +; CHECK-NEXT: ret i32 poison ; %tinkywinky = sdiv i32 %foo, 0 ret i32 %tinkywinky diff --git a/llvm/test/Transforms/SCCP/ub-shift.ll b/llvm/test/Transforms/SCCP/ub-shift.ll --- a/llvm/test/Transforms/SCCP/ub-shift.ll +++ b/llvm/test/Transforms/SCCP/ub-shift.ll @@ -3,10 +3,9 @@ define void @shift_undef_64(ptr %p) { ; CHECK-LABEL: @shift_undef_64( -; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 4 -; CHECK-NEXT: store i64 -1, ptr [[P]], align 4 -; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i64 -1, 4294967298 -; CHECK-NEXT: store i64 [[R3]], ptr [[P]], align 4 +; CHECK-NEXT: store i64 poison, ptr [[P:%.*]], align 4 +; CHECK-NEXT: store i64 poison, ptr [[P]], align 4 +; CHECK-NEXT: store i64 poison, ptr [[P]], align 4 ; CHECK-NEXT: ret void ; %r1 = lshr i64 -1, 4294967296 ; 2^32 @@ -23,10 +22,9 @@ define void @shift_undef_65(ptr %p) { ; CHECK-LABEL: @shift_undef_65( -; CHECK-NEXT: store i65 0, ptr [[P:%.*]], align 4 -; CHECK-NEXT: store i65 0, ptr [[P]], align 4 -; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i65 1, -18446744073709551615 -; CHECK-NEXT: store i65 [[R3]], ptr [[P]], align 4 +; CHECK-NEXT: store i65 poison, ptr [[P:%.*]], align 4 +; CHECK-NEXT: store i65 poison, ptr [[P]], align 4 +; CHECK-NEXT: store i65 poison, ptr [[P]], align 4 ; CHECK-NEXT: ret void ; %r1 = lshr i65 2, 18446744073709551617 @@ -43,10 +41,9 @@ define void @shift_undef_256(ptr %p) { ; CHECK-LABEL: @shift_undef_256( -; CHECK-NEXT: store i256 0, ptr [[P:%.*]], align 4 -; CHECK-NEXT: store i256 0, ptr [[P]], align 4 -; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i256 1, 18446744073709551619 -; CHECK-NEXT: store i256 [[R3]], ptr [[P]], align 4 +; CHECK-NEXT: store i256 poison, ptr [[P:%.*]], align 4 +; CHECK-NEXT: store i256 poison, ptr [[P]], align 4 +; CHECK-NEXT: store i256 poison, ptr [[P]], align 4 ; CHECK-NEXT: ret void ; %r1 = lshr i256 2, 18446744073709551617 @@ -63,10 +60,9 @@ define void @shift_undef_511(ptr %p) { ; CHECK-LABEL: @shift_undef_511( -; CHECK-NEXT: store i511 0, ptr [[P:%.*]], align 4 -; CHECK-NEXT: store i511 -1, ptr [[P]], align 4 -; CHECK-NEXT: [[R3:%.*]] = shl nuw nsw i511 -3, 1208925819614629174706180 -; CHECK-NEXT: store i511 [[R3]], ptr [[P]], align 4 +; CHECK-NEXT: store i511 poison, ptr [[P:%.*]], align 4 +; CHECK-NEXT: store i511 poison, ptr [[P]], align 4 +; CHECK-NEXT: store i511 poison, ptr [[P]], align 4 ; CHECK-NEXT: ret void ; %r1 = lshr i511 -1, 1208925819614629174706276 ; 2^80 + 100 diff --git a/llvm/test/Transforms/SCCP/undef-resolve.ll b/llvm/test/Transforms/SCCP/undef-resolve.ll --- a/llvm/test/Transforms/SCCP/undef-resolve.ll +++ b/llvm/test/Transforms/SCCP/undef-resolve.ll @@ -5,8 +5,7 @@ ; PR6940 define double @test1() { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[T:%.*]] = sitofp i32 undef to double -; CHECK-NEXT: ret double [[T]] +; CHECK-NEXT: ret double 0.000000e+00 ; %t = sitofp i32 undef to double ret double %t @@ -195,8 +194,7 @@ ; Make sure casts produce a possible value define i32 @test5() { ; CHECK-LABEL: @test5( -; CHECK-NEXT: [[T:%.*]] = sext i8 undef to i32 -; CHECK-NEXT: ret i32 [[T]] +; CHECK-NEXT: ret i32 0 ; %t = sext i8 undef to i32 ret i32 %t @@ -269,8 +267,7 @@ ; Test unary ops define double @test12(double %x) { ; CHECK-LABEL: @test12( -; CHECK-NEXT: [[T:%.*]] = fneg double undef -; CHECK-NEXT: ret double [[T]] +; CHECK-NEXT: ret double undef ; %t = fneg double undef ret double %t diff --git a/llvm/test/Transforms/SCCP/widening.ll b/llvm/test/Transforms/SCCP/widening.ll --- a/llvm/test/Transforms/SCCP/widening.ll +++ b/llvm/test/Transforms/SCCP/widening.ll @@ -435,75 +435,15 @@ define void @foo(ptr %arg) { ; SCCP-LABEL: @foo( ; SCCP-NEXT: bb: -; SCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32 ; SCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8 -; SCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [ -; SCCP-NEXT: i32 1, label [[BB3:%.*]] -; SCCP-NEXT: i32 2, label [[BB4:%.*]] -; SCCP-NEXT: i32 4, label [[BB19:%.*]] -; SCCP-NEXT: ] -; SCCP: bb3: -; SCCP-NEXT: unreachable -; SCCP: bb4: -; SCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3 -; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3 -; SCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]] -; SCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1 -; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32 -; SCCP-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 -; SCCP-NEXT: br label [[BB11:%.*]] -; SCCP: bb11: -; SCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ] -; SCCP-NEXT: br label [[BB13:%.*]] -; SCCP: bb13: -; SCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6 -; SCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]] -; SCCP: bb15: -; SCCP-NEXT: unreachable -; SCCP: bb16: -; SCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2 -; SCCP-NEXT: br label [[BB18]] -; SCCP: bb18: -; SCCP-NEXT: br label [[BB11]] -; SCCP: bb19: -; SCCP-NEXT: unreachable +; SCCP-NEXT: br label [[BB20:%.*]] ; SCCP: bb20: ; SCCP-NEXT: ret void ; ; IPSCCP-LABEL: @foo( ; IPSCCP-NEXT: bb: -; IPSCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32 ; IPSCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8 -; IPSCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [ -; IPSCCP-NEXT: i32 1, label [[BB3:%.*]] -; IPSCCP-NEXT: i32 2, label [[BB4:%.*]] -; IPSCCP-NEXT: i32 4, label [[BB19:%.*]] -; IPSCCP-NEXT: ] -; IPSCCP: bb3: -; IPSCCP-NEXT: unreachable -; IPSCCP: bb4: -; IPSCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3 -; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3 -; IPSCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]] -; IPSCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1 -; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32 -; IPSCCP-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 -; IPSCCP-NEXT: br label [[BB11:%.*]] -; IPSCCP: bb11: -; IPSCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ] -; IPSCCP-NEXT: br label [[BB13:%.*]] -; IPSCCP: bb13: -; IPSCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6 -; IPSCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]] -; IPSCCP: bb15: -; IPSCCP-NEXT: unreachable -; IPSCCP: bb16: -; IPSCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2 -; IPSCCP-NEXT: br label [[BB18]] -; IPSCCP: bb18: -; IPSCCP-NEXT: br label [[BB11]] -; IPSCCP: bb19: -; IPSCCP-NEXT: unreachable +; IPSCCP-NEXT: br label [[BB20:%.*]] ; IPSCCP: bb20: ; IPSCCP-NEXT: ret void ;