Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 ; RUN: opt < %s -expand-varargs -S | FileCheck %s | 1 ; RUN: opt < %s -expand-varargs -S | FileCheck %s |
| 2 | 2 |
| 3 %va_list = type i8* | 3 %va_list = type i8* |
| 4 | 4 |
| 5 declare void @llvm.va_start(i8*) | 5 declare void @llvm.va_start(i8*) |
| 6 declare void @llvm.va_end(i8*) | 6 declare void @llvm.va_end(i8*) |
| 7 declare void @llvm.va_copy(i8*, i8*) | 7 declare void @llvm.va_copy(i8*, i8*) |
| 8 | 8 |
| 9 declare i32 @outside_func(i32 %arg, %va_list* %args) | 9 declare i32 @outside_func(i32 %arg, %va_list* %args) |
| 10 | 10 |
| 11 | 11 |
| 12 ; Produced by the expansion of @varargs_call1(): | 12 ; Produced by the expansion of @varargs_call1(): |
| 13 ; CHECK: %vararg_call = type <{ i64, i32 }> | 13 ; CHECK: %vararg_call = type <{ i64, i32 }> |
| 14 | 14 |
| 15 ; Produced by the expansion of @call_with_zero_varargs(). | 15 ; Produced by the expansion of @call_with_zero_varargs(). |
| 16 ; We have a dummy field to deal with buggy programs: | 16 ; We have a dummy field to deal with buggy programs: |
| 17 ; CHECK: %vararg_call.0 = type <{ i32 }> | 17 ; CHECK: %vararg_call.0 = type <{ i32 }> |
| 18 | 18 |
| 19 | 19 |
| 20 define i32 @varargs_func(i32 %arg, ...) { | 20 define i32 @varargs_func(i32 %arg, ...) { |
| 21 %arglist_alloc = alloca %va_list | 21 %arglist_alloc = alloca %va_list |
| 22 %arglist = bitcast %va_list* %arglist_alloc to i8* | 22 %arglist = bitcast %va_list* %arglist_alloc to i8* |
| 23 | 23 |
| 24 call void @llvm.va_start(i8* %arglist) | 24 call void @llvm.va_start(i8* %arglist) |
| 25 %result = call i32 @outside_func(i32 %arg, %va_list* %arglist_alloc) | 25 %result = call i32 @outside_func(i32 %arg, %va_list* %arglist_alloc) |
| 26 call void @llvm.va_end(i8* %arglist) | 26 call void @llvm.va_end(i8* %arglist) |
| 27 ret i32 %result | 27 ret i32 %result |
| 28 } | 28 } |
| 29 ; CHECK: define i32 @varargs_func(i32 %arg, i8* %varargs) { | 29 ; CHECK: define i32 @varargs_func(i32 %arg, i8* %varargs) { |
|
jvoung (off chromium)
2013/04/26 16:43:09
Same question about noalias for the new %varargs p
Mark Seaborn
2013/04/26 16:52:58
Done.
| |
| 30 ; CHECK-NEXT: %arglist_alloc = alloca i8* | 30 ; CHECK-NEXT: %arglist_alloc = alloca i8* |
| 31 ; CHECK-NEXT: %arglist = bitcast i8** %arglist_alloc to i8* | 31 ; CHECK-NEXT: %arglist = bitcast i8** %arglist_alloc to i8* |
| 32 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i8** | 32 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i8** |
| 33 ; CHECK-NEXT: store i8* %varargs, i8** %arglist1 | 33 ; CHECK-NEXT: store i8* %varargs, i8** %arglist1 |
| 34 ; CHECK-NEXT: %result = call i32 @outside_func(i32 %arg, i8** %arglist_alloc) | 34 ; CHECK-NEXT: %result = call i32 @outside_func(i32 %arg, i8** %arglist_alloc) |
| 35 ; CHECK-NEXT: ret i32 %result | 35 ; CHECK-NEXT: ret i32 %result |
| 36 | 36 |
| 37 | 37 |
| 38 define i32 @varargs_call1() { | 38 define i32 @varargs_call1() { |
| 39 %result = call i32 (i32, ...)* @varargs_func(i32 111, i64 222, i32 333) | 39 %result = call i32 (i32, ...)* @varargs_func(i32 111, i64 222, i32 333) |
| 40 ret i32 %result | 40 ret i32 %result |
| 41 } | 41 } |
| 42 ; CHECK: define i32 @varargs_call1() { | 42 ; CHECK: define i32 @varargs_call1() { |
| 43 ; CHECK-NEXT: %vararg_buffer = alloca %vararg_call | 43 ; CHECK-NEXT: %vararg_buffer = alloca %vararg_call |
| 44 ; CHECK-NEXT: %vararg_lifetime_bitcast = bitcast %vararg_call* %vararg_buffer to i8* | 44 ; CHECK-NEXT: %vararg_lifetime_bitcast = bitcast %vararg_call* %vararg_buffer to i8* |
| 45 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 12, i8* %vararg_lifetime_bitcas t) | 45 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 12, i8* %vararg_lifetime_bitcas t) |
| 46 ; CHECK-NEXT: %vararg_ptr = getelementptr %vararg_call* %vararg_buffer, i32 0, i 32 0 | 46 ; CHECK-NEXT: %vararg_ptr = getelementptr %vararg_call* %vararg_buffer, i32 0, i 32 0 |
| 47 ; CHECK-NEXT: store i64 222, i64* %vararg_ptr | 47 ; CHECK-NEXT: store i64 222, i64* %vararg_ptr |
| 48 ; CHECK-NEXT: %vararg_ptr1 = getelementptr %vararg_call* %vararg_buffer, i32 0, i32 1 | 48 ; CHECK-NEXT: %vararg_ptr1 = getelementptr %vararg_call* %vararg_buffer, i32 0, i32 1 |
| 49 ; CHECK-NEXT: store i32 333, i32* %vararg_ptr1 | 49 ; CHECK-NEXT: store i32 333, i32* %vararg_ptr1 |
| 50 ; CHECK-NEXT: %vararg_func = bitcast i32 (i32, ...)* bitcast (i32 (i32, i8*)* @v arargs_func to i32 (i32, ...)*) to i32 (i32, %vararg_call*)* | 50 ; CHECK-NEXT: %vararg_func = bitcast i32 (i32, ...)* bitcast (i32 (i32, i8*)* @v arargs_func to i32 (i32, ...)*) to i32 (i32, %vararg_call*)* |
| 51 ; CHECK-NEXT: %result = call i32 %vararg_func(i32 111, %vararg_call* %vararg_buf fer) | 51 ; CHECK-NEXT: %result = call i32 %vararg_func(i32 111, %vararg_call* noalias %va rarg_buffer) |
| 52 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 12, i8* %vararg_lifetime_bitcast) | 52 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 12, i8* %vararg_lifetime_bitcast) |
| 53 ; CHECK-NEXT: ret i32 %result | 53 ; CHECK-NEXT: ret i32 %result |
| 54 | 54 |
| 55 | 55 |
| 56 ; Check that the pass works when there are no variable arguments. | 56 ; Check that the pass works when there are no variable arguments. |
| 57 define i32 @call_with_zero_varargs() { | 57 define i32 @call_with_zero_varargs() { |
| 58 %result = call i32 (i32, ...)* @varargs_func(i32 111) | 58 %result = call i32 (i32, ...)* @varargs_func(i32 111) |
| 59 ret i32 %result | 59 ret i32 %result |
| 60 } | 60 } |
| 61 ; CHECK: define i32 @call_with_zero_varargs() { | 61 ; CHECK: define i32 @call_with_zero_varargs() { |
| 62 ; CHECK-NEXT: %vararg_buffer = alloca %vararg_call.0 | 62 ; CHECK-NEXT: %vararg_buffer = alloca %vararg_call.0 |
| 63 ; CHECK: %vararg_func = bitcast i32 (i32, ...)* bitcast (i32 (i32, i8*)* @vararg s_func to i32 (i32, ...)*) to i32 (i32, %vararg_call.0*)* | 63 ; CHECK: %vararg_func = bitcast i32 (i32, ...)* bitcast (i32 (i32, i8*)* @vararg s_func to i32 (i32, ...)*) to i32 (i32, %vararg_call.0*)* |
| 64 ; CHECK-NEXT: %result = call i32 %vararg_func(i32 111, %vararg_call.0* %vararg_b uffer) | 64 ; CHECK-NEXT: %result = call i32 %vararg_func(i32 111, %vararg_call.0* noalias % vararg_buffer) |
| 65 | 65 |
| 66 | 66 |
| 67 ; Check that "invoke" instructions are expanded out too. | 67 ; Check that "invoke" instructions are expanded out too. |
| 68 define i32 @varargs_invoke() { | 68 define i32 @varargs_invoke() { |
| 69 %result = invoke i32 (i32, ...)* @varargs_func(i32 111, i64 222) | 69 %result = invoke i32 (i32, ...)* @varargs_func(i32 111, i64 222) |
| 70 to label %cont unwind label %lpad | 70 to label %cont unwind label %lpad |
| 71 cont: | 71 cont: |
| 72 ret i32 %result | 72 ret i32 %result |
| 73 lpad: | 73 lpad: |
| 74 %lp = landingpad { i8*, i32 } personality i8* null cleanup | 74 %lp = landingpad { i8*, i32 } personality i8* null cleanup |
| 75 ret i32 0 | 75 ret i32 0 |
| 76 } | 76 } |
| 77 ; CHECK: @varargs_invoke | 77 ; CHECK: @varargs_invoke |
| 78 ; CHECK: %result = invoke i32 %vararg_func(i32 111, %vararg_call.1* %vararg_buff er) | 78 ; CHECK: %result = invoke i32 %vararg_func(i32 111, %vararg_call.1* noalias %var arg_buffer) |
| 79 ; CHECK-NEXT: to label %cont unwind label %lpad | 79 ; CHECK-NEXT: to label %cont unwind label %lpad |
| 80 ; CHECK: cont: | 80 ; CHECK: cont: |
| 81 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) | 81 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) |
| 82 ; CHECK: lpad: | 82 ; CHECK: lpad: |
| 83 ; CHECK: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) | 83 ; CHECK: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) |
| 84 | 84 |
| 85 | 85 |
| 86 define void @varargs_multiple_calls() { | 86 define void @varargs_multiple_calls() { |
| 87 %call1 = call i32 (i32, ...)* @varargs_func(i32 11, i64 22, i32 33) | 87 %call1 = call i32 (i32, ...)* @varargs_func(i32 11, i64 22, i32 33) |
| 88 %call2 = call i32 (i32, ...)* @varargs_func(i32 44, i64 55, i32 66) | 88 %call2 = call i32 (i32, ...)* @varargs_func(i32 44, i64 55, i32 66) |
| 89 ret void | 89 ret void |
| 90 } | 90 } |
| 91 ; CHECK: @varargs_multiple_calls() | 91 ; CHECK: @varargs_multiple_calls() |
| 92 ; The added allocas should appear at the start of the function. | 92 ; The added allocas should appear at the start of the function. |
| 93 ; CHECK: %vararg_buffer{{.*}} = alloca %vararg_call{{.*}} | 93 ; CHECK: %vararg_buffer{{.*}} = alloca %vararg_call{{.*}} |
| 94 ; CHECK: %vararg_buffer{{.*}} = alloca %vararg_call{{.*}} | 94 ; CHECK: %vararg_buffer{{.*}} = alloca %vararg_call{{.*}} |
| 95 ; CHECK: %call1 = call i32 %vararg_func{{.*}}(i32 11, %vararg_call{{.*}}* %varar g_buffer{{.*}}) | 95 ; CHECK: %call1 = call i32 %vararg_func{{.*}}(i32 11, %vararg_call{{.*}}* noalia s %vararg_buffer{{.*}}) |
| 96 ; CHECK: %call2 = call i32 %vararg_func{{.*}}(i32 44, %vararg_call{{.*}}* %varar g_buffer{{.*}}) | 96 ; CHECK: %call2 = call i32 %vararg_func{{.*}}(i32 44, %vararg_call{{.*}}* noalia s %vararg_buffer{{.*}}) |
| 97 | 97 |
| 98 | 98 |
| 99 define i32 @va_arg_i32(i8* %arglist) { | 99 define i32 @va_arg_i32(i8* %arglist) { |
| 100 %result = va_arg i8* %arglist, i32 | 100 %result = va_arg i8* %arglist, i32 |
| 101 ret i32 %result | 101 ret i32 %result |
| 102 } | 102 } |
| 103 ; CHECK: define i32 @va_arg_i32(i8* %arglist) { | 103 ; CHECK: define i32 @va_arg_i32(i8* %arglist) { |
| 104 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i32** | 104 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i32** |
| 105 ; CHECK-NEXT: %arglist_current = load i32** %arglist1 | 105 ; CHECK-NEXT: %arglist_current = load i32** %arglist1 |
| 106 ; CHECK-NEXT: %result = load i32* %arglist_current | 106 ; CHECK-NEXT: %result = load i32* %arglist_current |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 125 define void @do_va_copy(i8* %dest, i8* %src) { | 125 define void @do_va_copy(i8* %dest, i8* %src) { |
| 126 call void @llvm.va_copy(i8* %dest, i8* %src) | 126 call void @llvm.va_copy(i8* %dest, i8* %src) |
| 127 ret void | 127 ret void |
| 128 } | 128 } |
| 129 ; CHECK: define void @do_va_copy(i8* %dest, i8* %src) { | 129 ; CHECK: define void @do_va_copy(i8* %dest, i8* %src) { |
| 130 ; CHECK-NEXT: %vacopy_src = bitcast i8* %src to i8** | 130 ; CHECK-NEXT: %vacopy_src = bitcast i8* %src to i8** |
| 131 ; CHECK-NEXT: %vacopy_dest = bitcast i8* %dest to i8** | 131 ; CHECK-NEXT: %vacopy_dest = bitcast i8* %dest to i8** |
| 132 ; CHECK-NEXT: %vacopy_currentptr = load i8** %vacopy_src | 132 ; CHECK-NEXT: %vacopy_currentptr = load i8** %vacopy_src |
| 133 ; CHECK-NEXT: store i8* %vacopy_currentptr, i8** %vacopy_dest | 133 ; CHECK-NEXT: store i8* %vacopy_currentptr, i8** %vacopy_dest |
| 134 ; CHECK-NEXT: ret void | 134 ; CHECK-NEXT: ret void |
| OLD | NEW |