summaryrefslogtreecommitdiffstats
path: root/test/Transforms/SCCP
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/SCCP')
-rw-r--r--test/Transforms/SCCP/2002-05-02-EdgeFailure.ll26
-rw-r--r--test/Transforms/SCCP/2002-05-02-MissSecondInst.ll8
-rw-r--r--test/Transforms/SCCP/2002-05-20-MissedIncomingValue.ll19
-rw-r--r--test/Transforms/SCCP/2002-05-21-InvalidSimplify.ll33
-rw-r--r--test/Transforms/SCCP/2002-08-30-GetElementPtrTest.ll9
-rw-r--r--test/Transforms/SCCP/2003-06-24-OverdefinedPHIValue.ll30
-rw-r--r--test/Transforms/SCCP/2003-08-26-InvokeHandling.ll18
-rw-r--r--test/Transforms/SCCP/2004-11-16-DeadInvoke.ll13
-rw-r--r--test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll12
-rw-r--r--test/Transforms/SCCP/2006-10-23-IPSCCP-Crash.ll103
-rw-r--r--test/Transforms/SCCP/2006-12-04-PackedType.ll140
-rw-r--r--test/Transforms/SCCP/2006-12-19-UndefBug.ll8
-rw-r--r--test/Transforms/SCCP/2007-05-16-InvokeCrash.ll41
-rw-r--r--test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll36
-rw-r--r--test/Transforms/SCCP/2008-04-22-multiple-ret-sccp.ll11
-rw-r--r--test/Transforms/SCCP/2008-05-23-UndefCallFold.ll14
-rw-r--r--test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll28
-rw-r--r--test/Transforms/SCCP/2009-05-27-VectorOperandZero.ll10
-rw-r--r--test/Transforms/SCCP/apint-array.ll23
-rw-r--r--test/Transforms/SCCP/apint-basictest.ll16
-rw-r--r--test/Transforms/SCCP/apint-basictest2.ll17
-rw-r--r--test/Transforms/SCCP/apint-basictest3.ll23
-rw-r--r--test/Transforms/SCCP/apint-basictest4.ll25
-rw-r--r--test/Transforms/SCCP/apint-bigarray.ll23
-rw-r--r--test/Transforms/SCCP/apint-bigint.ll9
-rw-r--r--test/Transforms/SCCP/apint-bigint2.ll18
-rw-r--r--test/Transforms/SCCP/apint-ipsccp1.ll24
-rw-r--r--test/Transforms/SCCP/apint-ipsccp2.ll19
-rw-r--r--test/Transforms/SCCP/apint-ipsccp3.ll23
-rw-r--r--test/Transforms/SCCP/apint-ipsccp4.ll49
-rw-r--r--test/Transforms/SCCP/apint-load.ll36
-rw-r--r--test/Transforms/SCCP/apint-phi.ll19
-rw-r--r--test/Transforms/SCCP/apint-select.ll21
-rw-r--r--test/Transforms/SCCP/calltest.ll21
-rw-r--r--test/Transforms/SCCP/crash.ll29
-rw-r--r--test/Transforms/SCCP/dg.exp3
-rw-r--r--test/Transforms/SCCP/ipsccp-basic.ll206
-rw-r--r--test/Transforms/SCCP/loadtest.ll33
-rw-r--r--test/Transforms/SCCP/logical-nuke.ll9
-rw-r--r--test/Transforms/SCCP/phitest.ll20
-rw-r--r--test/Transforms/SCCP/sccptest.ll58
-rw-r--r--test/Transforms/SCCP/select.ll12
42 files changed, 1295 insertions, 0 deletions
diff --git a/test/Transforms/SCCP/2002-05-02-EdgeFailure.ll b/test/Transforms/SCCP/2002-05-02-EdgeFailure.ll
new file mode 100644
index 0000000..bb0cf04
--- /dev/null
+++ b/test/Transforms/SCCP/2002-05-02-EdgeFailure.ll
@@ -0,0 +1,26 @@
+; edgefailure - This function illustrates how SCCP is not doing it's job. This
+; function should be optimized almost completely away: the loop should be
+; analyzed to detect that the body executes exactly once, and thus the branch
+; can be eliminated and code becomes trivially dead. This is distilled from a
+; real benchmark (mst from Olden benchmark, MakeGraph function). When SCCP is
+; fixed, this should be eliminated by a single SCCP application.
+;
+; RUN: opt < %s -sccp -S | not grep loop
+
+define i32* @test() {
+bb1:
+ %A = malloc i32 ; <i32*> [#uses=2]
+ br label %bb2
+bb2: ; preds = %bb2, %bb1
+ ;; Always 0
+ %i = phi i32 [ %i2, %bb2 ], [ 0, %bb1 ] ; <i32> [#uses=2]
+ ;; Always 1
+ %i2 = add i32 %i, 1 ; <i32> [#uses=2]
+ store i32 %i, i32* %A
+ ;; Always false
+ %loop = icmp sle i32 %i2, 0 ; <i1> [#uses=1]
+ br i1 %loop, label %bb2, label %bb3
+bb3: ; preds = %bb2
+ ret i32* %A
+}
+
diff --git a/test/Transforms/SCCP/2002-05-02-MissSecondInst.ll b/test/Transforms/SCCP/2002-05-02-MissSecondInst.ll
new file mode 100644
index 0000000..bb5b51d
--- /dev/null
+++ b/test/Transforms/SCCP/2002-05-02-MissSecondInst.ll
@@ -0,0 +1,8 @@
+; RUN: opt < %s -sccp -S | not grep sub
+
+define void @test3(i32, i32) {
+ add i32 0, 0 ; <i32>:3 [#uses=0]
+ sub i32 0, 4 ; <i32>:4 [#uses=0]
+ ret void
+}
+
diff --git a/test/Transforms/SCCP/2002-05-20-MissedIncomingValue.ll b/test/Transforms/SCCP/2002-05-20-MissedIncomingValue.ll
new file mode 100644
index 0000000..f619802
--- /dev/null
+++ b/test/Transforms/SCCP/2002-05-20-MissedIncomingValue.ll
@@ -0,0 +1,19 @@
+; This test shows a case where SCCP is incorrectly eliminating the PHI node
+; because it thinks it has a constant 0 value, when it really doesn't.
+
+; RUN: opt < %s -sccp -S | grep phi
+
+define i32 @test(i32 %A, i1 %c) {
+bb1:
+ br label %BB2
+BB2: ; preds = %BB4, %bb1
+ %V = phi i32 [ 0, %bb1 ], [ %A, %BB4 ] ; <i32> [#uses=1]
+ br label %BB3
+BB3: ; preds = %BB2
+ br i1 %c, label %BB4, label %BB5
+BB4: ; preds = %BB3
+ br label %BB2
+BB5: ; preds = %BB3
+ ret i32 %V
+}
+
diff --git a/test/Transforms/SCCP/2002-05-21-InvalidSimplify.ll b/test/Transforms/SCCP/2002-05-21-InvalidSimplify.ll
new file mode 100644
index 0000000..f02a293
--- /dev/null
+++ b/test/Transforms/SCCP/2002-05-21-InvalidSimplify.ll
@@ -0,0 +1,33 @@
+; This test shows SCCP "proving" that the loop (from bb6 to 14) loops infinitely
+; this is in fact NOT the case, so the return should still be alive in the code
+; after sccp and CFG simplification have been performed.
+;
+; RUN: opt < %s -sccp -simplifycfg -S | \
+; RUN: grep ret
+
+define void @old_main() {
+bb3:
+ br label %bb6
+bb6: ; preds = %bb14, %bb3
+ %reg403 = phi i32 [ %reg155, %bb14 ], [ 0, %bb3 ] ; <i32> [#uses=1]
+ %reg155 = add i32 %reg403, 1 ; <i32> [#uses=2]
+ br label %bb11
+bb11: ; preds = %bb11, %bb6
+ %reg407 = phi i32 [ %reg408, %bb11 ], [ 0, %bb6 ] ; <i32> [#uses=2]
+ %reg408 = add i32 %reg407, 1 ; <i32> [#uses=1]
+ %cond550 = icmp sle i32 %reg407, 1 ; <i1> [#uses=1]
+ br i1 %cond550, label %bb11, label %bb12
+bb12: ; preds = %bb11
+ br label %bb13
+bb13: ; preds = %bb13, %bb12
+ %reg409 = phi i32 [ %reg410, %bb13 ], [ 0, %bb12 ] ; <i32> [#uses=1]
+ %reg410 = add i32 %reg409, 1 ; <i32> [#uses=2]
+ %cond552 = icmp sle i32 %reg410, 2 ; <i1> [#uses=1]
+ br i1 %cond552, label %bb13, label %bb14
+bb14: ; preds = %bb13
+ %cond553 = icmp sle i32 %reg155, 31 ; <i1> [#uses=1]
+ br i1 %cond553, label %bb6, label %bb15
+bb15: ; preds = %bb14
+ ret void
+}
+
diff --git a/test/Transforms/SCCP/2002-08-30-GetElementPtrTest.ll b/test/Transforms/SCCP/2002-08-30-GetElementPtrTest.ll
new file mode 100644
index 0000000..6aaf33e
--- /dev/null
+++ b/test/Transforms/SCCP/2002-08-30-GetElementPtrTest.ll
@@ -0,0 +1,9 @@
+; RUN: opt < %s -sccp -S | not grep %X
+
+@G = external global [40 x i32] ; <[40 x i32]*> [#uses=1]
+
+define i32* @test() {
+ %X = getelementptr [40 x i32]* @G, i64 0, i64 0 ; <i32*> [#uses=1]
+ ret i32* %X
+}
+
diff --git a/test/Transforms/SCCP/2003-06-24-OverdefinedPHIValue.ll b/test/Transforms/SCCP/2003-06-24-OverdefinedPHIValue.ll
new file mode 100644
index 0000000..576f5d6
--- /dev/null
+++ b/test/Transforms/SCCP/2003-06-24-OverdefinedPHIValue.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -sccp -simplifycfg -S | \
+; RUN: not grep then:
+
+define void @cprop_test11(i32* %data.1) {
+entry:
+ %tmp.1 = load i32* %data.1 ; <i32> [#uses=3]
+ %tmp.41 = icmp sgt i32 %tmp.1, 1 ; <i1> [#uses=1]
+ br i1 %tmp.41, label %no_exit, label %loopexit
+no_exit: ; preds = %endif, %then, %entry
+ %j.0 = phi i32 [ %j.0, %endif ], [ %i.0, %then ], [ 1, %entry ] ; <i32> [#uses=3]
+ %i.0 = phi i32 [ %inc, %endif ], [ %inc1, %then ], [ 1, %entry ] ; <i32> [#uses=4]
+ %tmp.8.not = icmp ne i32 %j.0, 0 ; <i1> [#uses=1]
+ br i1 %tmp.8.not, label %endif, label %then
+then: ; preds = %no_exit
+ %inc1 = add i32 %i.0, 1 ; <i32> [#uses=3]
+ %tmp.42 = icmp slt i32 %inc1, %tmp.1 ; <i1> [#uses=1]
+ br i1 %tmp.42, label %no_exit, label %loopexit
+endif: ; preds = %no_exit
+ %inc = add i32 %i.0, 1 ; <i32> [#uses=3]
+ %tmp.4 = icmp slt i32 %inc, %tmp.1 ; <i1> [#uses=1]
+ br i1 %tmp.4, label %no_exit, label %loopexit
+loopexit: ; preds = %endif, %then, %entry
+ %j.1 = phi i32 [ 1, %entry ], [ %j.0, %endif ], [ %i.0, %then ] ; <i32> [#uses=1]
+ %i.1 = phi i32 [ 1, %entry ], [ %inc, %endif ], [ %inc1, %then ] ; <i32> [#uses=1]
+ %tmp.17 = getelementptr i32* %data.1, i64 1 ; <i32*> [#uses=1]
+ store i32 %j.1, i32* %tmp.17
+ %tmp.23 = getelementptr i32* %data.1, i64 2 ; <i32*> [#uses=1]
+ store i32 %i.1, i32* %tmp.23
+ ret void
+}
diff --git a/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll b/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll
new file mode 100644
index 0000000..9876375
--- /dev/null
+++ b/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll
@@ -0,0 +1,18 @@
+; The PHI cannot be eliminated from this testcase, SCCP is mishandling invoke's!
+; RUN: opt < %s -sccp -S | grep phi
+
+declare void @foo()
+
+define i32 @test(i1 %cond) {
+Entry:
+ br i1 %cond, label %Inv, label %Cont
+Inv: ; preds = %Entry
+ invoke void @foo( )
+ to label %Ok unwind label %Cont
+Ok: ; preds = %Inv
+ br label %Cont
+Cont: ; preds = %Ok, %Inv, %Entry
+ %X = phi i32 [ 0, %Entry ], [ 1, %Ok ], [ 0, %Inv ] ; <i32> [#uses=1]
+ ret i32 %X
+}
+
diff --git a/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll b/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll
new file mode 100644
index 0000000..5d2c78e
--- /dev/null
+++ b/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -sccp -disable-output
+
+declare i32 @foo()
+
+define void @caller() {
+ br i1 true, label %T, label %F
+F: ; preds = %0
+ %X = invoke i32 @foo( )
+ to label %T unwind label %T ; <i32> [#uses=0]
+T: ; preds = %F, %F, %0
+ ret void
+}
+
diff --git a/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll b/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll
new file mode 100644
index 0000000..4adfde3
--- /dev/null
+++ b/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -sccp -S | grep {ret i32 1}
+
+; This function definitely returns 1, even if we don't know the direction
+; of the branch.
+
+define i32 @foo() {
+ br i1 undef, label %T, label %T
+T: ; preds = %0, %0
+ %X = add i32 0, 1 ; <i32> [#uses=1]
+ ret i32 %X
+}
+
diff --git a/test/Transforms/SCCP/2006-10-23-IPSCCP-Crash.ll b/test/Transforms/SCCP/2006-10-23-IPSCCP-Crash.ll
new file mode 100644
index 0000000..47f9cb4
--- /dev/null
+++ b/test/Transforms/SCCP/2006-10-23-IPSCCP-Crash.ll
@@ -0,0 +1,103 @@
+; RUN: opt < %s -sccp -disable-output
+; END.
+target datalayout = "E-p:32:32"
+target triple = "powerpc-apple-darwin8.7.0"
+ %struct.pat_list = type { i32, %struct.pat_list* }
+@JUMP = external global i32 ; <i32*> [#uses=1]
+@old_D_pat = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
+
+define void @asearch1(i32 %D) {
+entry:
+ %tmp80 = icmp ult i32 0, %D ; <i1> [#uses=1]
+ br i1 %tmp80, label %bb647.preheader, label %cond_true81.preheader
+cond_true81.preheader: ; preds = %entry
+ ret void
+bb647.preheader: ; preds = %entry
+ %tmp3.i = call i32 @read( ) ; <i32> [#uses=1]
+ %tmp6.i = add i32 %tmp3.i, 0 ; <i32> [#uses=1]
+ %tmp653 = icmp sgt i32 %tmp6.i, 0 ; <i1> [#uses=1]
+ br i1 %tmp653, label %cond_true654, label %UnifiedReturnBlock
+cond_true612: ; preds = %cond_true654
+ ret void
+cond_next624: ; preds = %cond_true654
+ ret void
+cond_true654: ; preds = %bb647.preheader
+ br i1 undef, label %cond_true612, label %cond_next624
+UnifiedReturnBlock: ; preds = %bb647.preheader
+ ret void
+}
+
+define void @bitap(i32 %D) {
+entry:
+ %tmp29 = icmp eq i32 0, 0 ; <i1> [#uses=1]
+ br i1 %tmp29, label %cond_next50, label %cond_next37
+cond_next37: ; preds = %entry
+ ret void
+cond_next50: ; preds = %entry
+ %tmp52 = icmp sgt i32 %D, 0 ; <i1> [#uses=1]
+ br i1 %tmp52, label %cond_true53, label %cond_next71
+cond_true53: ; preds = %cond_next50
+ %tmp54 = load i32* @JUMP ; <i32> [#uses=1]
+ %tmp55 = icmp eq i32 %tmp54, 1 ; <i1> [#uses=1]
+ br i1 %tmp55, label %cond_true56, label %cond_next63
+cond_true56: ; preds = %cond_true53
+ %tmp57 = bitcast i32 %D to i32 ; <i32> [#uses=1]
+ call void @asearch1( i32 %tmp57 )
+ ret void
+cond_next63: ; preds = %cond_true53
+ ret void
+cond_next71: ; preds = %cond_next50
+ ret void
+}
+
+declare i32 @read()
+
+define void @initial_value() {
+entry:
+ ret void
+}
+
+define void @main() {
+entry:
+ br label %cond_next252
+cond_next208: ; preds = %cond_true260
+ %tmp229 = call i32 @atoi( ) ; <i32> [#uses=1]
+ br label %cond_next252
+bb217: ; preds = %cond_true260
+ ret void
+cond_next252: ; preds = %cond_next208, %entry
+ %D.0.0 = phi i32 [ 0, %entry ], [ %tmp229, %cond_next208 ] ; <i32> [#uses=1]
+ %tmp254 = getelementptr i8** null, i32 1 ; <i8**> [#uses=1]
+ %tmp256 = load i8** %tmp254 ; <i8*> [#uses=1]
+ %tmp258 = load i8* %tmp256 ; <i8> [#uses=1]
+ %tmp259 = icmp eq i8 %tmp258, 45 ; <i1> [#uses=1]
+ br i1 %tmp259, label %cond_true260, label %bb263
+cond_true260: ; preds = %cond_next252
+ %tmp205818 = icmp sgt i8 0, -1 ; <i1> [#uses=1]
+ br i1 %tmp205818, label %cond_next208, label %bb217
+bb263: ; preds = %cond_next252
+ %tmp265 = icmp eq i32 0, 0 ; <i1> [#uses=1]
+ br i1 %tmp265, label %cond_next276, label %cond_true266
+cond_true266: ; preds = %bb263
+ ret void
+cond_next276: ; preds = %bb263
+ %tmp278 = icmp eq i32 0, 0 ; <i1> [#uses=1]
+ br i1 %tmp278, label %cond_next298, label %cond_true279
+cond_true279: ; preds = %cond_next276
+ ret void
+cond_next298: ; preds = %cond_next276
+ call void @bitap( i32 %D.0.0 )
+ ret void
+}
+
+declare i32 @atoi()
+
+define void @subset_pset() {
+entry:
+ ret void
+}
+
+define void @strcmp() {
+entry:
+ ret void
+}
diff --git a/test/Transforms/SCCP/2006-12-04-PackedType.ll b/test/Transforms/SCCP/2006-12-04-PackedType.ll
new file mode 100644
index 0000000..cee3349
--- /dev/null
+++ b/test/Transforms/SCCP/2006-12-04-PackedType.ll
@@ -0,0 +1,140 @@
+; Test VectorType handling by SCCP.
+; SCCP ignores VectorTypes until PR 1034 is fixed
+;
+; RUN: opt < %s -sccp
+; END.
+
+target datalayout = "E-p:32:32"
+target triple = "powerpc-apple-darwin8"
+ %struct.GLDAlphaTest = type { float, i16, i8, i8 }
+ %struct.GLDArrayRange = type { i8, i8, i8, i8 }
+ %struct.GLDBlendMode = type { i16, i16, i16, i16, %struct.GLTColor4, i16, i16, i8, i8, i8, i8 }
+ %struct.GLDBufferRec = type opaque
+ %struct.GLDBufferstate = type { %struct.GLTDimensions, %struct.GLTDimensions, %struct.GLTFixedColor4, %struct.GLTFixedColor4, i8, i8, i8, i8, [2 x %struct.GLSBuffer], [4 x %struct.GLSBuffer], %struct.GLSBuffer, %struct.GLSBuffer, %struct.GLSBuffer, [4 x %struct.GLSBuffer*], %struct.GLSBuffer*, %struct.GLSBuffer*, %struct.GLSBuffer*, i8, i8 }
+ %struct.GLDClearColor = type { double, %struct.GLTColor4, %struct.GLTColor4, float, i32 }
+ %struct.GLDClipPlane = type { i32, [6 x %struct.GLTColor4] }
+ %struct.GLDColorBuffer = type { i16, i16, [4 x i16] }
+ %struct.GLDColorMatrix = type { [16 x float]*, %struct.GLDImagingColorScale }
+ %struct.GLDContextRec = type { float, float, float, float, float, float, float, float, %struct.GLTColor4, %struct.GLTColor4, %struct.GLVMFPContext, %struct.GLDTextureMachine, %struct.GLGProcessor, %struct._GLVMConstants*, void (%struct.GLDContextRec*, i32, i32, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, i32)*, %struct._GLVMFunction*, void (%struct.GLDContextRec*, %struct.GLDVertex*)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*, %struct.GLDVertex*)*, %struct._GLVMFunction*, %struct._GLVMFunction*, %struct._GLVMFunction*, i32, i32, i32, float, float, float, i32, %struct.GLSDrawable, %struct.GLDFramebufferAttachment, %struct.GLDFormat, %struct.GLDBufferstate, %struct.GLDSharedRec*, %struct.GLDState*, %struct.GLDPluginState*, %struct.GLTDimensions, %struct.GLTColor4*, %struct.GLTColor4*, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, %struct.GLDPipelineProgramRec*, %struct.GLDStateProgramRec, %struct.GLVMTextures, { [4 x i8*], i8*, i8* }, [64 x float], %struct.GLDStippleData, i16, i8, i8, i32, %struct.GLDFramebufferRec*, i8, %struct.GLDQueryRec*, %struct.GLDQueryRec* }
+ %struct.GLDConvolution = type { %struct.GLTColor4, %struct.GLDImagingColorScale, i16, i16, float*, i32, i32 }
+ %struct.GLDDepthTest = type { i16, i16, i8, i8, i8, i8, double, double }
+ %struct.GLDFogMode = type { %struct.GLTColor4, float, float, float, float, float, i16, i16, i16, i8, i8 }
+ %struct.GLDFormat = type { i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8, i32, i32, i32 }
+ %struct.GLDFramebufferAttachment = type { i32, i32, i32, i32, i32, i32 }
+ %struct.GLDFramebufferData = type { [6 x %struct.GLDFramebufferAttachment], [4 x i16], i16, i16, i16, i16, i32 }
+ %struct.GLDFramebufferRec = type { %struct.GLDFramebufferData*, %struct.GLDPluginFramebufferData*, %struct.GLDPixelFormat }
+ %struct.GLDHintMode = type { i16, i16, i16, i16, i16, i16, i16, i16, i16, i16 }
+ %struct.GLDHistogram = type { %struct.GLTFixedColor4*, i32, i16, i8, i8 }
+ %struct.GLDImagingColorScale = type { { float, float }, { float, float }, { float, float }, { float, float } }
+ %struct.GLDImagingSubset = type { %struct.GLDConvolution, %struct.GLDConvolution, %struct.GLDConvolution, %struct.GLDColorMatrix, %struct.GLDMinmax, %struct.GLDHistogram, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, i32 }
+ %struct.GLDLight = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTCoord3, float, float, float, float, float, %struct.GLTCoord3, float, float, float, float, float }
+ %struct.GLDLightModel = type { %struct.GLTColor4, [8 x %struct.GLDLight], [2 x %struct.GLDMaterial], i32, i16, i16, i16, i8, i8, i8, i8, i8, i8 }
+ %struct.GLDLightProduct = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4 }
+ %struct.GLDLineMode = type { float, i32, i16, i16, i8, i8, i8, i8 }
+ %struct.GLDLogicOp = type { i16, i8, i8 }
+ %struct.GLDMaskMode = type { i32, [3 x i32], i8, i8, i8, i8, i8, i8, i8, i8 }
+ %struct.GLDMaterial = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, float, float, float, float, [8 x %struct.GLDLightProduct], %struct.GLTColor4, [6 x i32], [2 x i32] }
+ %struct.GLDMinmax = type { %struct.GLDMinmaxTable*, i16, i8, i8 }
+ %struct.GLDMinmaxTable = type { %struct.GLTColor4, %struct.GLTColor4 }
+ %struct.GLDMipmaplevel = type { [4 x i32], [4 x float], [4 x i32], [4 x i32], [4 x float], [4 x i32], [3 x i32], i32, float*, float*, float*, i32, i32, i8*, i16, i16, i16, i16 }
+ %struct.GLDMultisample = type { float, i8, i8, i8, i8, i8, i8, i8, i8 }
+ %struct.GLDPipelineProgramData = type { i16, i16, i32, %struct._PPStreamToken*, i64, %struct.GLDShaderSourceData*, %struct.GLTColor4*, i32 }
+ %struct.GLDPipelineProgramRec = type { %struct.GLDPipelineProgramData*, %struct._PPStreamToken*, %struct._PPStreamToken*, %struct._GLVMFunction*, i32, i32, i32 }
+ %struct.GLDPipelineProgramState = type { i8, i8, i8, i8, %struct.GLTColor4* }
+ %struct.GLDPixelFormat = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 }
+ %struct.GLDPixelMap = type { i32*, float*, float*, float*, float*, float*, float*, float*, float*, i32*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
+ %struct.GLDPixelMode = type { float, float, %struct.GLDPixelStore, %struct.GLDPixelTransfer, %struct.GLDPixelMap, %struct.GLDImagingSubset, i32, i32 }
+ %struct.GLDPixelPack = type { i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8 }
+ %struct.GLDPixelStore = type { %struct.GLDPixelPack, %struct.GLDPixelPack }
+ %struct.GLDPixelTransfer = type { float, float, float, float, float, float, float, float, float, float, i32, i32, float, float, float, float, float, float, float, float, float, float, float, float }
+ %struct.GLDPluginFramebufferData = type { [6 x %struct.GLDTextureRec*], i32, i32 }
+ %struct.GLDPluginProgramData = type { [3 x %struct.GLDPipelineProgramRec*], %struct.GLDBufferRec**, i32 }
+ %struct.GLDPluginState = type { [16 x [5 x %struct.GLDTextureRec*]], [3 x %struct.GLDTextureRec*], [16 x %struct.GLDTextureRec*], [3 x %struct.GLDPipelineProgramRec*], %struct.GLDProgramRec*, %struct.GLDVertexArrayRec*, [16 x %struct.GLDBufferRec*], %struct.GLDFramebufferRec*, %struct.GLDFramebufferRec* }
+ %struct.GLDPointMode = type { float, float, float, float, %struct.GLTCoord3, float, i8, i8, i8, i8, i16, i16, i32, i16, i16 }
+ %struct.GLDPolygonMode = type { [128 x i8], float, float, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 }
+ %struct.GLDProgramData = type { i32, [16 x i32], i32, i32, i32, i32 }
+ %struct.GLDProgramRec = type { %struct.GLDProgramData*, %struct.GLDPluginProgramData*, i32 }
+ %struct.GLDQueryRec = type { i32, i32, %struct.GLDQueryRec* }
+ %struct.GLDRect = type { i32, i32, i32, i32, i32, i32 }
+ %struct.GLDRegisterCombiners = type { i8, i8, i8, i8, i32, [2 x %struct.GLTColor4], [8 x %struct.GLDRegisterCombinersPerStageState], %struct.GLDRegisterCombinersFinalStageState }
+ %struct.GLDRegisterCombinersFinalStageState = type { i8, i8, i8, i8, [7 x %struct.GLDRegisterCombinersPerVariableState] }
+ %struct.GLDRegisterCombinersPerPortionState = type { [4 x %struct.GLDRegisterCombinersPerVariableState], i8, i8, i8, i8, i16, i16, i16, i16, i16, i16 }
+ %struct.GLDRegisterCombinersPerStageState = type { [2 x %struct.GLDRegisterCombinersPerPortionState], [2 x %struct.GLTColor4] }
+ %struct.GLDRegisterCombinersPerVariableState = type { i16, i16, i16, i16 }
+ %struct.GLDScissorTest = type { %struct.GLTFixedColor4, i8, i8, i8, i8 }
+ %struct.GLDShaderSourceData = type { i32, i32, i8*, i32*, i32, i32, i8*, i32*, i8* }
+ %struct.GLDSharedRec = type opaque
+ %struct.GLDState = type { i16, i16, i32, i32, i32, [256 x %struct.GLTColor4], [128 x %struct.GLTColor4], %struct.GLDViewport, %struct.GLDTransform, %struct.GLDLightModel, i32*, i32, i32, i32, %struct.GLDAlphaTest, %struct.GLDBlendMode, %struct.GLDClearColor, %struct.GLDColorBuffer, %struct.GLDDepthTest, %struct.GLDArrayRange, %struct.GLDFogMode, %struct.GLDHintMode, %struct.GLDLineMode, %struct.GLDLogicOp, %struct.GLDMaskMode, %struct.GLDPixelMode, %struct.GLDPointMode, %struct.GLDPolygonMode, %struct.GLDScissorTest, i32, %struct.GLDStencilTest, [16 x %struct.GLDTextureMode], %struct.GLDArrayRange, [8 x %struct.GLDTextureCoordGen], %struct.GLDClipPlane, %struct.GLDMultisample, %struct.GLDRegisterCombiners, %struct.GLDArrayRange, %struct.GLDArrayRange, [3 x %struct.GLDPipelineProgramState], %struct.GLDTransformFeedback }
+ %struct.GLDStateProgramRec = type { %struct.GLDPipelineProgramData*, %struct.GLDPipelineProgramRec* }
+ %struct.GLDStencilTest = type { [3 x { i32, i32, i16, i16, i16, i16 }], i32, [4 x i8] }
+ %struct.GLDStippleData = type { i32, i16, i16, [32 x [32 x i8]] }
+ %struct.GLDTextureCoordGen = type { { i16, i16, %struct.GLTColor4, %struct.GLTColor4 }, { i16, i16, %struct.GLTColor4, %struct.GLTColor4 }, { i16, i16, %struct.GLTColor4, %struct.GLTColor4 }, { i16, i16, %struct.GLTColor4, %struct.GLTColor4 }, i8, i8, i8, i8 }
+ %struct.GLDTextureGeomState = type { i16, i16, i16, i16, i16, i8, i8, i16, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, [6 x i16], [6 x i16] }
+ %struct.GLDTextureLevel = type { i32, i32, i16, i16, i16, i8, i8, i16, i16, i16, i16, i8* }
+ %struct.GLDTextureMachine = type { [8 x %struct.GLDTextureRec*], %struct.GLDTextureRec*, i8, i8, i8, i8 }
+ %struct.GLDTextureMode = type { %struct.GLTColor4, i32, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, float, float, float, i16, i16, i16, i16, i16, i16, [4 x i16], i8, i8, i8, i8, [3 x float], [4 x float], float, float }
+ %struct.GLDTextureParamState = type { i16, i16, i16, i16, i16, i16, %struct.GLTColor4, float, float, float, float, i16, i16, i16, i16, float, i16, i8, i8, i32, i8* }
+ %struct.GLDTextureRec = type { %struct.GLDTextureState*, i32, [2 x float], float, i32, float, float, float, float, float, float, %struct.GLDMipmaplevel*, %struct.GLDMipmaplevel*, i32, i32, i32, i32, i32, i32, %struct.GLDTextureParamState, i32, [2 x %struct._PPStreamToken] }
+ %struct.GLDTextureState = type { i16, i16, i16, float, i32, i16, %struct.GLISWRSurface*, i8, i8, i8, i8, %struct.GLDTextureParamState, %struct.GLDTextureGeomState, %struct.GLDTextureLevel, [6 x [15 x %struct.GLDTextureLevel]] }
+ %struct.GLDTransform = type { [24 x [16 x float]], [24 x [16 x float]], [16 x float], float, float, float, float, i32, float, i16, i16, i8, i8, i8, i8 }
+ %struct.GLDTransformFeedback = type { i8, i8, i8, [16 x i32], [16 x i32] }
+ %struct.GLDVertex = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTCoord3, float, %struct.GLTColor4, float, float, float, i8, i8, i8, i8, [4 x float], [2 x %struct.GLDMaterial*], i32, i32, [8 x %struct.GLTColor4] }
+ %struct.GLDVertexArrayRec = type opaque
+ %struct.GLDViewport = type { float, float, float, float, float, float, float, float, double, double, i32, i32, i32, i32, float, float, float, float }
+ %struct.GLGColorTable = type { i32, i32, i32, i8* }
+ %struct.GLGOperation = type { i8*, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, float, %struct.GLGColorTable, %struct.GLGColorTable, %struct.GLGColorTable }
+ %struct.GLGProcessor = type { void (%struct.GLDPixelMode*, %struct.GLGOperation*, %struct._GLGFunctionKey*)*, %struct._GLVMFunction*, %struct._GLGFunctionKey* }
+ %struct.GLISWRSurface = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i8*, i8*, [4 x i8*], i32 }
+ %struct.GLIWindow = type { i32, i32, i32 }
+ %struct.GLSBuffer = type { i8* }
+ %struct.GLSDrawable = type { %struct.GLSWindowRec* }
+ %struct.GLSWindowRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %struct.GLSDrawable, [2 x i8*], i8*, i8*, i8*, [4 x i8*], i32, i32, i32, i32, [4 x i32], i16, i16, i16, %struct.GLIWindow, i32, i32, i8*, i8* }
+ %struct.GLTColor4 = type { float, float, float, float }
+ %struct.GLTCoord3 = type { float, float, float }
+ %struct.GLTDimensions = type { i32, i32 }
+ %struct.GLTFixedColor4 = type { i32, i32, i32, i32 }
+ %struct.GLVMFPContext = type { float, i32, i32, i32 }
+ %struct.GLVMFragmentAttribRec = type { <4 x float>, <4 x float>, <4 x float>, <4 x float>, [8 x <4 x float>] }
+ %struct.GLVMTextures = type { [8 x %struct.GLDTextureRec*] }
+ %struct._GLGFunctionKey = type opaque
+ %struct._GLVMConstants = type opaque
+ %struct._GLVMFunction = type opaque
+ %struct._PPStreamToken = type { { i16, i8, i8, i32 } }
+
+define void @gldLLVMVecPointRender(%struct.GLDContextRec* %ctx) {
+entry:
+ %tmp.uip = getelementptr %struct.GLDContextRec* %ctx, i32 0, i32 22 ; <i32*> [#uses=1]
+ %tmp = load i32* %tmp.uip ; <i32> [#uses=3]
+ %tmp91 = lshr i32 %tmp, 5 ; <i32> [#uses=1]
+ %tmp92 = trunc i32 %tmp91 to i1 ; <i1> [#uses=1]
+ br i1 %tmp92, label %cond_true93, label %cond_next116
+cond_true93: ; preds = %entry
+ %tmp.upgrd.1 = getelementptr %struct.GLDContextRec* %ctx, i32 0, i32 31, i32 14 ; <i32*> [#uses=1]
+ %tmp95 = load i32* %tmp.upgrd.1 ; <i32> [#uses=1]
+ %tmp95.upgrd.2 = sitofp i32 %tmp95 to float ; <float> [#uses=1]
+ %tmp108 = fmul float undef, %tmp95.upgrd.2 ; <float> [#uses=1]
+ br label %cond_next116
+cond_next116: ; preds = %cond_true93, %entry
+ %point_size.2 = phi float [ %tmp108, %cond_true93 ], [ undef, %entry ] ; <float> [#uses=2]
+ %tmp457 = fcmp olt float %point_size.2, 1.000000e+00 ; <i1> [#uses=1]
+ %tmp460 = lshr i32 %tmp, 6 ; <i32> [#uses=1]
+ %tmp461 = trunc i32 %tmp460 to i1 ; <i1> [#uses=1]
+ br i1 %tmp457, label %cond_true458, label %cond_next484
+cond_true458: ; preds = %cond_next116
+ br i1 %tmp461, label %cond_true462, label %cond_next487
+cond_true462: ; preds = %cond_true458
+ %tmp26 = bitcast i32 %tmp to i32 ; <i32> [#uses=1]
+ %tmp465 = and i32 %tmp26, 128 ; <i32> [#uses=1]
+ %tmp466 = icmp eq i32 %tmp465, 0 ; <i1> [#uses=1]
+ br i1 %tmp466, label %cond_true467, label %cond_next487
+cond_true467: ; preds = %cond_true462
+ ret void
+cond_next484: ; preds = %cond_next116
+ %tmp486 = fmul float %point_size.2, 5.000000e-01 ; <float> [#uses=1]
+ br label %cond_next487
+cond_next487: ; preds = %cond_next484, %cond_true462, %cond_true458
+ %radius.0 = phi float [ %tmp486, %cond_next484 ], [ 5.000000e-01, %cond_true458 ], [ 5.000000e-01, %cond_true462 ] ; <float> [#uses=2]
+ %tmp494 = insertelement <4 x float> zeroinitializer, float %radius.0, i32 2 ; <<4 x float>> [#uses=1]
+ %tmp495 = insertelement <4 x float> %tmp494, float %radius.0, i32 3 ; <<4 x float>> [#uses=0]
+ ret void
+}
diff --git a/test/Transforms/SCCP/2006-12-19-UndefBug.ll b/test/Transforms/SCCP/2006-12-19-UndefBug.ll
new file mode 100644
index 0000000..ec69ce0
--- /dev/null
+++ b/test/Transforms/SCCP/2006-12-19-UndefBug.ll
@@ -0,0 +1,8 @@
+; RUN: opt < %s -sccp -S | \
+; RUN: grep {ret i1 false}
+
+define i1 @foo() {
+ %X = and i1 false, undef ; <i1> [#uses=1]
+ ret i1 %X
+}
+
diff --git a/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll b/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll
new file mode 100644
index 0000000..b84fe6d
--- /dev/null
+++ b/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -sccp -disable-output
+; PR1431
+
+define void @_ada_bench() {
+entry:
+ br label %cond_next
+cond_next: ; preds = %cond_next, %entry
+ %indvar46 = phi i32 [ 0, %entry ], [ %indvar.next47, %cond_next ] ; <i32> [#uses=1]
+ %indvar.next47 = add i32 %indvar46, 1 ; <i32> [#uses=2]
+ %exitcond48 = icmp eq i32 %indvar.next47, 10000 ; <i1> [#uses=1]
+ br i1 %exitcond48, label %cond_next40, label %cond_next
+cond_next40: ; preds = %cond_next40, %cond_next
+ %indvar43 = phi i32 [ %indvar.next44, %cond_next40 ], [ 0, %cond_next ] ; <i32> [#uses=1]
+ %indvar.next44 = add i32 %indvar43, 1 ; <i32> [#uses=2]
+ %exitcond45 = icmp eq i32 %indvar.next44, 10000 ; <i1> [#uses=1]
+ br i1 %exitcond45, label %cond_next53, label %cond_next40
+cond_next53: ; preds = %cond_next53, %cond_next40
+ %indvar41 = phi i32 [ %indvar.next42, %cond_next53 ], [ 0, %cond_next40 ] ; <i32> [#uses=1]
+ %indvar.next42 = add i32 %indvar41, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next42, 10000 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb67, label %cond_next53
+bb67: ; preds = %cond_next53
+ %tmp112 = invoke double @sin( double 5.000000e-01 )
+ to label %bb114 unwind label %cleanup ; <double> [#uses=0]
+bb114: ; preds = %bb67
+ %tmp147 = invoke double @log( double 5.000000e-01 )
+ to label %bb149 unwind label %cleanup ; <double> [#uses=0]
+bb149: ; preds = %bb114
+ %tmp175 = invoke double @sqrt( double 5.000000e-01 )
+ to label %bb177 unwind label %cleanup ; <double> [#uses=0]
+bb177: ; preds = %bb149
+ unreachable
+cleanup: ; preds = %bb149, %bb114, %bb67
+ unwind
+}
+
+declare double @sin(double)
+
+declare double @log(double)
+
+declare double @sqrt(double)
diff --git a/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll b/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll
new file mode 100644
index 0000000..aa613dc
--- /dev/null
+++ b/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -sccp -S | grep undef | count 1
+; PR1938
+
+define i32 @main() {
+entry:
+ br label %bb
+
+bb:
+ %indvar = phi i32 [ 0, %entry ], [ %k, %bb.backedge ]
+ %k = add i32 %indvar, 1
+ br i1 undef, label %cond_true, label %cond_false
+
+cond_true:
+ %tmp97 = icmp slt i32 %k, 10
+ br i1 %tmp97, label %bb.backedge, label %bb12
+
+bb.backedge:
+ br label %bb
+
+cond_false:
+ %tmp9 = icmp slt i32 %k, 10
+ br i1 %tmp9, label %bb.backedge, label %bb12
+
+bb12:
+ %tmp14 = icmp eq i32 %k, 10
+ br i1 %tmp14, label %cond_next18, label %cond_true17
+
+cond_true17:
+ tail call void @abort( )
+ unreachable
+
+cond_next18:
+ ret i32 0
+}
+
+declare void @abort()
diff --git a/test/Transforms/SCCP/2008-04-22-multiple-ret-sccp.ll b/test/Transforms/SCCP/2008-04-22-multiple-ret-sccp.ll
new file mode 100644
index 0000000..1b26ca9
--- /dev/null
+++ b/test/Transforms/SCCP/2008-04-22-multiple-ret-sccp.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -sccp -S | grep {ret i32 %Z}
+; rdar://5778210
+
+declare {i32, i32} @bar(i32 %A)
+
+define i32 @foo() {
+ %X = call {i32, i32} @bar(i32 17)
+ %Y = getresult {i32, i32} %X, 0
+ %Z = add i32 %Y, %Y
+ ret i32 %Z
+}
diff --git a/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll b/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll
new file mode 100644
index 0000000..cd6cf97
--- /dev/null
+++ b/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll
@@ -0,0 +1,14 @@
+; RUN: opt < %s -sccp -S | not grep {ret i32 undef}
+; PR2358
+target datalayout =
+"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-pc-linux-gnu"
+
+define i32 @x(i32 %b) {
+entry:
+ %val = call i32 @llvm.cttz.i32(i32 undef)
+ ret i32 %val
+}
+
+declare i32 @llvm.cttz.i32(i32)
+
diff --git a/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll b/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
new file mode 100644
index 0000000..d23ee2b
--- /dev/null
+++ b/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -ipsccp -S | grep {ret i32 42}
+; RUN: opt < %s -ipsccp -S | grep {ret i32 undef}
+; PR3325
+
+define i32 @main() {
+ %tmp1 = invoke i32 @f()
+ to label %UnifiedReturnBlock unwind label %lpad
+
+lpad:
+ unreachable
+
+UnifiedReturnBlock:
+ ret i32 %tmp1
+}
+
+define internal i32 @f() {
+ ret i32 42
+}
+
+declare i8* @__cxa_begin_catch(i8*) nounwind
+
+declare i8* @llvm.eh.exception() nounwind
+
+declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind
+
+declare void @__cxa_end_catch()
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SCCP/2009-05-27-VectorOperandZero.ll b/test/Transforms/SCCP/2009-05-27-VectorOperandZero.ll
new file mode 100644
index 0000000..7aced66
--- /dev/null
+++ b/test/Transforms/SCCP/2009-05-27-VectorOperandZero.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -sccp -disable-output
+; PR4277
+
+define i32 @main() nounwind {
+entry:
+ %0 = tail call signext i8 (...)* @sin() nounwind
+ ret i32 0
+}
+
+declare signext i8 @sin(...)
diff --git a/test/Transforms/SCCP/apint-array.ll b/test/Transforms/SCCP/apint-array.ll
new file mode 100644
index 0000000..1e75878
--- /dev/null
+++ b/test/Transforms/SCCP/apint-array.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -sccp -S | grep {ret i101 12}
+
+@Y = constant [6 x i101] [ i101 12, i101 123456789000000, i101 -12,i101
+-123456789000000, i101 0,i101 9123456789000000]
+
+define i101 @array()
+{
+Head:
+ %A = getelementptr [6 x i101]* @Y, i32 0, i32 1
+
+ %B = load i101* %A
+ %C = icmp sge i101 %B, 1
+ br i1 %C, label %True, label %False
+True:
+ %D = and i101 %B, 1
+ %E = trunc i101 %D to i32
+ %F = getelementptr [6 x i101]* @Y, i32 0, i32 %E
+ %G = load i101* %F
+ br label %False
+False:
+ %H = phi i101 [%G, %True], [-1, %Head]
+ ret i101 %H
+}
diff --git a/test/Transforms/SCCP/apint-basictest.ll b/test/Transforms/SCCP/apint-basictest.ll
new file mode 100644
index 0000000..c03bfef
--- /dev/null
+++ b/test/Transforms/SCCP/apint-basictest.ll
@@ -0,0 +1,16 @@
+; This is a basic sanity check for constant propogation. The add instruction
+; should be eliminated.
+
+; RUN: opt < %s -sccp -S | not grep add
+
+define i128 @test(i1 %B) {
+ br i1 %B, label %BB1, label %BB2
+BB1:
+ %Val = add i128 0, 1
+ br label %BB3
+BB2:
+ br label %BB3
+BB3:
+ %Ret = phi i128 [%Val, %BB1], [2, %BB2]
+ ret i128 %Ret
+}
diff --git a/test/Transforms/SCCP/apint-basictest2.ll b/test/Transforms/SCCP/apint-basictest2.ll
new file mode 100644
index 0000000..1734827
--- /dev/null
+++ b/test/Transforms/SCCP/apint-basictest2.ll
@@ -0,0 +1,17 @@
+; This is a basic sanity check for constant propogation. The add instruction
+; and phi instruction should be eliminated.
+
+; RUN: opt < %s -sccp -S | not grep phi
+; RUN: opt < %s -sccp -S | not grep add
+
+define i128 @test(i1 %B) {
+ br i1 %B, label %BB1, label %BB2
+BB1:
+ %Val = add i128 0, 1
+ br label %BB3
+BB2:
+ br label %BB3
+BB3:
+ %Ret = phi i128 [%Val, %BB1], [1, %BB2]
+ ret i128 %Ret
+}
diff --git a/test/Transforms/SCCP/apint-basictest3.ll b/test/Transforms/SCCP/apint-basictest3.ll
new file mode 100644
index 0000000..47671bf
--- /dev/null
+++ b/test/Transforms/SCCP/apint-basictest3.ll
@@ -0,0 +1,23 @@
+; This is a basic sanity check for constant propogation. It tests the basic
+; arithmatic operations.
+
+
+; RUN: opt < %s -sccp -S | not grep mul
+; RUN: opt < %s -sccp -S | not grep umod
+
+define i128 @test(i1 %B) {
+ br i1 %B, label %BB1, label %BB2
+BB1:
+ %t1 = add i128 0, 1
+ %t2 = sub i128 0, %t1
+ %t3 = mul i128 %t2, -1
+ br label %BB3
+BB2:
+ %f1 = udiv i128 -1, 1
+ %f2 = add i128 %f1, 1
+ %f3 = urem i128 %f2, 2121
+ br label %BB3
+BB3:
+ %Ret = phi i128 [%t3, %BB1], [%f3, %BB2]
+ ret i128 %Ret
+}
diff --git a/test/Transforms/SCCP/apint-basictest4.ll b/test/Transforms/SCCP/apint-basictest4.ll
new file mode 100644
index 0000000..41036ea
--- /dev/null
+++ b/test/Transforms/SCCP/apint-basictest4.ll
@@ -0,0 +1,25 @@
+; This is a basic sanity check for constant propogation. It tests the basic
+; logic operations.
+
+
+; RUN: opt < %s -sccp -S | not grep and
+; RUN: opt < %s -sccp -S | not grep trunc
+; RUN: opt < %s -sccp -S | grep {ret i100 -1}
+
+define i100 @test(i133 %A) {
+ %B = and i133 0, %A
+ %C = icmp sgt i133 %B, 0
+ br i1 %C, label %BB1, label %BB2
+BB1:
+ %t3 = xor i133 %B, -1
+ %t4 = trunc i133 %t3 to i100
+ br label %BB3
+BB2:
+ %f1 = or i133 -1, %A
+ %f2 = lshr i133 %f1, 33
+ %f3 = trunc i133 %f2 to i100
+ br label %BB3
+BB3:
+ %Ret = phi i100 [%t4, %BB1], [%f3, %BB2]
+ ret i100 %Ret
+}
diff --git a/test/Transforms/SCCP/apint-bigarray.ll b/test/Transforms/SCCP/apint-bigarray.ll
new file mode 100644
index 0000000..0dd9ad3
--- /dev/null
+++ b/test/Transforms/SCCP/apint-bigarray.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -sccp -S | not grep %X
+
+@G = global [1000000 x i10000] zeroinitializer
+
+define internal i10000* @test(i10000 %Arg) {
+ %X = getelementptr [1000000 x i10000]* @G, i32 0, i32 999
+ store i10000 %Arg, i10000* %X
+ ret i10000* %X
+}
+
+define i10000 @caller()
+{
+ %Y = call i10000* @test(i10000 -1)
+ %Z = load i10000* %Y
+ ret i10000 %Z
+}
+
+define i10000 @caller2()
+{
+ %Y = call i10000* @test(i10000 1)
+ %Z = load i10000* %Y
+ ret i10000 %Z
+}
diff --git a/test/Transforms/SCCP/apint-bigint.ll b/test/Transforms/SCCP/apint-bigint.ll
new file mode 100644
index 0000000..36a96c3
--- /dev/null
+++ b/test/Transforms/SCCP/apint-bigint.ll
@@ -0,0 +1,9 @@
+; RUN: opt < %s -sccp -S | not grep xor
+
+define i11129 @test1() {
+ %B = shl i11129 1, 11128
+ %C = sub i11129 %B, 1
+ %D = xor i11129 %B, %C
+
+ ret i11129 %D
+}
diff --git a/test/Transforms/SCCP/apint-bigint2.ll b/test/Transforms/SCCP/apint-bigint2.ll
new file mode 100644
index 0000000..660eaad
--- /dev/null
+++ b/test/Transforms/SCCP/apint-bigint2.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -sccp -S | not grep load
+
+@Y = constant [6 x i101] [ i101 12, i101 123456789000000, i101 -12,
+ i101 -123456789000000, i101 0,i101 9123456789000000]
+
+define i101 @array()
+{
+Head:
+ %A = getelementptr [6 x i101]* @Y, i32 0, i32 1
+ %B = load i101* %A
+ %D = and i101 %B, 1
+ %DD = or i101 %D, 1
+ %E = trunc i101 %DD to i32
+ %F = getelementptr [6 x i101]* @Y, i32 0, i32 %E
+ %G = load i101* %F
+
+ ret i101 %G
+}
diff --git a/test/Transforms/SCCP/apint-ipsccp1.ll b/test/Transforms/SCCP/apint-ipsccp1.ll
new file mode 100644
index 0000000..fda40f5
--- /dev/null
+++ b/test/Transforms/SCCP/apint-ipsccp1.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -ipsccp -S | grep -v {ret i512 undef} | \
+; RUN: grep {ret i8 2}
+
+define internal i512 @test(i1 %B) {
+ br i1 %B, label %BB1, label %BB2
+BB1:
+ %Val = add i512 0, 1
+ br label %BB3
+BB2:
+ br label %BB3
+BB3:
+ %Ret = phi i512 [%Val, %BB1], [2, %BB2]
+ ret i512 %Ret
+}
+
+define i8 @caller()
+{
+ %t1 = and i2 2, 1
+ %t11 = trunc i2 %t1 to i1
+ %t2 = call i512 @test(i1 %t11)
+ %t3 = trunc i512 %t2 to i8
+ ret i8 %t3
+}
+
diff --git a/test/Transforms/SCCP/apint-ipsccp2.ll b/test/Transforms/SCCP/apint-ipsccp2.ll
new file mode 100644
index 0000000..3c02e05
--- /dev/null
+++ b/test/Transforms/SCCP/apint-ipsccp2.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -ipsccp -S | grep -v {ret i101 0} | \
+; RUN: grep -v {ret i101 undef} | not grep ret
+
+
+define internal i101 @bar(i101 %A) {
+ %x = icmp eq i101 %A, 0
+ br i1 %x, label %T, label %F
+T:
+ %B = call i101 @bar(i101 0)
+ ret i101 0
+F: ; unreachable
+ %C = call i101 @bar(i101 1)
+ ret i101 %C
+}
+
+define i101 @foo() {
+ %X = call i101 @bar(i101 0)
+ ret i101 %X
+}
diff --git a/test/Transforms/SCCP/apint-ipsccp3.ll b/test/Transforms/SCCP/apint-ipsccp3.ll
new file mode 100644
index 0000000..68987ae
--- /dev/null
+++ b/test/Transforms/SCCP/apint-ipsccp3.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -ipsccp -S | not grep global
+
+@G = internal global i66 undef
+
+
+
+define void @foo() {
+ %X = load i66* @G
+ store i66 %X, i66* @G
+ ret void
+}
+
+define i66 @bar() {
+ %V = load i66* @G
+ %C = icmp eq i66 %V, 17
+ br i1 %C, label %T, label %F
+T:
+ store i66 17, i66* @G
+ ret i66 %V
+F:
+ store i66 123, i66* @G
+ ret i66 0
+}
diff --git a/test/Transforms/SCCP/apint-ipsccp4.ll b/test/Transforms/SCCP/apint-ipsccp4.ll
new file mode 100644
index 0000000..75875ff
--- /dev/null
+++ b/test/Transforms/SCCP/apint-ipsccp4.ll
@@ -0,0 +1,49 @@
+; This test makes sure that these instructions are properly constant propagated.
+
+; RUN: opt < %s -ipsccp -S | not grep load
+; RUN: opt < %s -ipsccp -S | not grep add
+; RUN: opt < %s -ipsccp -S | not grep phi
+
+
+@Y = constant [2 x { i212, float }] [ { i212, float } { i212 12, float 1.0 },
+ { i212, float } { i212 37, float 2.0 } ]
+
+define internal float @test2() {
+ %A = getelementptr [2 x { i212, float}]* @Y, i32 0, i32 1, i32 1
+ %B = load float* %A
+ ret float %B
+}
+
+define internal float @test3() {
+ %A = getelementptr [2 x { i212, float}]* @Y, i32 0, i32 0, i32 1
+ %B = load float* %A
+ ret float %B
+}
+
+define internal float @test()
+{
+ %A = call float @test2()
+ %B = call float @test3()
+
+ %E = fdiv float %B, %A
+ ret float %E
+}
+
+define float @All()
+{
+ %A = call float @test()
+ %B = fcmp oge float %A, 1.0
+ br i1 %B, label %T, label %F
+T:
+ %C = fadd float %A, 1.0
+ br label %exit
+F:
+ %D = fadd float %A, 2.0
+ br label %exit
+exit:
+ %E = phi float [%C, %T], [%D, %F]
+ ret float %E
+}
+
+
+
diff --git a/test/Transforms/SCCP/apint-load.ll b/test/Transforms/SCCP/apint-load.ll
new file mode 100644
index 0000000..56fdb35
--- /dev/null
+++ b/test/Transforms/SCCP/apint-load.ll
@@ -0,0 +1,36 @@
+; This test makes sure that these instructions are properly constant propagated.
+
+; RUN: opt < %s -ipsccp -S | not grep load
+; RUN: opt < %s -ipsccp -S | not grep fdiv
+
+@X = constant i212 42
+@Y = constant [2 x { i212, float }] [ { i212, float } { i212 12, float 1.0 },
+ { i212, float } { i212 37, float 0x3FF3B2FEC0000000 } ]
+define i212 @test1() {
+ %B = load i212* @X
+ ret i212 %B
+}
+
+define internal float @test2() {
+ %A = getelementptr [2 x { i212, float}]* @Y, i32 0, i32 1, i32 1
+ %B = load float* %A
+ ret float %B
+}
+
+define internal i212 @test3() {
+ %A = getelementptr [2 x { i212, float}]* @Y, i32 0, i32 0, i32 0
+ %B = load i212* %A
+ ret i212 %B
+}
+
+define float @All()
+{
+ %A = call float @test2()
+ %B = call i212 @test3()
+ %C = mul i212 %B, -1234567
+ %D = sitofp i212 %C to float
+ %E = fdiv float %A, %D
+ ret float %E
+}
+
+
diff --git a/test/Transforms/SCCP/apint-phi.ll b/test/Transforms/SCCP/apint-phi.ll
new file mode 100644
index 0000000..50f0d1a
--- /dev/null
+++ b/test/Transforms/SCCP/apint-phi.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -sccp -S | not grep phi
+
+define i999 @test(i999%A, i1 %c) {
+bb1:
+ br label %BB2
+BB2:
+ %V = phi i999 [2, %bb1], [%A, %BB4]
+ br label %BB3
+
+BB3:
+ %E = trunc i999 %V to i1
+ %F = and i1 %E, %c
+ br i1 %F, label %BB4, label %BB5
+BB4:
+ br label %BB2
+
+BB5:
+ ret i999 %V
+}
diff --git a/test/Transforms/SCCP/apint-select.ll b/test/Transforms/SCCP/apint-select.ll
new file mode 100644
index 0000000..c797519
--- /dev/null
+++ b/test/Transforms/SCCP/apint-select.ll
@@ -0,0 +1,21 @@
+; RUN: opt < %s -sccp -S | not grep select
+
+@A = constant i32 10
+
+define i712 @test1() {
+ %P = getelementptr i32* @A, i32 0
+ %B = ptrtoint i32* %P to i64
+ %BB = and i64 %B, undef
+ %C = icmp sge i64 %BB, 0
+ %X = select i1 %C, i712 0, i712 1
+ ret i712 %X
+}
+
+
+
+define i712 @test2(i1 %C) {
+ %X = select i1 %C, i712 0, i712 undef
+ ret i712 %X
+}
+
+
diff --git a/test/Transforms/SCCP/calltest.ll b/test/Transforms/SCCP/calltest.ll
new file mode 100644
index 0000000..9dec22f
--- /dev/null
+++ b/test/Transforms/SCCP/calltest.ll
@@ -0,0 +1,21 @@
+; RUN: opt < %s -sccp -loop-deletion -simplifycfg -S | not grep br
+
+; No matter how hard you try, sqrt(1.0) is always 1.0. This allows the
+; optimizer to delete this loop.
+
+declare double @sqrt(double)
+
+define double @test(i32 %param) {
+entry:
+ br label %Loop
+Loop: ; preds = %Loop, %entry
+ %I2 = phi i32 [ 0, %entry ], [ %I3, %Loop ] ; <i32> [#uses=1]
+ %V = phi double [ 1.000000e+00, %entry ], [ %V2, %Loop ] ; <double> [#uses=2]
+ %V2 = call double @sqrt( double %V ) ; <double> [#uses=1]
+ %I3 = add i32 %I2, 1 ; <i32> [#uses=2]
+ %tmp.7 = icmp ne i32 %I3, %param ; <i1> [#uses=1]
+ br i1 %tmp.7, label %Loop, label %Exit
+Exit: ; preds = %Loop
+ ret double %V
+}
+
diff --git a/test/Transforms/SCCP/crash.ll b/test/Transforms/SCCP/crash.ll
new file mode 100644
index 0000000..2f6da1d
--- /dev/null
+++ b/test/Transforms/SCCP/crash.ll
@@ -0,0 +1,29 @@
+; RUN: opt %s -sccp -S
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10.0"
+
+define void @test1(i8 %arg) {
+entry:
+ br i1 undef, label %return, label %bb
+
+bb:
+ br label %bb34
+
+bb23:
+ %c = icmp eq i8 %arg, undef
+ br i1 %c, label %bb34, label %bb23
+
+bb34:
+ %Kind.1 = phi i32 [ undef, %bb ], [ %ins174, %bb23 ]
+ %mask173 = or i32 %Kind.1, 7
+ %ins174 = and i32 %mask173, -249
+ br label %bb23
+
+return:
+ ret void
+}
+
+define i32 @test2([4 x i32] %A) {
+ %B = extractvalue [4 x i32] %A, 1
+ ret i32 %B
+}
diff --git a/test/Transforms/SCCP/dg.exp b/test/Transforms/SCCP/dg.exp
new file mode 100644
index 0000000..f200589
--- /dev/null
+++ b/test/Transforms/SCCP/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/test/Transforms/SCCP/ipsccp-basic.ll b/test/Transforms/SCCP/ipsccp-basic.ll
new file mode 100644
index 0000000..e369920
--- /dev/null
+++ b/test/Transforms/SCCP/ipsccp-basic.ll
@@ -0,0 +1,206 @@
+; RUN: opt < %s -ipsccp -S | FileCheck %s
+
+;;======================== test1
+
+define internal i32 @test1a(i32 %A) {
+ %X = add i32 1, 2
+ ret i32 %A
+}
+; CHECK: define internal i32 @test1a
+; CHECK: ret i32 undef
+
+define i32 @test1b() {
+ %X = call i32 @test1a( i32 17 )
+ ret i32 %X
+
+; CHECK: define i32 @test1b
+; CHECK: ret i32 17
+}
+
+
+
+;;======================== test2
+
+define internal i32 @test2a(i32 %A) {
+ %C = icmp eq i32 %A, 0
+ br i1 %C, label %T, label %F
+T:
+ %B = call i32 @test2a( i32 0 )
+ ret i32 0
+F:
+ %C.upgrd.1 = call i32 @test2a(i32 1)
+ ret i32 %C.upgrd.1
+}
+; CHECK: define internal i32 @test2a
+; CHECK-NEXT: br label %T
+; CHECK: ret i32 undef
+
+
+define i32 @test2b() {
+ %X = call i32 @test2a(i32 0)
+ ret i32 %X
+}
+; CHECK: define i32 @test2b
+; CHECK-NEXT: %X = call i32 @test2a(i32 0)
+; CHECK-NEXT: ret i32 0
+
+
+;;======================== test3
+
+@G = internal global i32 undef
+
+define void @test3a() {
+ %X = load i32* @G
+ store i32 %X, i32* @G
+ ret void
+}
+; CHECK: define void @test3a
+; CHECK-NEXT: ret void
+
+
+define i32 @test3b() {
+ %V = load i32* @G
+ %C = icmp eq i32 %V, 17
+ br i1 %C, label %T, label %F
+T:
+ store i32 17, i32* @G
+ ret i32 %V
+F:
+ store i32 123, i32* @G
+ ret i32 0
+}
+; CHECK: define i32 @test3b
+; CHECK-NOT: store
+; CHECK: ret i32 0
+
+
+;;======================== test4
+
+define internal {i64,i64} @test4a() {
+ %a = insertvalue {i64,i64} undef, i64 4, 1
+ %b = insertvalue {i64,i64} %a, i64 5, 0
+ ret {i64,i64} %b
+}
+
+define i64 @test4b() {
+ %a = invoke {i64,i64} @test4a()
+ to label %A unwind label %B
+A:
+ %b = extractvalue {i64,i64} %a, 0
+ %c = call i64 @test4c(i64 %b)
+ ret i64 %c
+B:
+ ret i64 0
+}
+; CHECK: define i64 @test4b()
+; CHECK: %c = call i64 @test4c(i64 5)
+; CHECK-NEXT: ret i64 5
+
+
+define internal i64 @test4c(i64 %a) {
+ ret i64 %a
+}
+; CHECK: define internal i64 @test4c
+; CHECK: ret i64 undef
+
+
+
+;;======================== test5
+
+; PR4313
+define internal {i64,i64} @test5a() {
+ %a = insertvalue {i64,i64} undef, i64 4, 1
+ %b = insertvalue {i64,i64} %a, i64 5, 0
+ ret {i64,i64} %b
+}
+
+define i64 @test5b() {
+ %a = invoke {i64,i64} @test5a()
+ to label %A unwind label %B
+A:
+ %c = call i64 @test5c({i64,i64} %a)
+ ret i64 %c
+B:
+ ret i64 0
+}
+
+; CHECK: define i64 @test5b()
+; CHECK: A:
+; CHECK-NEXT: %c = call i64 @test5c(%0 %a)
+; CHECK-NEXT: ret i64 5
+
+define internal i64 @test5c({i64,i64} %a) {
+ %b = extractvalue {i64,i64} %a, 0
+ ret i64 %b
+}
+
+
+;;======================== test6
+
+define i64 @test6a() {
+ ret i64 0
+}
+
+define i64 @test6b() {
+ %a = call i64 @test6a()
+ ret i64 %a
+}
+; CHECK: define i64 @test6b
+; CHECK: ret i64 0
+
+;;======================== test7
+
+
+%T = type {i32,i32}
+
+define internal {i32, i32} @test7a(i32 %A) {
+ %X = add i32 1, %A
+ %mrv0 = insertvalue %T undef, i32 %X, 0
+ %mrv1 = insertvalue %T %mrv0, i32 %A, 1
+ ret %T %mrv1
+; CHECK: @test7a
+; CHECK-NEXT: %mrv0 = insertvalue %T undef, i32 18, 0
+; CHECK-NEXT: %mrv1 = insertvalue %T %mrv0, i32 17, 1
+}
+
+define i32 @test7b() {
+ %X = call {i32, i32} @test7a(i32 17)
+ %Y = extractvalue {i32, i32} %X, 0
+ %Z = add i32 %Y, %Y
+ ret i32 %Z
+; CHECK: define i32 @test7b
+; CHECK-NEXT: call %T @test7a(i32 17)
+; CHECK-NEXT: ret i32 36
+}
+
+;;======================== test8
+
+
+define internal {} @test8a(i32 %A, i32* %P) {
+ store i32 %A, i32* %P
+ ret {} {}
+; CHECK: @test8a
+; CHECK-NEXT: store i32 5,
+; CHECK-NEXT: ret
+}
+
+define void @test8b(i32* %P) {
+ %X = call {} @test8a(i32 5, i32* %P)
+ ret void
+; CHECK: define void @test8b
+; CHECK-NEXT: call { } @test8a
+; CHECK-NEXT: ret void
+}
+
+;;======================== test9
+
+@test9g = internal global { } zeroinitializer
+
+define void @test9() {
+entry:
+ %local_foo = alloca { }
+ load { }* @test9g
+ store { } %0, { }* %local_foo
+ ret void
+}
+
diff --git a/test/Transforms/SCCP/loadtest.ll b/test/Transforms/SCCP/loadtest.ll
new file mode 100644
index 0000000..add2af4
--- /dev/null
+++ b/test/Transforms/SCCP/loadtest.ll
@@ -0,0 +1,33 @@
+; This test makes sure that these instructions are properly constant propagated.
+
+target datalayout = "e-p:32:32"
+
+; RUN: opt < %s -sccp -S | not grep load
+
+
+@X = constant i32 42 ; <i32*> [#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]
+
+define i32 @test1() {
+ %B = load i32* @X ; <i32> [#uses=1]
+ ret i32 %B
+}
+
+define float @test2() {
+ %A = getelementptr [2 x { i32, float }]* @Y, i64 0, i64 1, i32 1 ; <float*> [#uses=1]
+ %B = load float* %A ; <float> [#uses=1]
+ ret float %B
+}
+
+define i32 @test3() {
+ %A = getelementptr [2 x { i32, float }]* @Y, i64 0, i64 0, i32 0 ; <i32*> [#uses=1]
+ %B = load i32* %A
+ ret i32 %B
+}
+
+define i8 @test4() {
+ %A = bitcast i32* @X to i8*
+ %B = load i8* %A
+ ret i8 %B
+}
+
diff --git a/test/Transforms/SCCP/logical-nuke.ll b/test/Transforms/SCCP/logical-nuke.ll
new file mode 100644
index 0000000..b3d845c
--- /dev/null
+++ b/test/Transforms/SCCP/logical-nuke.ll
@@ -0,0 +1,9 @@
+; RUN: opt < %s -sccp -S | grep {ret i32 0}
+
+; Test that SCCP has basic knowledge of when and/or nuke overdefined values.
+
+define i32 @test(i32 %X) {
+ %Y = and i32 %X, 0 ; <i32> [#uses=1]
+ ret i32 %Y
+}
+
diff --git a/test/Transforms/SCCP/phitest.ll b/test/Transforms/SCCP/phitest.ll
new file mode 100644
index 0000000..4c5c3dc
--- /dev/null
+++ b/test/Transforms/SCCP/phitest.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -sccp -dce -simplifycfg -S | not grep br
+
+define i32 @test(i32 %param) {
+entry:
+ %tmp.1 = icmp ne i32 %param, 0 ; <i1> [#uses=1]
+ br i1 %tmp.1, label %endif.0, label %else
+else: ; preds = %entry
+ br label %endif.0
+endif.0: ; preds = %else, %entry
+ %a.0 = phi i32 [ 2, %else ], [ 3, %entry ] ; <i32> [#uses=1]
+ %b.0 = phi i32 [ 3, %else ], [ 2, %entry ] ; <i32> [#uses=1]
+ %tmp.5 = add i32 %a.0, %b.0 ; <i32> [#uses=1]
+ %tmp.7 = icmp ne i32 %tmp.5, 5 ; <i1> [#uses=1]
+ br i1 %tmp.7, label %UnifiedReturnBlock, label %endif.1
+endif.1: ; preds = %endif.0
+ ret i32 0
+UnifiedReturnBlock: ; preds = %endif.0
+ ret i32 2
+}
+
diff --git a/test/Transforms/SCCP/sccptest.ll b/test/Transforms/SCCP/sccptest.ll
new file mode 100644
index 0000000..a719f6c
--- /dev/null
+++ b/test/Transforms/SCCP/sccptest.ll
@@ -0,0 +1,58 @@
+; RUN: opt < %s -sccp -S | FileCheck %s
+
+; This is a basic sanity check for constant propagation. The add instruction
+; should be eliminated.
+
+define i32 @test1(i1 %B) {
+ br i1 %B, label %BB1, label %BB2
+BB1: ; preds = %0
+ %Val = add i32 0, 0 ; <i32> [#uses=1]
+ br label %BB3
+BB2: ; preds = %0
+ br label %BB3
+BB3: ; preds = %BB2, %BB1
+ %Ret = phi i32 [ %Val, %BB1 ], [ 1, %BB2 ] ; <i32> [#uses=1]
+ ret i32 %Ret
+
+; CHECK: @test1
+; CHECK: %Ret = phi i32 [ 0, %BB1 ], [ 1, %BB2 ]
+}
+
+; This is the test case taken from appel's book that illustrates a hard case
+; that SCCP gets right.
+;
+define i32 @test2(i32 %i0, i32 %j0) {
+; CHECK: @test2
+BB1:
+ br label %BB2
+BB2:
+ %j2 = phi i32 [ %j4, %BB7 ], [ 1, %BB1 ]
+ %k2 = phi i32 [ %k4, %BB7 ], [ 0, %BB1 ]
+ %kcond = icmp slt i32 %k2, 100
+ br i1 %kcond, label %BB3, label %BB4
+BB3:
+ %jcond = icmp slt i32 %j2, 20
+ br i1 %jcond, label %BB5, label %BB6
+; CHECK: BB3:
+; CHECK-NEXT: br i1 true, label %BB5, label %BB6
+BB4:
+ ret i32 %j2
+; CHECK: BB4:
+; CHECK-NEXT: ret i32 1
+BB5:
+ %k3 = add i32 %k2, 1
+ br label %BB7
+BB6:
+ %k5 = add i32 %k2, 1
+ br label %BB7
+; CHECK: BB6:
+; CHECK-NEXT: br label %BB7
+BB7:
+ %j4 = phi i32 [ 1, %BB5 ], [ %k2, %BB6 ]
+ %k4 = phi i32 [ %k3, %BB5 ], [ %k5, %BB6 ]
+ br label %BB2
+; CHECK: BB7:
+; CHECK-NEXT: %k4 = phi i32 [ %k3, %BB5 ], [ undef, %BB6 ]
+; CHECK-NEXT: br label %BB2
+}
+
diff --git a/test/Transforms/SCCP/select.ll b/test/Transforms/SCCP/select.ll
new file mode 100644
index 0000000..b2f1dd2
--- /dev/null
+++ b/test/Transforms/SCCP/select.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -sccp -S | not grep select
+
+define i32 @test1(i1 %C) {
+ %X = select i1 %C, i32 0, i32 0 ; <i32> [#uses=1]
+ ret i32 %X
+}
+
+define i32 @test2(i1 %C) {
+ %X = select i1 %C, i32 0, i32 undef ; <i32> [#uses=1]
+ ret i32 %X
+}
+