| 1 | // RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm \ |
| 2 | // RUN: -target-cpu pwr9 -target-feature +float128 -o - %s | FileCheck %s |
| 3 | |
| 4 | // Test homogeneous fp128 aggregate passing and returning. |
| 5 | |
| 6 | struct fp1 { __float128 f[1]; }; |
| 7 | struct fp2 { __float128 f[2]; }; |
| 8 | struct fp3 { __float128 f[3]; }; |
| 9 | struct fp4 { __float128 f[4]; }; |
| 10 | struct fp5 { __float128 f[5]; }; |
| 11 | struct fp6 { __float128 f[6]; }; |
| 12 | struct fp7 { __float128 f[7]; }; |
| 13 | struct fp8 { __float128 f[8]; }; |
| 14 | struct fp9 { __float128 f[9]; }; |
| 15 | |
| 16 | struct fpab { __float128 a; __float128 b; }; |
| 17 | struct fpabc { __float128 a; __float128 b; __float128 c; }; |
| 18 | |
| 19 | struct fp2a2b { __float128 a[2]; __float128 b[2]; }; |
| 20 | |
| 21 | // CHECK: define [1 x fp128] @func_f1(fp128 inreg %x.coerce) |
| 22 | struct fp1 func_f1(struct fp1 x) { return x; } |
| 23 | |
| 24 | // CHECK: define [2 x fp128] @func_f2([2 x fp128] %x.coerce) |
| 25 | struct fp2 func_f2(struct fp2 x) { return x; } |
| 26 | |
| 27 | // CHECK: define [3 x fp128] @func_f3([3 x fp128] %x.coerce) |
| 28 | struct fp3 func_f3(struct fp3 x) { return x; } |
| 29 | |
| 30 | // CHECK: define [4 x fp128] @func_f4([4 x fp128] %x.coerce) |
| 31 | struct fp4 func_f4(struct fp4 x) { return x; } |
| 32 | |
| 33 | // CHECK: define [5 x fp128] @func_f5([5 x fp128] %x.coerce) |
| 34 | struct fp5 func_f5(struct fp5 x) { return x; } |
| 35 | |
| 36 | // CHECK: define [6 x fp128] @func_f6([6 x fp128] %x.coerce) |
| 37 | struct fp6 func_f6(struct fp6 x) { return x; } |
| 38 | |
| 39 | // CHECK: define [7 x fp128] @func_f7([7 x fp128] %x.coerce) |
| 40 | struct fp7 func_f7(struct fp7 x) { return x; } |
| 41 | |
| 42 | // CHECK: define [8 x fp128] @func_f8([8 x fp128] %x.coerce) |
| 43 | struct fp8 func_f8(struct fp8 x) { return x; } |
| 44 | |
| 45 | // CHECK: define void @func_f9(%struct.fp9* noalias sret %agg.result, %struct.fp9* byval align 16 %x) |
| 46 | struct fp9 func_f9(struct fp9 x) { return x; } |
| 47 | |
| 48 | // CHECK: define [2 x fp128] @func_fab([2 x fp128] %x.coerce) |
| 49 | struct fpab func_fab(struct fpab x) { return x; } |
| 50 | |
| 51 | // CHECK: define [3 x fp128] @func_fabc([3 x fp128] %x.coerce) |
| 52 | struct fpabc func_fabc(struct fpabc x) { return x; } |
| 53 | |
| 54 | // CHECK: define [4 x fp128] @func_f2a2b([4 x fp128] %x.coerce) |
| 55 | struct fp2a2b func_f2a2b(struct fp2a2b x) { return x; } |
| 56 | |
| 57 | // CHECK-LABEL: @call_fp1 |
| 58 | // CHECK: %[[TMP:[^ ]+]] = load fp128, fp128* getelementptr inbounds (%struct.fp1, %struct.fp1* @global_f1, i32 0, i32 0, i32 0), align 16 |
| 59 | // CHECK: call [1 x fp128] @func_f1(fp128 inreg %[[TMP]]) |
| 60 | struct fp1 global_f1; |
| 61 | void call_fp1(void) { global_f1 = func_f1(global_f1); } |
| 62 | |
| 63 | // CHECK-LABEL: @call_fp2 |
| 64 | // CHECK: %[[TMP:[^ ]+]] = load [2 x fp128], [2 x fp128]* getelementptr inbounds (%struct.fp2, %struct.fp2* @global_f2, i32 0, i32 0), align 16 |
| 65 | // CHECK: call [2 x fp128] @func_f2([2 x fp128] %[[TMP]]) |
| 66 | struct fp2 global_f2; |
| 67 | void call_fp2(void) { global_f2 = func_f2(global_f2); } |
| 68 | |
| 69 | // CHECK-LABEL: @call_fp3 |
| 70 | // CHECK: %[[TMP:[^ ]+]] = load [3 x fp128], [3 x fp128]* getelementptr inbounds (%struct.fp3, %struct.fp3* @global_f3, i32 0, i32 0), align 16 |
| 71 | // CHECK: call [3 x fp128] @func_f3([3 x fp128] %[[TMP]]) |
| 72 | struct fp3 global_f3; |
| 73 | void call_fp3(void) { global_f3 = func_f3(global_f3); } |
| 74 | |
| 75 | // CHECK-LABEL: @call_fp4 |
| 76 | // CHECK: %[[TMP:[^ ]+]] = load [4 x fp128], [4 x fp128]* getelementptr inbounds (%struct.fp4, %struct.fp4* @global_f4, i32 0, i32 0), align 16 |
| 77 | // CHECK: call [4 x fp128] @func_f4([4 x fp128] %[[TMP]]) |
| 78 | struct fp4 global_f4; |
| 79 | void call_fp4(void) { global_f4 = func_f4(global_f4); } |
| 80 | |
| 81 | // CHECK-LABEL: @call_fp5 |
| 82 | // CHECK: %[[TMP:[^ ]+]] = load [5 x fp128], [5 x fp128]* getelementptr inbounds (%struct.fp5, %struct.fp5* @global_f5, i32 0, i32 0), align 16 |
| 83 | // CHECK: call [5 x fp128] @func_f5([5 x fp128] %[[TMP]]) |
| 84 | struct fp5 global_f5; |
| 85 | void call_fp5(void) { global_f5 = func_f5(global_f5); } |
| 86 | |
| 87 | // CHECK-LABEL: @call_fp6 |
| 88 | // CHECK: %[[TMP:[^ ]+]] = load [6 x fp128], [6 x fp128]* getelementptr inbounds (%struct.fp6, %struct.fp6* @global_f6, i32 0, i32 0), align 16 |
| 89 | // CHECK: call [6 x fp128] @func_f6([6 x fp128] %[[TMP]]) |
| 90 | struct fp6 global_f6; |
| 91 | void call_fp6(void) { global_f6 = func_f6(global_f6); } |
| 92 | |
| 93 | // CHECK-LABEL: @call_fp7 |
| 94 | // CHECK: %[[TMP:[^ ]+]] = load [7 x fp128], [7 x fp128]* getelementptr inbounds (%struct.fp7, %struct.fp7* @global_f7, i32 0, i32 0), align 16 |
| 95 | // CHECK: call [7 x fp128] @func_f7([7 x fp128] %[[TMP]]) |
| 96 | struct fp7 global_f7; |
| 97 | void call_fp7(void) { global_f7 = func_f7(global_f7); } |
| 98 | |
| 99 | // CHECK-LABEL: @call_fp8 |
| 100 | // CHECK: %[[TMP:[^ ]+]] = load [8 x fp128], [8 x fp128]* getelementptr inbounds (%struct.fp8, %struct.fp8* @global_f8, i32 0, i32 0), align 16 |
| 101 | // CHECK: call [8 x fp128] @func_f8([8 x fp128] %[[TMP]]) |
| 102 | struct fp8 global_f8; |
| 103 | void call_fp8(void) { global_f8 = func_f8(global_f8); } |
| 104 | |
| 105 | // CHECK-LABEL: @call_fp9 |
| 106 | // CHECK: %[[TMP1:[^ ]+]] = alloca %struct.fp9, align 16 |
| 107 | // CHECK: call void @func_f9(%struct.fp9* sret %[[TMP2:[^ ]+]], %struct.fp9* byval align 16 @global_f9 |
| 108 | // CHECK: %[[TMP3:[^ ]+]] = bitcast %struct.fp9* %[[TMP2]] to i8* |
| 109 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 bitcast (%struct.fp9* @global_f9 to i8*), i8* align 16 %[[TMP3]], i64 144, i1 false |
| 110 | // CHECK: ret void |
| 111 | struct fp9 global_f9; |
| 112 | void call_fp9(void) { global_f9 = func_f9(global_f9); } |
| 113 | |
| 114 | // CHECK-LABEL: @call_fpab |
| 115 | // CHECK: %[[TMP:[^ ]+]] = load [2 x fp128], [2 x fp128]* bitcast (%struct.fpab* @global_fab to [2 x fp128]*) |
| 116 | // CHECK: call [2 x fp128] @func_fab([2 x fp128] %[[TMP]]) |
| 117 | struct fpab global_fab; |
| 118 | void call_fpab(void) { global_fab = func_fab(global_fab); } |
| 119 | |
| 120 | // CHECK-LABEL: @call_fpabc |
| 121 | // CHECK: %[[TMP:[^ ]+]] = load [3 x fp128], [3 x fp128]* bitcast (%struct.fpabc* @global_fabc to [3 x fp128]*) |
| 122 | // CHECK: call [3 x fp128] @func_fabc([3 x fp128] %[[TMP]]) |
| 123 | struct fpabc global_fabc; |
| 124 | void call_fpabc(void) { global_fabc = func_fabc(global_fabc); } |
| 125 | |