Clang Project

clang_source_code/test/CodeGen/ppc64-soft-float.c
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
3
4// Test float returns and params.
5
6// CHECK: define float @func_p1(float %x)
7float func_p1(float x) { return x; }
8
9// CHECK: define double @func_p2(double %x)
10double func_p2(double x) { return x; }
11
12// CHECK: define ppc_fp128 @func_p3(ppc_fp128 %x)
13long double func_p3(long double x) { return x; }
14
15// Test homogeneous float aggregate passing and returning.
16
17struct f1 { float f[1]; };
18struct f2 { float f[2]; };
19struct f3 { float f[3]; };
20struct f4 { float f[4]; };
21struct f5 { float f[5]; };
22struct f6 { float f[6]; };
23struct f7 { float f[7]; };
24struct f8 { float f[8]; };
25struct f9 { float f[9]; };
26
27struct fab { float a; float b; };
28struct fabc { float a; float b; float c; };
29
30struct f2a2b { float a[2]; float b[2]; };
31
32// CHECK-LE: define i32 @func_f1(float inreg %x.coerce)
33// CHECK-BE: define void @func_f1(%struct.f1* noalias sret %agg.result, float inreg %x.coerce)
34struct f1 func_f1(struct f1 x) { return x; }
35
36// CHECK-LE: define i64 @func_f2(i64 %x.coerce)
37// CHECK-BE: define void @func_f2(%struct.f2* noalias sret %agg.result, i64 %x.coerce)
38struct f2 func_f2(struct f2 x) { return x; }
39
40// CHECK-LE: define { i64, i64 } @func_f3([2 x i64] %x.coerce)
41// CHECK-BE: define void @func_f3(%struct.f3* noalias sret %agg.result, [2 x i64] %x.coerce)
42struct f3 func_f3(struct f3 x) { return x; }
43
44// CHECK-LE: define { i64, i64 } @func_f4([2 x i64] %x.coerce)
45// CHECK-BE: define void @func_f4(%struct.f4* noalias sret %agg.result, [2 x i64] %x.coerce)
46struct f4 func_f4(struct f4 x) { return x; }
47
48// CHECK: define void @func_f5(%struct.f5* noalias sret %agg.result, [3 x i64] %x.coerce)
49struct f5 func_f5(struct f5 x) { return x; }
50
51// CHECK: define void @func_f6(%struct.f6* noalias sret %agg.result, [3 x i64] %x.coerce)
52struct f6 func_f6(struct f6 x) { return x; }
53
54// CHECK: define void @func_f7(%struct.f7* noalias sret %agg.result, [4 x i64] %x.coerce)
55struct f7 func_f7(struct f7 x) { return x; }
56
57// CHECK: define void @func_f8(%struct.f8* noalias sret %agg.result, [4 x i64] %x.coerce)
58struct f8 func_f8(struct f8 x) { return x; }
59
60// CHECK: define void @func_f9(%struct.f9* noalias sret %agg.result, [5 x i64] %x.coerce)
61struct f9 func_f9(struct f9 x) { return x; }
62
63// CHECK-LE: define i64 @func_fab(i64 %x.coerce)
64// CHECK-BE: define void @func_fab(%struct.fab* noalias sret %agg.result, i64 %x.coerce)
65struct fab func_fab(struct fab x) { return x; }
66
67// CHECK-LE: define { i64, i64 } @func_fabc([2 x i64] %x.coerce)
68// CHECK-BE: define void @func_fabc(%struct.fabc* noalias sret %agg.result, [2 x i64] %x.coerce)
69struct fabc func_fabc(struct fabc x) { return x; }
70
71// CHECK-LE: define { i64, i64 } @func_f2a2b([2 x i64] %x.coerce)
72// CHECK-BE: define void @func_f2a2b(%struct.f2a2b* noalias sret %agg.result, [2 x i64] %x.coerce)
73struct f2a2b func_f2a2b(struct f2a2b x) { return x; }
74
75// CHECK-LABEL: @call_f1
76// CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f1, align 4
77// CHECK: %[[TMP:[^ ]+]] = load float, float* getelementptr inbounds (%struct.f1, %struct.f1* @global_f1, i32 0, i32 0, i32 0), align 4
78// CHECK-LE: call i32 @func_f1(float inreg %[[TMP]])
79// CHECK-BE: call void @func_f1(%struct.f1* sret %[[TMP0]], float inreg %[[TMP]])
80struct f1 global_f1;
81void call_f1(void) { global_f1 = func_f1(global_f1); }
82
83// CHECK-LABEL: @call_f2
84// CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f2, align 4
85// CHECK: %[[TMP:[^ ]+]] = load i64, i64* bitcast (%struct.f2* @global_f2 to i64*), align 4
86// CHECK-LE: call i64 @func_f2(i64 %[[TMP]])
87// CHECK-BE: call void @func_f2(%struct.f2* sret %[[TMP0]], i64 %[[TMP]])
88struct f2 global_f2;
89void call_f2(void) { global_f2 = func_f2(global_f2); }
90
91// CHECK-LABEL: @call_f3
92// CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f3, align 4
93// CHECK: %[[TMP1:[^ ]+]] = alloca [2 x i64]
94// CHECK: %[[TMP2:[^ ]+]] = bitcast [2 x i64]* %[[TMP1]] to i8*
95// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[TMP2]], i8* align 4 bitcast (%struct.f3* @global_f3 to i8*), i64 12, i1 false)
96// CHECK: %[[TMP3:[^ ]+]] = load [2 x i64], [2 x i64]* %[[TMP1]]
97// CHECK-LE: call { i64, i64 } @func_f3([2 x i64] %[[TMP3]])
98// CHECK-BE: call void @func_f3(%struct.f3* sret %[[TMP0]], [2 x i64] %[[TMP3]])
99struct f3 global_f3;
100void call_f3(void) { global_f3 = func_f3(global_f3); }
101
102// CHECK-LABEL: @call_f4
103// CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f4, align 4
104// CHECK: %[[TMP:[^ ]+]] = load [2 x i64], [2 x i64]* bitcast (%struct.f4* @global_f4 to [2 x i64]*), align 4
105// CHECK-LE: call { i64, i64 } @func_f4([2 x i64] %[[TMP]])
106// CHECK-BE: call void @func_f4(%struct.f4* sret %[[TMP0]], [2 x i64] %[[TMP]])
107struct f4 global_f4;
108void call_f4(void) { global_f4 = func_f4(global_f4); }
109
110// CHECK-LABEL: @call_f5
111// CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f5, align 4
112// CHECK: %[[TMP1:[^ ]+]] = alloca [3 x i64]
113// CHECK: %[[TMP2:[^ ]+]] = bitcast [3 x i64]* %[[TMP1]] to i8*
114// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[TMP2]], i8* align 4 bitcast (%struct.f5* @global_f5 to i8*), i64 20, i1 false)
115// CHECK: %[[TMP3:[^ ]+]] = load [3 x i64], [3 x i64]* %[[TMP1]]
116// CHECK: call void @func_f5(%struct.f5* sret %[[TMP0]], [3 x i64] %[[TMP3]])
117struct f5 global_f5;
118void call_f5(void) { global_f5 = func_f5(global_f5); }
119
120// CHECK-LABEL: @call_f6
121// CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f6, align 4
122// CHECK: %[[TMP:[^ ]+]] = load [3 x i64], [3 x i64]* bitcast (%struct.f6* @global_f6 to [3 x i64]*), align 4
123// CHECK: call void @func_f6(%struct.f6* sret %[[TMP0]], [3 x i64] %[[TMP]])
124struct f6 global_f6;
125void call_f6(void) { global_f6 = func_f6(global_f6); }
126
127// CHECK-LABEL: @call_f7
128// CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f7, align 4
129// CHECK: %[[TMP1:[^ ]+]] = alloca [4 x i64], align 8
130// CHECK: %[[TMP2:[^ ]+]] = bitcast [4 x i64]* %[[TMP1]] to i8*
131// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[TMP2]], i8* align 4 bitcast (%struct.f7* @global_f7 to i8*), i64 28, i1 false)
132// CHECK: %[[TMP3:[^ ]+]] = load [4 x i64], [4 x i64]* %[[TMP1]], align 8
133// CHECK: call void @func_f7(%struct.f7* sret %[[TMP0]], [4 x i64] %[[TMP3]])
134struct f7 global_f7;
135void call_f7(void) { global_f7 = func_f7(global_f7); }
136
137// CHECK-LABEL: @call_f8
138// CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f8, align 4
139// CHECK: %[[TMP:[^ ]+]] = load [4 x i64], [4 x i64]* bitcast (%struct.f8* @global_f8 to [4 x i64]*), align 4
140// CHECK: call void @func_f8(%struct.f8* sret %[[TMP0]], [4 x i64] %[[TMP]])
141struct f8 global_f8;
142void call_f8(void) { global_f8 = func_f8(global_f8); }
143
144// CHECK-LABEL: @call_f9
145// CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64]
146// CHECK: %[[TMP2:[^ ]+]] = bitcast [5 x i64]* %[[TMP1]] to i8*
147// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[TMP2]], i8* align 4 bitcast (%struct.f9* @global_f9 to i8*), i64 36, i1 false)
148// CHECK: %[[TMP3:[^ ]+]] = load [5 x i64], [5 x i64]* %[[TMP1]]
149// CHECK: call void @func_f9(%struct.f9* sret %{{[^ ]+}}, [5 x i64] %[[TMP3]])
150struct f9 global_f9;
151void call_f9(void) { global_f9 = func_f9(global_f9); }
152
153// CHECK-LABEL: @call_fab
154// CHECK: %[[TMP0:[^ ]+]] = alloca %struct.fab, align 4
155// CHECK: %[[TMP:[^ ]+]] = load i64, i64* bitcast (%struct.fab* @global_fab to i64*), align 4
156// CHECK-LE: %call = call i64 @func_fab(i64 %[[TMP]])
157// CHECK-BE: call void @func_fab(%struct.fab* sret %[[TMP0]], i64 %[[TMP]])
158struct fab global_fab;
159void call_fab(void) { global_fab = func_fab(global_fab); }
160
161// CHECK-LABEL: @call_fabc
162// CHECK-BE: %[[TMPX:[^ ]+]] = alloca %struct.fabc, align 4
163// CHECK: %[[TMP0:[^ ]+]] = alloca [2 x i64], align 8
164// CHECK: %[[TMP2:[^ ]+]] = bitcast [2 x i64]* %[[TMP0]] to i8*
165// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[TMP2]], i8* align 4 bitcast (%struct.fabc* @global_fabc to i8*), i64 12, i1 false)
166// CHECK: %[[TMP3:[^ ]+]] = load [2 x i64], [2 x i64]* %[[TMP0]], align 8
167// CHECK-LE: %call = call { i64, i64 } @func_fabc([2 x i64] %[[TMP3]])
168// CHECK-BE: call void @func_fabc(%struct.fabc* sret %[[TMPX]], [2 x i64] %[[TMP3]])
169struct fabc global_fabc;
170void call_fabc(void) { global_fabc = func_fabc(global_fabc); }
171
172