1 // RUN: %clang_cc1 -msoft-float -mfloat-abi soft -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-LE %s
2 // RUN: %clang_cc1 -msoft-float -mfloat-abi soft -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-BE %s
4 // Test float returns and params.
6 // CHECK: define{{.*}} float @func_p1(float noundef %x)
7 float func_p1(float x
) { return x
; }
9 // CHECK: define{{.*}} double @func_p2(double noundef %x)
10 double func_p2(double x
) { return x
; }
12 // CHECK: define{{.*}} ppc_fp128 @func_p3(ppc_fp128 noundef %x)
13 long double func_p3(long double x
) { return x
; }
15 // Test homogeneous float aggregate passing and returning.
17 struct f1
{ float f
[1]; };
18 struct f2
{ float f
[2]; };
19 struct f3
{ float f
[3]; };
20 struct f4
{ float f
[4]; };
21 struct f5
{ float f
[5]; };
22 struct f6
{ float f
[6]; };
23 struct f7
{ float f
[7]; };
24 struct f8
{ float f
[8]; };
25 struct f9
{ float f
[9]; };
27 struct fab
{ float a
; float b
; };
28 struct fabc
{ float a
; float b
; float c
; };
30 struct f2a2b
{ float a
[2]; float b
[2]; };
32 // CHECK-LE: define{{.*}} i32 @func_f1(float inreg %x.coerce)
33 // CHECK-BE: define{{.*}} void @func_f1(ptr noalias sret(%struct.f1) align 4 %agg.result, float inreg %x.coerce)
34 struct f1
func_f1(struct f1 x
) { return x
; }
36 // CHECK-LE: define{{.*}} i64 @func_f2(i64 %x.coerce)
37 // CHECK-BE: define{{.*}} void @func_f2(ptr noalias sret(%struct.f2) align 4 %agg.result, i64 %x.coerce)
38 struct f2
func_f2(struct f2 x
) { return x
; }
40 // CHECK-LE: define{{.*}} { i64, i64 } @func_f3([2 x i64] %x.coerce)
41 // CHECK-BE: define{{.*}} void @func_f3(ptr noalias sret(%struct.f3) align 4 %agg.result, [2 x i64] %x.coerce)
42 struct f3
func_f3(struct f3 x
) { return x
; }
44 // CHECK-LE: define{{.*}} { i64, i64 } @func_f4([2 x i64] %x.coerce)
45 // CHECK-BE: define{{.*}} void @func_f4(ptr noalias sret(%struct.f4) align 4 %agg.result, [2 x i64] %x.coerce)
46 struct f4
func_f4(struct f4 x
) { return x
; }
48 // CHECK: define{{.*}} void @func_f5(ptr noalias sret(%struct.f5) align 4 %agg.result, [3 x i64] %x.coerce)
49 struct f5
func_f5(struct f5 x
) { return x
; }
51 // CHECK: define{{.*}} void @func_f6(ptr noalias sret(%struct.f6) align 4 %agg.result, [3 x i64] %x.coerce)
52 struct f6
func_f6(struct f6 x
) { return x
; }
54 // CHECK: define{{.*}} void @func_f7(ptr noalias sret(%struct.f7) align 4 %agg.result, [4 x i64] %x.coerce)
55 struct f7
func_f7(struct f7 x
) { return x
; }
57 // CHECK: define{{.*}} void @func_f8(ptr noalias sret(%struct.f8) align 4 %agg.result, [4 x i64] %x.coerce)
58 struct f8
func_f8(struct f8 x
) { return x
; }
60 // CHECK: define{{.*}} void @func_f9(ptr noalias sret(%struct.f9) align 4 %agg.result, [5 x i64] %x.coerce)
61 struct f9
func_f9(struct f9 x
) { return x
; }
63 // CHECK-LE: define{{.*}} i64 @func_fab(i64 %x.coerce)
64 // CHECK-BE: define{{.*}} void @func_fab(ptr noalias sret(%struct.fab) align 4 %agg.result, i64 %x.coerce)
65 struct fab
func_fab(struct fab x
) { return x
; }
67 // CHECK-LE: define{{.*}} { i64, i64 } @func_fabc([2 x i64] %x.coerce)
68 // CHECK-BE: define{{.*}} void @func_fabc(ptr noalias sret(%struct.fabc) align 4 %agg.result, [2 x i64] %x.coerce)
69 struct fabc
func_fabc(struct fabc x
) { return x
; }
71 // CHECK-LE: define{{.*}} { i64, i64 } @func_f2a2b([2 x i64] %x.coerce)
72 // CHECK-BE: define{{.*}} void @func_f2a2b(ptr noalias sret(%struct.f2a2b) align 4 %agg.result, [2 x i64] %x.coerce)
73 struct f2a2b
func_f2a2b(struct f2a2b x
) { return x
; }
75 // CHECK-LABEL: @call_f1
76 // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f1, align 4
77 // CHECK: %[[TMP:[^ ]+]] = load float, ptr @global_f1, align 4
78 // CHECK-LE: call i32 @func_f1(float inreg %[[TMP]])
79 // CHECK-BE: call void @func_f1(ptr sret(%struct.f1) align 4 %[[TMP0]], float inreg %[[TMP]])
81 void call_f1(void) { global_f1
= func_f1(global_f1
); }
83 // CHECK-LABEL: @call_f2
84 // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f2, align 4
85 // CHECK: %[[TMP:[^ ]+]] = load i64, ptr @global_f2, align 4
86 // CHECK-LE: call i64 @func_f2(i64 %[[TMP]])
87 // CHECK-BE: call void @func_f2(ptr sret(%struct.f2) align 4 %[[TMP0]], i64 %[[TMP]])
89 void call_f2(void) { global_f2
= func_f2(global_f2
); }
91 // CHECK-LABEL: @call_f3
92 // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f3, align 4
93 // CHECK: %[[TMP1:[^ ]+]] = alloca [2 x i64]
94 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f3, i64 12, i1 false)
95 // CHECK: %[[TMP3:[^ ]+]] = load [2 x i64], ptr %[[TMP1]]
96 // CHECK-LE: call { i64, i64 } @func_f3([2 x i64] %[[TMP3]])
97 // CHECK-BE: call void @func_f3(ptr sret(%struct.f3) align 4 %[[TMP0]], [2 x i64] %[[TMP3]])
99 void call_f3(void) { global_f3
= func_f3(global_f3
); }
101 // CHECK-LABEL: @call_f4
102 // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f4, align 4
103 // CHECK: %[[TMP:[^ ]+]] = load [2 x i64], ptr @global_f4, align 4
104 // CHECK-LE: call { i64, i64 } @func_f4([2 x i64] %[[TMP]])
105 // CHECK-BE: call void @func_f4(ptr sret(%struct.f4) align 4 %[[TMP0]], [2 x i64] %[[TMP]])
107 void call_f4(void) { global_f4
= func_f4(global_f4
); }
109 // CHECK-LABEL: @call_f5
110 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f5, align 4
111 // CHECK: %[[TMP1:[^ ]+]] = alloca [3 x i64]
112 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f5, i64 20, i1 false)
113 // CHECK: %[[TMP3:[^ ]+]] = load [3 x i64], ptr %[[TMP1]]
114 // CHECK: call void @func_f5(ptr sret(%struct.f5) align 4 %[[TMP0]], [3 x i64] %[[TMP3]])
116 void call_f5(void) { global_f5
= func_f5(global_f5
); }
118 // CHECK-LABEL: @call_f6
119 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f6, align 4
120 // CHECK: %[[TMP:[^ ]+]] = load [3 x i64], ptr @global_f6, align 4
121 // CHECK: call void @func_f6(ptr sret(%struct.f6) align 4 %[[TMP0]], [3 x i64] %[[TMP]])
123 void call_f6(void) { global_f6
= func_f6(global_f6
); }
125 // CHECK-LABEL: @call_f7
126 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f7, align 4
127 // CHECK: %[[TMP1:[^ ]+]] = alloca [4 x i64], align 8
128 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f7, i64 28, i1 false)
129 // CHECK: %[[TMP3:[^ ]+]] = load [4 x i64], ptr %[[TMP1]], align 8
130 // CHECK: call void @func_f7(ptr sret(%struct.f7) align 4 %[[TMP0]], [4 x i64] %[[TMP3]])
132 void call_f7(void) { global_f7
= func_f7(global_f7
); }
134 // CHECK-LABEL: @call_f8
135 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f8, align 4
136 // CHECK: %[[TMP:[^ ]+]] = load [4 x i64], ptr @global_f8, align 4
137 // CHECK: call void @func_f8(ptr sret(%struct.f8) align 4 %[[TMP0]], [4 x i64] %[[TMP]])
139 void call_f8(void) { global_f8
= func_f8(global_f8
); }
141 // CHECK-LABEL: @call_f9
142 // CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64]
143 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f9, i64 36, i1 false)
144 // CHECK: %[[TMP3:[^ ]+]] = load [5 x i64], ptr %[[TMP1]]
145 // CHECK: call void @func_f9(ptr sret(%struct.f9) align 4 %{{[^ ]+}}, [5 x i64] %[[TMP3]])
147 void call_f9(void) { global_f9
= func_f9(global_f9
); }
149 // CHECK-LABEL: @call_fab
150 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.fab, align 4
151 // CHECK: %[[TMP:[^ ]+]] = load i64, ptr @global_fab, align 4
152 // CHECK-LE: %call = call i64 @func_fab(i64 %[[TMP]])
153 // CHECK-BE: call void @func_fab(ptr sret(%struct.fab) align 4 %[[TMP0]], i64 %[[TMP]])
154 struct fab global_fab
;
155 void call_fab(void) { global_fab
= func_fab(global_fab
); }
157 // CHECK-LABEL: @call_fabc
158 // CHECK-BE: %[[TMPX:[^ ]+]] = alloca %struct.fabc, align 4
159 // CHECK: %[[TMP0:[^ ]+]] = alloca [2 x i64], align 8
160 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP0]], ptr align 4 @global_fabc, i64 12, i1 false)
161 // CHECK: %[[TMP3:[^ ]+]] = load [2 x i64], ptr %[[TMP0]], align 8
162 // CHECK-LE: %call = call { i64, i64 } @func_fabc([2 x i64] %[[TMP3]])
163 // CHECK-BE: call void @func_fabc(ptr sret(%struct.fabc) align 4 %[[TMPX]], [2 x i64] %[[TMP3]])
164 struct fabc global_fabc
;
165 void call_fabc(void) { global_fabc
= func_fabc(global_fabc
); }