aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/SRETPromotion
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/SRETPromotion')
-rw-r--r--test/Transforms/SRETPromotion/2008-03-11-attributes.ll7
-rw-r--r--test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll24
-rw-r--r--test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll20
-rw-r--r--test/Transforms/SRETPromotion/basictest.ll33
-rw-r--r--test/Transforms/SRETPromotion/dg.exp3
5 files changed, 87 insertions, 0 deletions
diff --git a/test/Transforms/SRETPromotion/2008-03-11-attributes.ll b/test/Transforms/SRETPromotion/2008-03-11-attributes.ll
new file mode 100644
index 0000000..55abec5
--- /dev/null
+++ b/test/Transforms/SRETPromotion/2008-03-11-attributes.ll
@@ -0,0 +1,7 @@
+; RUN: opt < %s -sretpromotion -disable-output
+ %struct.ObjPoint = type { double, double, double, double, double, double }
+
+define void @RotatePoint(%struct.ObjPoint* sret %agg.result, %struct.ObjPoint* byval %a, double %rx, double %ry, double %rz) nounwind {
+entry:
+ unreachable
+}
diff --git a/test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll b/test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll
new file mode 100644
index 0000000..1168b0b
--- /dev/null
+++ b/test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll
@@ -0,0 +1,24 @@
+; This test lures sretpromotion into promoting the sret argument of foo, even
+; when the function is used as an argument to bar. It used to not check for
+; this, assuming that all users of foo were direct calls, resulting in an
+; assertion failure later on.
+
+; We're mainly testing for opt not to crash, but we'll check to see if the sret
+; attribute is still there for good measure.
+; RUN: opt < %s -sretpromotion -S | grep sret
+
+%struct.S = type <{ i32, i32 }>
+
+define i32 @main() {
+entry:
+ %tmp = alloca %struct.S ; <%struct.S*> [#uses=1]
+ call void @bar( %struct.S* sret %tmp, void (%struct.S*, ...)* @foo )
+ ret i32 undef
+}
+
+declare void @bar(%struct.S* sret , void (%struct.S*, ...)*)
+
+define internal void @foo(%struct.S* sret %agg.result, ...) {
+entry:
+ ret void
+}
diff --git a/test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll b/test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll
new file mode 100644
index 0000000..26c6a6e
--- /dev/null
+++ b/test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll
@@ -0,0 +1,20 @@
+; This test shows an sret function that is used as an operand to a bitcast.
+; StructRetPromotion used to assume that a function was only used by call or
+; invoke instructions, making this code cause an assertion failure.
+
+; We're mainly testing for opt not to crash, but we'll check to see if the sret
+; attribute is still there for good measure.
+; RUN: opt < %s -sretpromotion -S | grep sret
+
+%struct.S = type <{ i32, i32 }>
+
+define i32 @main() {
+entry:
+ %bar = bitcast void (%struct.S*)* @foo to i32 ()*
+ ret i32 undef
+}
+
+define internal void @foo(%struct.S* sret) {
+entry:
+ ret void
+}
diff --git a/test/Transforms/SRETPromotion/basictest.ll b/test/Transforms/SRETPromotion/basictest.ll
new file mode 100644
index 0000000..ff047dc
--- /dev/null
+++ b/test/Transforms/SRETPromotion/basictest.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -sretpromotion -S > %t
+; RUN: cat %t | grep sret | count 1
+
+; This function is promotable
+define internal void @promotable({i32, i32}* sret %s) {
+ %A = getelementptr {i32, i32}* %s, i32 0, i32 0
+ store i32 0, i32* %A
+ %B = getelementptr {i32, i32}* %s, i32 0, i32 0
+ store i32 1, i32* %B
+ ret void
+}
+
+; This function is not promotable (due to it's use below)
+define internal void @notpromotable({i32, i32}* sret %s) {
+ %A = getelementptr {i32, i32}* %s, i32 0, i32 0
+ store i32 0, i32* %A
+ %B = getelementptr {i32, i32}* %s, i32 0, i32 0
+ store i32 1, i32* %B
+ ret void
+}
+
+define void @caller({i32, i32}* %t) {
+ %s = alloca {i32, i32}
+ call void @promotable({i32, i32}* %s)
+ %A = getelementptr {i32, i32}* %s, i32 0, i32 0
+ %a = load i32* %A
+ %B = getelementptr {i32, i32}* %s, i32 0, i32 0
+ %b = load i32* %B
+ ; This passes in something that's not an alloca, which makes the argument not
+ ; promotable
+ call void @notpromotable({i32, i32}* %t)
+ ret void
+}
diff --git a/test/Transforms/SRETPromotion/dg.exp b/test/Transforms/SRETPromotion/dg.exp
new file mode 100644
index 0000000..f200589
--- /dev/null
+++ b/test/Transforms/SRETPromotion/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]