diff options
| author | Mark Seaborn <mseaborn@chromium.org> | 2013-03-27 13:28:15 -0700 |
|---|---|---|
| committer | Mark Seaborn <mseaborn@chromium.org> | 2013-03-27 13:28:15 -0700 |
| commit | 66afec2f1d3ebc1909f4acfea836cc4e0332dbce (patch) | |
| tree | df9b4ab110a4d1921c58800d0a656194f2241f1a /test/Transforms/NaCl | |
| parent | 9c7984ea3134c4f7f425bb2e01a5ee8540829fd9 (diff) | |
PNaCl: Fix ExpandVarArgs to handle "byval" struct arguments properly
* Ensure that the "byval" attribute is preserved for the fixed
arguments. Before, it was stripped off from function calls but
left in for function definitions, which broke passing struct
arguments (which PNaCl Clang generates as "byval").
* Ensure that function and return attributes are preserved too.
* Handle "byval" variable arguments in calls too by dereferencing the
pointer. These are not yet usable with PNaCl Clang, which does not
allow va_arg on structs (see
https://code.google.com/p/nativeclient/issues/detail?id=2381), but
we might as well make this pass ready to handle this.
BUG=https://code.google.com/p/nativeclient/issues/detail?id=3338
TEST=test/Transforms/NaCl/expand-varargs*.ll
Review URL: https://codereview.chromium.org/13100002
Diffstat (limited to 'test/Transforms/NaCl')
| -rw-r--r-- | test/Transforms/NaCl/expand-varargs-attrs.ll | 72 | ||||
| -rw-r--r-- | test/Transforms/NaCl/expand-varargs-struct.ll | 18 |
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 |
