aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/NaCl/expand-varargs-attrs.ll72
-rw-r--r--test/Transforms/NaCl/expand-varargs-struct.ll18
2 files changed, 90 insertions, 0 deletions
diff --git a/test/Transforms/NaCl/expand-varargs-attrs.ll b/test/Transforms/NaCl/expand-varargs-attrs.ll
new file mode 100644
index 0000000000..f53a8106f0
--- /dev/null
+++ b/test/Transforms/NaCl/expand-varargs-attrs.ll
@@ -0,0 +1,72 @@
+; RUN: opt < %s -expand-varargs -S | FileCheck %s
+
+declare i32 @varargs_func(i32 %arg, ...)
+
+
+; Check that attributes such as "byval" are preserved on fixed arguments.
+
+%MyStruct = type { i64, i64 }
+
+define void @func_with_arg_attrs(%MyStruct* byval, ...) {
+ ret void
+}
+; CHECK: define void @func_with_arg_attrs(%MyStruct* byval, i8* %varargs) {
+
+
+declare void @take_struct_arg(%MyStruct* byval %s, ...)
+
+define void @call_with_arg_attrs(%MyStruct* %s) {
+ call void (%MyStruct*, ...)* @take_struct_arg(%MyStruct* byval %s)
+ ret void
+}
+; CHECK: define void @call_with_arg_attrs(%MyStruct* %s) {
+; CHECK: call void %vararg_func(%MyStruct* byval %s, {}* undef)
+
+
+; The "byval" attribute here should be dropped.
+define i32 @pass_struct_via_vararg1(%MyStruct* %s) {
+ %result = call i32 (i32, ...)* @varargs_func(i32 111, %MyStruct* byval %s)
+ ret i32 %result
+}
+; CHECK: define i32 @pass_struct_via_vararg1(%MyStruct* %s) {
+; CHECK: %result = call i32 %vararg_func(i32 111, %{{.*}}* %vararg_buffer)
+
+
+; The "byval" attribute here should be dropped.
+define i32 @pass_struct_via_vararg2(%MyStruct* %s) {
+ %result = call i32 (i32, ...)* @varargs_func(i32 111, i32 2, %MyStruct* byval %s)
+ ret i32 %result
+}
+; CHECK: define i32 @pass_struct_via_vararg2(%MyStruct* %s) {
+; CHECK: %result = call i32 %vararg_func(i32 111, %{{.*}}* %vararg_buffer)
+
+
+; Check that return attributes such as "signext" are preserved.
+define i32 @call_with_return_attr() {
+ %result = call signext i32 (i32, ...)* @varargs_func(i32 111, i64 222)
+ ret i32 %result
+}
+; CHECK: define i32 @call_with_return_attr() {
+; CHECK: %result = call signext i32 %vararg_func(i32 111
+
+
+; Check that the "readonly" function attribute is preserved.
+define i32 @call_readonly() {
+ %result = call i32 (i32, ...)* @varargs_func(i32 111, i64 222) readonly
+ ret i32 %result
+}
+; CHECK: define i32 @call_readonly() {
+; CHECK: %result = call i32 %vararg_func(i32 111, {{.*}}) #1
+
+
+; Check that the "tail" attribute gets removed, because the callee
+; reads space alloca'd by the caller.
+define i32 @tail_call() {
+ %result = tail call i32 (i32, ...)* @varargs_func(i32 111, i64 222)
+ ret i32 %result
+}
+; CHECK: define i32 @tail_call() {
+; CHECK: %result = call i32 %vararg_func(i32 111
+
+
+; CHECK: attributes #1 = { readonly }
diff --git a/test/Transforms/NaCl/expand-varargs-struct.ll b/test/Transforms/NaCl/expand-varargs-struct.ll
new file mode 100644
index 0000000000..f147d7006f
--- /dev/null
+++ b/test/Transforms/NaCl/expand-varargs-struct.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -expand-varargs -S | FileCheck %s
+
+declare i32 @varargs_func(i32 %arg, ...)
+
+
+%MyStruct = type { i64, i64 }
+
+; CHECK: %vararg_call = type <{ i64, %MyStruct }>
+
+; Test passing a struct by value.
+define i32 @varargs_call_struct(%MyStruct* %ptr) {
+ %result = call i32 (i32, ...)* @varargs_func(i32 111, i64 222, %MyStruct* byval %ptr)
+ ret i32 %result
+}
+; CHECK: define i32 @varargs_call_struct(%MyStruct* %ptr) {
+; CHECK: %vararg_struct_copy = load %MyStruct* %ptr
+; CHECK: %vararg_ptr1 = getelementptr %vararg_call* %vararg_buffer, i32 0, i32 1
+; CHECK: store %MyStruct %vararg_struct_copy, %MyStruct* %vararg_ptr1