diff options
Diffstat (limited to 'test/Transforms/SCCP')
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 +} + |