OLD | NEW |
1 ; RUN: opt < %s -expand-varargs -S | FileCheck %s | 1 ; RUN: opt < %s -expand-varargs -S | FileCheck %s |
2 | 2 |
3 declare i32 @varargs_func(i32 %arg, ...) | 3 declare i32 @varargs_func(i32 %arg, ...) |
4 | 4 |
5 | 5 |
6 ; Check that attributes such as "byval" are preserved on fixed arguments. | 6 ; Check that attributes such as "byval" are preserved on fixed arguments. |
7 | 7 |
8 %MyStruct = type { i64, i64 } | 8 %MyStruct = type { i64, i64 } |
9 | 9 |
10 define void @func_with_arg_attrs(%MyStruct* byval, ...) { | 10 define void @func_with_arg_attrs(%MyStruct* byval, ...) { |
11 ret void | 11 ret void |
12 } | 12 } |
13 ; CHECK-LABEL: define void @func_with_arg_attrs(%MyStruct* byval, i8* noalias %v
arargs) { | 13 ; CHECK-LABEL: define void @func_with_arg_attrs(%MyStruct* byval, i8* noalias %v
arargs) { |
14 | 14 |
15 | 15 |
16 declare void @take_struct_arg(%MyStruct* byval %s, ...) | 16 declare void @take_struct_arg(%MyStruct* byval %s, ...) |
17 | 17 |
18 define void @call_with_arg_attrs(%MyStruct* %s) { | 18 define void @call_with_arg_attrs(%MyStruct* %s) { |
19 call void (%MyStruct*, ...)* @take_struct_arg(%MyStruct* byval %s) | 19 call void (%MyStruct*, ...) @take_struct_arg(%MyStruct* byval %s) |
20 ret void | 20 ret void |
21 } | 21 } |
22 ; CHECK-LABEL: @call_with_arg_attrs( | 22 ; CHECK-LABEL: @call_with_arg_attrs( |
23 ; CHECK: call void bitcast (void (%MyStruct*, i8*)* @take_struct_arg to void (%M
yStruct*, { i32 }*)*)(%MyStruct* byval %s, { i32 }* %vararg_buffer) | 23 ; CHECK: call void bitcast (void (%MyStruct*, i8*)* @take_struct_arg to void (%M
yStruct*, { i32 }*)*)(%MyStruct* byval %s, { i32 }* %vararg_buffer) |
24 | 24 |
25 | 25 |
26 ; The "byval" attribute here should be dropped. | 26 ; The "byval" attribute here should be dropped. |
27 define i32 @pass_struct_via_vararg1(%MyStruct* %s) { | 27 define i32 @pass_struct_via_vararg1(%MyStruct* %s) { |
28 %result = call i32 (i32, ...)* @varargs_func(i32 111, %MyStruct* byval %s) | 28 %result = call i32 (i32, ...) @varargs_func(i32 111, %MyStruct* byval %s) |
29 ret i32 %result | 29 ret i32 %result |
30 } | 30 } |
31 ; CHECK-LABEL: @pass_struct_via_vararg1( | 31 ; CHECK-LABEL: @pass_struct_via_vararg1( |
32 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ %MyStruct }*)*)(i32 111, { %MyStruct }* %vararg_buffer) | 32 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ %MyStruct }*)*)(i32 111, { %MyStruct }* %vararg_buffer) |
33 | 33 |
34 | 34 |
35 ; The "byval" attribute here should be dropped. | 35 ; The "byval" attribute here should be dropped. |
36 define i32 @pass_struct_via_vararg2(%MyStruct* %s) { | 36 define i32 @pass_struct_via_vararg2(%MyStruct* %s) { |
37 %result = call i32 (i32, ...)* @varargs_func(i32 111, i32 2, %MyStruct* byval
%s) | 37 %result = call i32 (i32, ...) @varargs_func(i32 111, i32 2, %MyStruct* byval %
s) |
38 ret i32 %result | 38 ret i32 %result |
39 } | 39 } |
40 ; CHECK-LABEL: @pass_struct_via_vararg2( | 40 ; CHECK-LABEL: @pass_struct_via_vararg2( |
41 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ i32, %MyStruct }*)*)(i32 111, { i32, %MyStruct }* %vararg_buffer) | 41 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ i32, %MyStruct }*)*)(i32 111, { i32, %MyStruct }* %vararg_buffer) |
42 | 42 |
43 | 43 |
44 ; Check that return attributes such as "signext" are preserved. | 44 ; Check that return attributes such as "signext" are preserved. |
45 define i32 @call_with_return_attr() { | 45 define i32 @call_with_return_attr() { |
46 %result = call signext i32 (i32, ...)* @varargs_func(i32 111, i64 222) | 46 %result = call signext i32 (i32, ...) @varargs_func(i32 111, i64 222) |
47 ret i32 %result | 47 ret i32 %result |
48 } | 48 } |
49 ; CHECK-LABEL: @call_with_return_attr( | 49 ; CHECK-LABEL: @call_with_return_attr( |
50 ; CHECK: %result = call signext i32 bitcast (i32 (i32, i8*)* @varargs_func to i3
2 (i32, { i64 }*)*)(i32 111, { i64 }* %vararg_buffer) | 50 ; CHECK: %result = call signext i32 bitcast (i32 (i32, i8*)* @varargs_func to i3
2 (i32, { i64 }*)*)(i32 111, { i64 }* %vararg_buffer) |
51 | 51 |
52 | 52 |
53 ; Check that the "readonly" function attribute is preserved. | 53 ; Check that the "readonly" function attribute is preserved. |
54 define i32 @call_readonly() { | 54 define i32 @call_readonly() { |
55 %result = call i32 (i32, ...)* @varargs_func(i32 111, i64 222) readonly | 55 %result = call i32 (i32, ...) @varargs_func(i32 111, i64 222) readonly |
56 ret i32 %result | 56 ret i32 %result |
57 } | 57 } |
58 ; CHECK-LABEL: @call_readonly( | 58 ; CHECK-LABEL: @call_readonly( |
59 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ i64 }*)*)(i32 111, { i64 }* %vararg_buffer) #1 | 59 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ i64 }*)*)(i32 111, { i64 }* %vararg_buffer) #1 |
60 | 60 |
61 | 61 |
62 ; Check that the "tail" attribute gets removed, because the callee | 62 ; Check that the "tail" attribute gets removed, because the callee |
63 ; reads space alloca'd by the caller. | 63 ; reads space alloca'd by the caller. |
64 define i32 @tail_call() { | 64 define i32 @tail_call() { |
65 %result = tail call i32 (i32, ...)* @varargs_func(i32 111, i64 222) | 65 %result = tail call i32 (i32, ...) @varargs_func(i32 111, i64 222) |
66 ret i32 %result | 66 ret i32 %result |
67 } | 67 } |
68 ; CHECK-LABEL: @tail_call( | 68 ; CHECK-LABEL: @tail_call( |
69 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ i64 }*)*)(i32 111, { i64 }* %vararg_buffer) | 69 ; CHECK: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32,
{ i64 }*)*)(i32 111, { i64 }* %vararg_buffer) |
70 | 70 |
71 | 71 |
72 ; CHECK: attributes #1 = { readonly } | 72 ; CHECK: attributes #1 = { readonly } |
OLD | NEW |