diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index e0c7bb8868a..2d83fa38b80 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -1501,6 +1501,13 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { if (TrackedRetVals.count(F)) continue; + if (isa(I)) { + // A load here means one of two things: a load of undef from a global, + // a load from an unknown pointer. Either way, having it return undef + // is okay. + continue; + } + markOverdefined(&I); return true; } diff --git a/test/Transforms/IPConstantProp/PR26044.ll b/test/Transforms/IPConstantProp/PR26044.ll index 8b4f2590b9f..efd229e1dac 100644 --- a/test/Transforms/IPConstantProp/PR26044.ll +++ b/test/Transforms/IPConstantProp/PR26044.ll @@ -11,8 +11,7 @@ define void @fn2(i32* %P) { ; CHECK: for.cond1: ; CHECK-NEXT: br i1 false, label [[IF_END]], label [[IF_END]] ; CHECK: if.end: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 undef) ; CHECK-NEXT: store i32 [[CALL]], i32* [[P]] ; CHECK-NEXT: br label [[FOR_COND1:%.*]] ; @@ -34,8 +33,8 @@ define internal i32 @fn1(i32 %p1) { ; CHECK-LABEL: define {{[^@]+}}@fn1 ; CHECK-SAME: (i32 [[P1:%.*]]) ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0 -; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 undef, 0 +; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 undef, i32 undef ; CHECK-NEXT: ret i32 [[COND]] ; entry: diff --git a/test/Transforms/SCCP/apint-bigint2.ll b/test/Transforms/SCCP/apint-bigint2.ll index 7d75240a0d8..8effa2181a4 100644 --- a/test/Transforms/SCCP/apint-bigint2.ll +++ b/test/Transforms/SCCP/apint-bigint2.ll @@ -18,8 +18,7 @@ define i101 @array() { } ; CHECK-LABEL: @large_aggregate -; CHECK-NEXT: %B = load i101, i101* undef -; CHECK-NEXT: %D = and i101 %B, 1 +; CHECK-NEXT: %D = and i101 undef, 1 ; CHECK-NEXT: %DD = or i101 %D, 1 ; CHECK-NEXT: %G = getelementptr i101, i101* getelementptr inbounds ([6 x i101], [6 x i101]* @Y, i32 0, i32 5), i101 %DD ; CHECK-NEXT: %L3 = load i101, i101* %G diff --git a/test/Transforms/SCCP/loadtest.ll b/test/Transforms/SCCP/loadtest.ll index baaad94b0cc..6c43cd26731 100644 --- a/test/Transforms/SCCP/loadtest.ll +++ b/test/Transforms/SCCP/loadtest.ll @@ -2,6 +2,7 @@ ; RUN: opt < %s -data-layout="e-p:32:32" -debugify -sccp -S | FileCheck %s ; RUN: opt < %s -data-layout="E-p:32:32" -debugify -sccp -S | FileCheck %s +; RUN: opt < %s -data-layout="E-p:32:32" -debugify -ipsccp -S | FileCheck %s @X = constant i32 42 ; [#uses=1] @Y = constant [2 x { i32, float }] [ { i32, float } { i32 12, float 1.000000e+00 }, { i32, float } { i32 37, float 0x3FF3B2FEC0000000 } ] ; <[2 x { i32, float }]*> [#uses=2] @@ -43,4 +44,3 @@ define i8 @test4() { %B = load i8, i8* %A ret i8 %B } - diff --git a/test/Transforms/SCCP/loadtest2.ll b/test/Transforms/SCCP/loadtest2.ll new file mode 100644 index 00000000000..ab7eeac5fbc --- /dev/null +++ b/test/Transforms/SCCP/loadtest2.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -data-layout="E-p:32:32" -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 +; + %l = load i32, i32* @j, align 4 + %add = add nsw i32 %l, %b + ret i32 %add +}