summaryrefslogtreecommitdiffstats
path: root/test/Transforms/Mem2Reg
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/Mem2Reg')
-rw-r--r--test/Transforms/Mem2Reg/2002-03-28-UninitializedVal.ll11
-rw-r--r--test/Transforms/Mem2Reg/2002-05-01-ShouldNotPromoteThisAlloca.ll12
-rw-r--r--test/Transforms/Mem2Reg/2003-04-10-DFNotFound.ll10
-rw-r--r--test/Transforms/Mem2Reg/2003-04-18-DeadBlockProblem.ll16
-rw-r--r--test/Transforms/Mem2Reg/2003-04-24-MultipleIdenticalSuccessors.ll16
-rw-r--r--test/Transforms/Mem2Reg/2003-06-26-IterativePromote.ll16
-rw-r--r--test/Transforms/Mem2Reg/2003-10-05-DeadPHIInsertion.ll22
-rw-r--r--test/Transforms/Mem2Reg/2005-06-30-ReadBeforeWrite.ll47
-rw-r--r--test/Transforms/Mem2Reg/2005-11-28-Crash.ll62
-rw-r--r--test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll47
-rw-r--r--test/Transforms/Mem2Reg/ConvertDebugInfo.ll32
-rw-r--r--test/Transforms/Mem2Reg/PromoteMemToRegister.ll18
-rw-r--r--test/Transforms/Mem2Reg/UndefValuesMerge.ll13
-rw-r--r--test/Transforms/Mem2Reg/crash.ll41
-rw-r--r--test/Transforms/Mem2Reg/dg.exp3
15 files changed, 366 insertions, 0 deletions
diff --git a/test/Transforms/Mem2Reg/2002-03-28-UninitializedVal.ll b/test/Transforms/Mem2Reg/2002-03-28-UninitializedVal.ll
new file mode 100644
index 0000000..777f375
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2002-03-28-UninitializedVal.ll
@@ -0,0 +1,11 @@
+; Uninitialized values are not handled correctly.
+;
+; RUN: opt < %s -mem2reg -disable-output
+;
+
+define i32 @test() {
+ ; To be promoted
+ %X = alloca i32 ; <i32*> [#uses=1]
+ %Y = load i32* %X ; <i32> [#uses=1]
+ ret i32 %Y
+}
diff --git a/test/Transforms/Mem2Reg/2002-05-01-ShouldNotPromoteThisAlloca.ll b/test/Transforms/Mem2Reg/2002-05-01-ShouldNotPromoteThisAlloca.ll
new file mode 100644
index 0000000..89bd492
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2002-05-01-ShouldNotPromoteThisAlloca.ll
@@ -0,0 +1,12 @@
+; This input caused the mem2reg pass to die because it was trying to promote
+; the %r alloca, even though it is invalid to do so in this case!
+;
+; RUN: opt < %s -mem2reg
+
+define void @test() {
+ %r = alloca i32 ; <i32*> [#uses=2]
+ store i32 4, i32* %r
+ store i32* %r, i32** null
+ ret void
+}
+
diff --git a/test/Transforms/Mem2Reg/2003-04-10-DFNotFound.ll b/test/Transforms/Mem2Reg/2003-04-10-DFNotFound.ll
new file mode 100644
index 0000000..3665483
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2003-04-10-DFNotFound.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -mem2reg
+
+define void @_Z3barv() {
+ %result = alloca i32 ; <i32*> [#uses=1]
+ ret void
+ ; No predecessors!
+ store i32 0, i32* %result
+ ret void
+}
+
diff --git a/test/Transforms/Mem2Reg/2003-04-18-DeadBlockProblem.ll b/test/Transforms/Mem2Reg/2003-04-18-DeadBlockProblem.ll
new file mode 100644
index 0000000..36bd9e6
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2003-04-18-DeadBlockProblem.ll
@@ -0,0 +1,16 @@
+; This testcases makes sure that mem2reg can handle unreachable blocks.
+; RUN: opt < %s -mem2reg
+
+define i32 @test() {
+ %X = alloca i32 ; <i32*> [#uses=2]
+ store i32 6, i32* %X
+ br label %Loop
+Loop: ; preds = %EndOfLoop, %0
+ store i32 5, i32* %X
+ br label %EndOfLoop
+Unreachable: ; No predecessors!
+ br label %EndOfLoop
+EndOfLoop: ; preds = %Unreachable, %Loop
+ br label %Loop
+}
+
diff --git a/test/Transforms/Mem2Reg/2003-04-24-MultipleIdenticalSuccessors.ll b/test/Transforms/Mem2Reg/2003-04-24-MultipleIdenticalSuccessors.ll
new file mode 100644
index 0000000..f5f1ee3
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2003-04-24-MultipleIdenticalSuccessors.ll
@@ -0,0 +1,16 @@
+; Mem2reg used to only add one incoming value to a PHI node, even if it had
+; multiple incoming edges from a block.
+;
+; RUN: opt < %s -mem2reg -disable-output
+
+define i32 @test(i1 %c1, i1 %c2) {
+ %X = alloca i32 ; <i32*> [#uses=2]
+ br i1 %c1, label %Exit, label %B2
+B2: ; preds = %0
+ store i32 2, i32* %X
+ br i1 %c2, label %Exit, label %Exit
+Exit: ; preds = %B2, %B2, %0
+ %Y = load i32* %X ; <i32> [#uses=1]
+ ret i32 %Y
+}
+
diff --git a/test/Transforms/Mem2Reg/2003-06-26-IterativePromote.ll b/test/Transforms/Mem2Reg/2003-06-26-IterativePromote.ll
new file mode 100644
index 0000000..e82caa9
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2003-06-26-IterativePromote.ll
@@ -0,0 +1,16 @@
+; Promoting some values allows promotion of other values.
+; RUN: opt < %s -mem2reg -S | not grep alloca
+
+define i32 @test2() {
+ %result = alloca i32 ; <i32*> [#uses=2]
+ %a = alloca i32 ; <i32*> [#uses=2]
+ %p = alloca i32* ; <i32**> [#uses=2]
+ store i32 0, i32* %a
+ store i32* %a, i32** %p
+ %tmp.0 = load i32** %p ; <i32*> [#uses=1]
+ %tmp.1 = load i32* %tmp.0 ; <i32> [#uses=1]
+ store i32 %tmp.1, i32* %result
+ %tmp.2 = load i32* %result ; <i32> [#uses=1]
+ ret i32 %tmp.2
+}
+
diff --git a/test/Transforms/Mem2Reg/2003-10-05-DeadPHIInsertion.ll b/test/Transforms/Mem2Reg/2003-10-05-DeadPHIInsertion.ll
new file mode 100644
index 0000000..1d38efc
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2003-10-05-DeadPHIInsertion.ll
@@ -0,0 +1,22 @@
+; Mem2reg should not insert dead PHI nodes! The naive algorithm inserts a PHI
+; node in L3, even though there is no load of %A in anything dominated by L3.
+
+; RUN: opt < %s -mem2reg -S | not grep phi
+
+define void @test(i32 %B, i1 %C) {
+ %A = alloca i32 ; <i32*> [#uses=4]
+ store i32 %B, i32* %A
+ br i1 %C, label %L1, label %L2
+L1: ; preds = %0
+ store i32 %B, i32* %A
+ %D = load i32* %A ; <i32> [#uses=1]
+ call void @test( i32 %D, i1 false )
+ br label %L3
+L2: ; preds = %0
+ %E = load i32* %A ; <i32> [#uses=1]
+ call void @test( i32 %E, i1 true )
+ br label %L3
+L3: ; preds = %L2, %L1
+ ret void
+}
+
diff --git a/test/Transforms/Mem2Reg/2005-06-30-ReadBeforeWrite.ll b/test/Transforms/Mem2Reg/2005-06-30-ReadBeforeWrite.ll
new file mode 100644
index 0000000..7435596
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2005-06-30-ReadBeforeWrite.ll
@@ -0,0 +1,47 @@
+; RUN: opt < %s -mem2reg -instcombine -S | grep store
+; PR590
+
+
+define void @zero(i8* %p, i32 %n) {
+entry:
+ %p_addr = alloca i8* ; <i8**> [#uses=2]
+ %n_addr = alloca i32 ; <i32*> [#uses=2]
+ %i = alloca i32 ; <i32*> [#uses=6]
+ %out = alloca i32 ; <i32*> [#uses=2]
+ %undef = alloca i32 ; <i32*> [#uses=2]
+ store i8* %p, i8** %p_addr
+ store i32 %n, i32* %n_addr
+ store i32 0, i32* %i
+ br label %loopentry
+loopentry: ; preds = %endif, %entry
+ %tmp.0 = load i32* %n_addr ; <i32> [#uses=1]
+ %tmp.1 = add i32 %tmp.0, 1 ; <i32> [#uses=1]
+ %tmp.2 = load i32* %i ; <i32> [#uses=1]
+ %tmp.3 = icmp sgt i32 %tmp.1, %tmp.2 ; <i1> [#uses=2]
+ %tmp.4 = zext i1 %tmp.3 to i32 ; <i32> [#uses=0]
+ br i1 %tmp.3, label %no_exit, label %return
+no_exit: ; preds = %loopentry
+ %tmp.5 = load i32* %undef ; <i32> [#uses=1]
+ store i32 %tmp.5, i32* %out
+ store i32 0, i32* %undef
+ %tmp.6 = load i32* %i ; <i32> [#uses=1]
+ %tmp.7 = icmp sgt i32 %tmp.6, 0 ; <i1> [#uses=2]
+ %tmp.8 = zext i1 %tmp.7 to i32 ; <i32> [#uses=0]
+ br i1 %tmp.7, label %then, label %endif
+then: ; preds = %no_exit
+ %tmp.9 = load i8** %p_addr ; <i8*> [#uses=1]
+ %tmp.10 = load i32* %i ; <i32> [#uses=1]
+ %tmp.11 = sub i32 %tmp.10, 1 ; <i32> [#uses=1]
+ %tmp.12 = getelementptr i8* %tmp.9, i32 %tmp.11 ; <i8*> [#uses=1]
+ %tmp.13 = load i32* %out ; <i32> [#uses=1]
+ %tmp.14 = trunc i32 %tmp.13 to i8 ; <i8> [#uses=1]
+ store i8 %tmp.14, i8* %tmp.12
+ br label %endif
+endif: ; preds = %then, %no_exit
+ %tmp.15 = load i32* %i ; <i32> [#uses=1]
+ %inc = add i32 %tmp.15, 1 ; <i32> [#uses=1]
+ store i32 %inc, i32* %i
+ br label %loopentry
+return: ; preds = %loopentry
+ ret void
+}
diff --git a/test/Transforms/Mem2Reg/2005-11-28-Crash.ll b/test/Transforms/Mem2Reg/2005-11-28-Crash.ll
new file mode 100644
index 0000000..8fd3351
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2005-11-28-Crash.ll
@@ -0,0 +1,62 @@
+; RUN: opt < %s -mem2reg -disable-output
+; PR670
+
+define void @printk(i32, ...) {
+entry:
+ %flags = alloca i32 ; <i32*> [#uses=2]
+ br i1 false, label %then.0, label %endif.0
+then.0: ; preds = %entry
+ br label %endif.0
+endif.0: ; preds = %then.0, %entry
+ store i32 0, i32* %flags
+ br label %loopentry
+loopentry: ; preds = %endif.3, %endif.0
+ br i1 false, label %no_exit, label %loopexit
+no_exit: ; preds = %loopentry
+ br i1 false, label %then.1, label %endif.1
+then.1: ; preds = %no_exit
+ br i1 false, label %shortcirc_done.0, label %shortcirc_next.0
+shortcirc_next.0: ; preds = %then.1
+ br label %shortcirc_done.0
+shortcirc_done.0: ; preds = %shortcirc_next.0, %then.1
+ br i1 false, label %shortcirc_done.1, label %shortcirc_next.1
+shortcirc_next.1: ; preds = %shortcirc_done.0
+ br label %shortcirc_done.1
+shortcirc_done.1: ; preds = %shortcirc_next.1, %shortcirc_done.0
+ br i1 false, label %shortcirc_done.2, label %shortcirc_next.2
+shortcirc_next.2: ; preds = %shortcirc_done.1
+ br label %shortcirc_done.2
+shortcirc_done.2: ; preds = %shortcirc_next.2, %shortcirc_done.1
+ br i1 false, label %then.2, label %endif.2
+then.2: ; preds = %shortcirc_done.2
+ br label %endif.2
+endif.2: ; preds = %then.2, %shortcirc_done.2
+ br label %endif.1
+endif.1: ; preds = %endif.2, %no_exit
+ br i1 false, label %then.3, label %endif.3
+then.3: ; preds = %endif.1
+ br label %endif.3
+endif.3: ; preds = %then.3, %endif.1
+ br label %loopentry
+loopexit: ; preds = %loopentry
+ br label %endif.4
+then.4: ; No predecessors!
+ %tmp.61 = load i32* %flags ; <i32> [#uses=0]
+ br label %out
+dead_block_after_goto: ; No predecessors!
+ br label %endif.4
+endif.4: ; preds = %dead_block_after_goto, %loopexit
+ br i1 false, label %then.5, label %else
+then.5: ; preds = %endif.4
+ br label %endif.5
+else: ; preds = %endif.4
+ br label %endif.5
+endif.5: ; preds = %else, %then.5
+ br label %out
+out: ; preds = %endif.5, %then.4
+ br label %return
+after_ret: ; No predecessors!
+ br label %return
+return: ; preds = %after_ret, %out
+ ret void
+}
diff --git a/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll b/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
new file mode 100644
index 0000000..50683cf
--- /dev/null
+++ b/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
@@ -0,0 +1,47 @@
+; RUN: opt < %s -std-compile-opts -S | grep volatile | count 3
+; PR1520
+; Don't promote volatile loads/stores. This is really needed to handle setjmp/lonjmp properly.
+
+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:32:32"
+target triple = "i686-pc-linux-gnu"
+ %struct.__jmp_buf_tag = type { [6 x i32], i32, %struct.__sigset_t }
+ %struct.__sigset_t = type { [32 x i32] }
+@j = external global [1 x %struct.__jmp_buf_tag] ; <[1 x %struct.__jmp_buf_tag]*> [#uses=1]
+
+define i32 @f() {
+entry:
+ %retval = alloca i32, align 4 ; <i32*> [#uses=2]
+ %v = alloca i32, align 4 ; <i32*> [#uses=3]
+ %tmp = alloca i32, align 4 ; <i32*> [#uses=3]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ volatile store i32 0, i32* %v, align 4
+ %tmp1 = call i32 @_setjmp( %struct.__jmp_buf_tag* getelementptr ([1 x %struct.__jmp_buf_tag]* @j, i32 0, i32 0) ) ; <i32> [#uses=1]
+ %tmp2 = icmp ne i32 %tmp1, 0 ; <i1> [#uses=1]
+ %tmp23 = zext i1 %tmp2 to i8 ; <i8> [#uses=1]
+ %toBool = icmp ne i8 %tmp23, 0 ; <i1> [#uses=1]
+ br i1 %toBool, label %bb, label %bb5
+
+bb: ; preds = %entry
+ %tmp4 = volatile load i32* %v, align 4 ; <i32> [#uses=1]
+ store i32 %tmp4, i32* %tmp, align 4
+ br label %bb6
+
+bb5: ; preds = %entry
+ volatile store i32 1, i32* %v, align 4
+ call void @g( )
+ store i32 0, i32* %tmp, align 4
+ br label %bb6
+
+bb6: ; preds = %bb5, %bb
+ %tmp7 = load i32* %tmp, align 4 ; <i32> [#uses=1]
+ store i32 %tmp7, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %bb6
+ %retval8 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval8
+}
+
+declare i32 @_setjmp(%struct.__jmp_buf_tag*)
+
+declare void @g()
diff --git a/test/Transforms/Mem2Reg/ConvertDebugInfo.ll b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
new file mode 100644
index 0000000..a013a1d
--- /dev/null
+++ b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
@@ -0,0 +1,32 @@
+; RUN: opt < %s -mem2reg -S | FileCheck %s
+
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+define double @testfunc(i32 %i, double %j) {
+ %I = alloca i32 ; <i32*> [#uses=4]
+ call void @llvm.dbg.declare(metadata !{i32* %I}, metadata !0)
+ %J = alloca double ; <double*> [#uses=2]
+ call void @llvm.dbg.declare(metadata !{double* %J}, metadata !1)
+; CHECK: call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !0)
+ store i32 %i, i32* %I
+; CHECK: call void @llvm.dbg.value(metadata !{double %j}, i64 0, metadata !1), !dbg !3
+ store double %j, double* %J, !dbg !3
+ %t1 = load i32* %I ; <i32> [#uses=1]
+ %t2 = add i32 %t1, 1 ; <i32> [#uses=1]
+ store i32 %t2, i32* %I
+ %t3 = load i32* %I ; <i32> [#uses=1]
+ %t4 = sitofp i32 %t3 to double ; <double> [#uses=1]
+ %t5 = load double* %J ; <double> [#uses=1]
+ %t6 = fmul double %t4, %t5 ; <double> [#uses=1]
+ ret double %t6
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+!bar = !{!0}
+!foo = !{!2}
+
+!0 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !2, i32 5, metadata !"foo"} ; [ DW_TAG_auto_variable ]
+!1 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !0, i32 5, metadata !1} ; [ DW_TAG_auto_variable ]
+!2 = metadata !{i32 458804, i32 0, metadata !2, metadata !"foo", metadata !"bar", metadata !"bar", metadata !2, i32 3, metadata !0, i1 false, i1 true} ; [ DW_TAG_variable ]
+!3 = metadata !{i32 4, i32 0, metadata !0, null}
diff --git a/test/Transforms/Mem2Reg/PromoteMemToRegister.ll b/test/Transforms/Mem2Reg/PromoteMemToRegister.ll
new file mode 100644
index 0000000..1be6b03
--- /dev/null
+++ b/test/Transforms/Mem2Reg/PromoteMemToRegister.ll
@@ -0,0 +1,18 @@
+; Simple sanity check testcase. Both alloca's should be eliminated.
+; RUN: opt < %s -mem2reg -S | not grep alloca
+
+define double @testfunc(i32 %i, double %j) {
+ %I = alloca i32 ; <i32*> [#uses=4]
+ %J = alloca double ; <double*> [#uses=2]
+ store i32 %i, i32* %I
+ store double %j, double* %J
+ %t1 = load i32* %I ; <i32> [#uses=1]
+ %t2 = add i32 %t1, 1 ; <i32> [#uses=1]
+ store i32 %t2, i32* %I
+ %t3 = load i32* %I ; <i32> [#uses=1]
+ %t4 = sitofp i32 %t3 to double ; <double> [#uses=1]
+ %t5 = load double* %J ; <double> [#uses=1]
+ %t6 = fmul double %t4, %t5 ; <double> [#uses=1]
+ ret double %t6
+}
+
diff --git a/test/Transforms/Mem2Reg/UndefValuesMerge.ll b/test/Transforms/Mem2Reg/UndefValuesMerge.ll
new file mode 100644
index 0000000..5013229
--- /dev/null
+++ b/test/Transforms/Mem2Reg/UndefValuesMerge.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -mem2reg -S | not grep phi
+
+define i32 @testfunc(i1 %C, i32 %i, i8 %j) {
+ %I = alloca i32 ; <i32*> [#uses=2]
+ br i1 %C, label %T, label %Cont
+T: ; preds = %0
+ store i32 %i, i32* %I
+ br label %Cont
+Cont: ; preds = %T, %0
+ %Y = load i32* %I ; <i32> [#uses=1]
+ ret i32 %Y
+}
+
diff --git a/test/Transforms/Mem2Reg/crash.ll b/test/Transforms/Mem2Reg/crash.ll
new file mode 100644
index 0000000..655549f
--- /dev/null
+++ b/test/Transforms/Mem2Reg/crash.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -mem2reg -S
+; PR5023
+
+declare i32 @test1f()
+
+define i32 @test1() {
+entry:
+ %whichFlag = alloca i32
+ %A = invoke i32 @test1f()
+ to label %invcont2 unwind label %lpad86
+
+invcont2:
+ store i32 %A, i32* %whichFlag
+ br label %bb15
+
+bb15:
+ %B = load i32* %whichFlag
+ ret i32 %B
+
+lpad86:
+ br label %bb15
+
+}
+
+
+
+define i32 @test2() {
+entry:
+ %whichFlag = alloca i32
+ br label %bb15
+
+bb15:
+ %B = load i32* %whichFlag
+ ret i32 %B
+
+invcont2:
+ %C = load i32* %whichFlag
+ store i32 %C, i32* %whichFlag
+ br label %bb15
+}
+
diff --git a/test/Transforms/Mem2Reg/dg.exp b/test/Transforms/Mem2Reg/dg.exp
new file mode 100644
index 0000000..f200589
--- /dev/null
+++ b/test/Transforms/Mem2Reg/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]