xref: /llvm-project/clang/test/CodeGen/cmse-clear-return.c (revision c5de4dd1eab00df76c1a68c5f397304ceacb71f2)
1 // RUN: %clang_cc1 -triple thumbv8m.main   -O0 -mcmse -emit-llvm %s -o - | \
2 // RUN:    FileCheck %s --check-prefixes=CHECK,CHECK-LE,CHECK-LE-NOPT,CHECK-SOFT
3 // RUN: %clang_cc1 -triple thumbebv8m.main -O0 -mcmse -emit-llvm %s -o - | \
4 // RUN:    FileCheck %s --check-prefixes=CHECK,CHECK-BE,CHECK-SOFT
5 // RUN: %clang_cc1 -triple thumbv8m.main   -O2 -mcmse -emit-llvm %s -o - | \
6 // RUN:    FileCheck %s --check-prefixes=CHECK,CHECK-LE,CHECK-LE-OPT,CHECK-SOFT
7 // RUN: %clang_cc1 -triple thumbebv8m.main -O2 -mcmse -emit-llvm %s -o - | \
8 // RUN:    FileCheck %s --check-prefixes=CHECK,CHECK-BE,CHECK-BE-OPT,CHECK-SOFT
9 // RUN: %clang_cc1 -triple thumbv8m.main   -O0 -mcmse -emit-llvm %s -o - \
10 // RUN:            -mfloat-abi hard | \
11 // RUN:    FileCheck %s --check-prefixes=CHECK,CHECK-LE,CHECK-LE-NOPT,CHECK-HARD
12 
13 
14 //   :        Memory layout                | Mask
15 // LE: .......1 ........ ........ ........ | 0x00000001/1
16 // BE: 1....... ........ ........ ........ | 0x80000000/-2147483648
17 typedef struct T0 {
18   int a : 1, : 31;
19 } T0;
20 
21 T0 t0;
f0(void)22 __attribute__((cmse_nonsecure_entry)) T0 f0(void) { return t0; }
23 // CHECK:    define {{.*}} @f0()
24 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 1
25 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, -2147483648
26 // CHECK:    ret i32 %[[R]]
27 
28 // LE: ......1. ........ ........ ........ 0x00000002/2
29 // BE: .1...... ........ ........ ........ 0x40000000/1073741824
30 typedef struct T1 {
31   int : 1, a : 1, : 30;
32 } T1;
33 
34 T1 t1;
f1(void)35 __attribute__((cmse_nonsecure_entry)) T1 f1(void) { return t1; }
36 // CHECK:    define {{.*}} @f1()
37 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 2
38 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, 1073741824
39 // CHECK:    ret i32 %[[R]]
40 
41 // LE: ........ .......1 ........ ........ 0x00000100/256
42 // BE: ........ 1....... ........ ........ 0x00800000/8388608
43 typedef struct T2 {
44   int : 8, a : 1, : 23;
45 } T2;
46 
47 T2 t2;
f2(void)48 __attribute__((cmse_nonsecure_entry)) T2 f2(void) { return t2; }
49 // CHECK:    define {{.*}} @f2()
50 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 256
51 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, 8388608
52 // CHECK:    ret i32 %[[R]]
53 
54 // LE: ........ .....1.. ........ ........ 0x00000400/1024
55 // BE: ........ ..1..... ........ ........ 0x00200000/2097152
56 typedef struct T3 {
57   int : 10, a : 1;
58 } T3;
59 
60 T3 t3;
f3(void)61 __attribute__((cmse_nonsecure_entry)) T3 f3(void) { return t3; }
62 // CHECK:    define {{.*}} @f3()
63 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 1024
64 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, 2097152
65 // CHECK:    ret i32 %[[R]]
66 
67 // LE: 11111111 ........ ........ ........ 0x000000ff/255
68 // BE: 11111111 ........ ........ ........ 0xff000000/-16777216
69 typedef struct T4 {
70   int a : 8, : 24;
71 } T4;
72 
73 T4 t4;
f4(void)74 __attribute__((cmse_nonsecure_entry)) T4 f4(void) { return t4; }
75 // CHECK: define {{.*}} @f4()
76 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 255
77 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, -16777216
78 // CHECK: ret i32 %[[R]]
79 
80 // LE: 1111111. .......1 ........ ........ 0x000001fe/510
81 // BE: .1111111 1....... ........ ........ 0x7f800000/2139095040
82 typedef struct T5 {
83   int : 1, a : 8, : 23;
84 } T5;
85 
86 T5 t5;
f5(void)87 __attribute__((cmse_nonsecure_entry)) T5 f5(void) { return t5; }
88 // CHECK:    define {{.*}} @f5()
89 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 510
90 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, 2139095040
91 // CHECK:    ret i32 %[[R]]
92 
93 // LE: 1111111. 11111111 ........ ........ 0x0000fffe/65534
94 // BE: .1111111 11111111 ........ ........ 0x7fff0000/2147418112
95 typedef struct T6 {
96   int : 1, a : 15, : 16;
97 } T6;
98 
99 T6 t6;
f6(void)100 __attribute__((cmse_nonsecure_entry)) T6 f6(void) { return t6; }
101 // CHECK:    define {{.*}} @f6()
102 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 65534
103 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, 2147418112
104 // CHECK:    ret i32 %[[R]]
105 
106 // LE: 1111111. 11111111 .......1 ........ 0x0001fffe/131070
107 // BE: .1111111 11111111 1....... ........ 0x7fff8000/2147450880
108 typedef struct T7 {
109   int : 1, a : 16, : 15;
110 } T7;
111 
112 T7 t7;
f7(void)113 __attribute__((cmse_nonsecure_entry)) T7 f7(void) { return t7; }
114 // CHECK:    define {{.*}} @f7()
115 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 131070
116 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, 2147450880
117 // CHECK:    ret i32 %[[R]]
118 
119 // LE: 11111111 111111.. 11111111 11111111 0xfffffcff/-769
120 // BE: 11111111 ..111111 11111111 11111111 0xff3fffff/-12582913
121 typedef struct T8 {
122   struct T80 {
123     char a;
124     char : 2, b : 6;
125   } a;
126   short b;
127 } T8;
128 
129 T8 t8;
f8(void)130 __attribute__((cmse_nonsecure_entry)) T8 f8(void) { return t8; }
131 // CHECK:    define {{.*}} @f8()
132 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, -769
133 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, -12582913
134 // CHECK:    ret i32 %[[R]]
135 
136 // LE: ......11 ..111111 ...11111 ........ 0x001f3f03/2047747
137 // BE: 11...... 111111.. 11111... ........ 0xc0fcf800/-1057163264
138 typedef struct T9 {
139   struct T90 {
140     char a : 2;
141     char : 0;
142     short b : 6;
143   } a;
144   int b : 5;
145 } T9;
146 
147 T9 t9;
f9(void)148 __attribute__((cmse_nonsecure_entry)) T9 f9(void) { return t9; }
149 // CHECK:    define {{.*}} @f9()
150 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 2047747
151 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, -1057163264
152 // CHECK:    ret i32 %[[R]]
153 
f91(void)154 T9 f91(void) { return t9; }
155 // CHECK:  define {{.*}} @f91()
156 // CHECK: %[[R:.*]] = load i32
157 // CHECK: ret i32 %[[R]]
158 
159 // LE: 11111111 ........ 11111111 11111111 0xffff00ff/-65281
160 // BE: 11111111 ........ 11111111 11111111 0xff00ffff/16711681
161 typedef struct T10 {
162   char a;
163   short b;
164 } T10;
165 
166 T10 t10;
f10(void)167 __attribute__((cmse_nonsecure_entry)) T10 f10(void) { return t10; }
168 // CHECK: define {{.*}} @f10()
169 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, -65281
170 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, -16711681
171 // CHECK: ret i32 %[[R]]
172 
173 // LE: 11111111 11111111 11111111 ........ 0x00ffffff/16777215
174 // BE: 11111111 11111111 11111111 ........ 0xffffff00/-256
175 typedef struct T11 {
176   short a;
177   char b;
178 } T11;
179 
180 T11 t11;
f11(void)181 __attribute__((cmse_nonsecure_entry)) T11 f11(void) { return t11; }
182 // CHECK: define {{.*}} @f11()
183 // CHECK-LE: %[[R:.*]] = and i32 %{{.*}}, 16777215
184 // CHECK-BE: %[[R:.*]] = and i32 %{{.*}}, -256
185 // CHECK: ret i32 %[[R]]
186 
187 // LE: 11111111 11111111 11111111 ........ 0x00ffffff/16777215
188 // BE: 11111111 11111111 11111111 ........ 0xffffff00/-256
189 typedef struct T12 {
190   char a[3];
191 } T12;
192 
193 T12 t12;
f12(void)194 __attribute__((cmse_nonsecure_entry)) T12 f12(void) { return t12; }
195 // CHECK:    define {{.*}} @f12()
196 // CHECK-LE-OPT:  %[[V0:.*]] = load i24, ptr @t12
197 // CHECK-LE-OPT:  %[[R:.*]] = zext i24 %[[V0]] to i32
198 // CHECK-LE-NOPT: %[[R:.*]] = and i32 %{{.*}}, 16777215
199 
200 // CHECK-BE-OPT:  %[[V0:.*]] = load i24, ptr @t12
201 // CHECK-BE-OPT:  %[[V1:.*]] = zext i24 %[[V0]] to i32
202 // CHECK-BE-OPT:  %[[R:.*]] = shl nuw i32 %[[V1]], 8
203 // CHECK:         ret i32 %[[R]]
204 
205 // LE: 11111111 11111111 11111111 ........ 0x00ffffff/16777215
206 // BE: 11111111 11111111 11111111 ........ 0xffffff00/-256
207 typedef struct __attribute__((packed)) T13 {
208   char a;
209   short b;
210 } T13;
211 
212 T13 t13;
f13(void)213 __attribute__((cmse_nonsecure_entry)) T13 f13(void) { return t13; }
214 // CHECK:         define {{.*}} @f13()
215 // CHECK-LE-OPT:  %[[V0:.*]] = load i24, ptr @t13
216 // CHECK-LE-OPT:  %[[R:.*]] = zext i24 %[[V0]] to i32
217 // CHECK-LE-NOPT: %[[R:.*]] = and i32 %{{.*}}, 16777215
218 
219 // CHECK-BE-OPT:  %[[V0:.*]] = load i24, ptr @t13
220 // CHECK-BE-OPT:  %[[V1:.*]] = zext i24 %[[V0]] to i32
221 // CHECK-BE-OPT:  %[[R:.*]] = shl nuw i32 %[[V1]], 8
222 // CHECK:         ret i32 %[[R]]
223 
224 typedef struct __attribute__((packed)) T14 {
225   short a;
226   short b;
227 } T14;
228 
229 T14 t14;
f14(void)230 __attribute__((cmse_nonsecure_entry)) T14 f14(void) { return t14; }
231 // CHECK:         define {{.*}} @f14()
232 // CHECK:         [[R:%.*]] = load
233 // CHECK-LE-OPT:  ret i32 [[R]]
234 // CHECK-LE-NOPT: [[AND:%.+]] = and i32 [[R]], -1
235 // CHECK-LE-NOPT: ret i32 [[AND]]
236 // CHECK-BE-OPT:  ret i32 [[R]]
237 
238 // LE: 1111..11 1111..11 11111111 11111111 0xfffff3f3/-3085
239 // BE: 11..1111 11..1111 11111111 11111111 0xcfcfffff/-808452097
240 typedef struct T17 {
241   struct T170 {
242     char a : 2;
243     char   : 2, b : 4;
244   } a[2];
245   char b[2];
246   char c[];
247 } T17;
248 
249 T17 t17;
f17(void)250 __attribute__((cmse_nonsecure_entry)) T17 f17(void) { return t17; }
251 // CHECK:    define {{.*}} @f17()
252 // CHECK-LE: %[[R:.*]] = and i32 {{.*}}, -3085
253 // CHECK-BE: %[[R:.*]] = and i32 {{.*}}, -808452097
254 // CHECK: ret i32 %[[R]]
255 
256 typedef struct T21 {
257   float a;
258 } T21;
259 
260 T21 t21;
f21(void)261 __attribute__((cmse_nonsecure_entry)) T21 f21(void) { return t21; }
262 // CHECK:      define {{.*}} @f21()
263 // CHECK-SOFT: ret i32
264 // CHECK-HARD: ret %struct.T21
265 
f22(void)266 __attribute__((cmse_nonsecure_entry)) float f22(void) { return 1.0f; }
267 // CHECK: define {{.*}} @f22()
268 // CHECK: ret float
269