| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 1 | ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi | FileCheck %s |
| 2 | ; Test that we correctly use registers and align elements when using va_arg |
| 3 | |
| 4 | %struct_t = type { double, double, double } |
| 5 | @static_val = constant %struct_t { double 1.0, double 2.0, double 3.0 } |
| 6 | |
| 7 | declare void @llvm.va_start(i8*) nounwind |
| 8 | declare void @llvm.va_end(i8*) nounwind |
| 9 | |
| Stephen Lin | f799e3f | 2013-07-13 20:38:47 +0000 | [diff] [blame] | 10 | ; CHECK-LABEL: test_byval_8_bytes_alignment: |
| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 11 | define void @test_byval_8_bytes_alignment(i32 %i, ...) { |
| 12 | entry: |
| 13 | ; CHECK: stm r0, {r1, r2, r3} |
| 14 | %g = alloca i8* |
| 15 | %g1 = bitcast i8** %g to i8* |
| 16 | call void @llvm.va_start(i8* %g1) |
| 17 | |
| 18 | ; CHECK: add [[REG:(r[0-9]+)|(lr)]], {{(r[0-9]+)|(lr)}}, #7 |
| 19 | ; CHECK: bfc [[REG]], #0, #3 |
| 20 | %0 = va_arg i8** %g, double |
| 21 | call void @llvm.va_end(i8* %g1) |
| Stepan Dyatkovskiy | e58df62 | 2013-04-04 16:11:18 +0000 | [diff] [blame] | 22 | |
| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 23 | ret void |
| 24 | } |
| 25 | |
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 26 | ; CHECK-LABEL: main: |
| Quentin Colombet | 663150f | 2013-06-20 22:51:44 +0000 | [diff] [blame] | 27 | ; CHECK: movw [[BASE:r[0-9]+]], :lower16:static_val |
| 28 | ; CHECK: movt [[BASE]], :upper16:static_val |
| 29 | ; ldm is not formed when the coalescer failed to coalesce everything. |
| Andrew Trick | 8485257 | 2013-07-25 18:35:14 +0000 | [diff] [blame] | 30 | ; CHECK: ldrd r2, [[TMP:r[0-9]+]], {{\[}}[[BASE]]{{\]}} |
| Quentin Colombet | 663150f | 2013-06-20 22:51:44 +0000 | [diff] [blame] | 31 | ; CHECK: movw r0, #555 |
| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 32 | define i32 @main() { |
| 33 | entry: |
| 34 | call void (i32, ...)* @test_byval_8_bytes_alignment(i32 555, %struct_t* byval @static_val) |
| 35 | ret i32 0 |
| 36 | } |
| 37 | |
| 38 | declare void @f(double); |
| 39 | |
| Stephen Lin | f799e3f | 2013-07-13 20:38:47 +0000 | [diff] [blame] | 40 | ; CHECK-LABEL: test_byval_8_bytes_alignment_fixed_arg: |
| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 41 | ; CHECK-NOT: str r1 |
| 42 | ; CHECK: str r3, [sp, #12] |
| 43 | ; CHECK: str r2, [sp, #8] |
| 44 | ; CHECK-NOT: str r1 |
| 45 | define void @test_byval_8_bytes_alignment_fixed_arg(i32 %n1, %struct_t* byval %val) nounwind { |
| 46 | entry: |
| David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 47 | %a = getelementptr inbounds %struct_t, %struct_t* %val, i32 0, i32 0 |
| David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame^] | 48 | %0 = load double, double* %a |
| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 49 | call void (double)* @f(double %0) |
| 50 | ret void |
| 51 | } |
| 52 | |
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 53 | ; CHECK-LABEL: main_fixed_arg: |
| Quentin Colombet | 663150f | 2013-06-20 22:51:44 +0000 | [diff] [blame] | 54 | ; CHECK: movw [[BASE:r[0-9]+]], :lower16:static_val |
| 55 | ; CHECK: movt [[BASE]], :upper16:static_val |
| 56 | ; ldm is not formed when the coalescer failed to coalesce everything. |
| Andrew Trick | 8485257 | 2013-07-25 18:35:14 +0000 | [diff] [blame] | 57 | ; CHECK: ldrd r2, [[TMP:r[0-9]+]], {{\[}}[[BASE]]{{\]}} |
| Quentin Colombet | 663150f | 2013-06-20 22:51:44 +0000 | [diff] [blame] | 58 | ; CHECK: movw r0, #555 |
| Stepan Dyatkovskiy | e59a920 | 2012-10-16 07:16:47 +0000 | [diff] [blame] | 59 | define i32 @main_fixed_arg() { |
| 60 | entry: |
| 61 | call void (i32, %struct_t*)* @test_byval_8_bytes_alignment_fixed_arg(i32 555, %struct_t* byval @static_val) |
| 62 | ret i32 0 |
| 63 | } |