Skip to content

Commit 4403710

Browse files
authored
[FMV][AArch64] Fix UPASS when "SSBS not fully self-synchronizing". (#167)
When running try_ssbs2() on hardware which is affected by the "SSBS not fully self-synchronizing" errata, the linux kernel mutes the detection of ssbs2 via hardware caps. As a result the default version ends up running the ssbs2 code which was expected to trap originally. To work around this UPASS I am passing an additional macro parameter to indicate whether the default version is exempt from diagnostics. This fixes llvm/llvm-project#109304.
1 parent a400206 commit 4403710

File tree

1 file changed

+59
-52
lines changed

1 file changed

+59
-52
lines changed

SingleSource/UnitTests/AArch64/acle-fmv-features.c

Lines changed: 59 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
#include <sys/sysctl.h>
1111
#endif
1212

13-
static bool safe_try_feature(bool (*try_feature)(void));
13+
static bool safe_try_feature(bool (*try_feature)(void), bool is_exempt);
1414

1515
static bool any_fails = false;
1616

1717
#if __HAVE_FUNCTION_MULTI_VERSIONING
18-
#define CHECK(FN_NAME_SUFFIX, FMV_FEATURE, TARGET_GUARD, BODY) \
18+
#define CHECK(FN_NAME_SUFFIX, FMV_FEATURE, TARGET_GUARD, IS_EXEMPT, BODY) \
1919
__attribute__((target(#TARGET_GUARD))) \
2020
static bool try_##FN_NAME_SUFFIX(void) { \
2121
do \
@@ -27,7 +27,8 @@ static bool any_fails = false;
2727
static void check_##FN_NAME_SUFFIX(void) { \
2828
printf("%s\n", #FMV_FEATURE); \
2929
fflush(stdout); \
30-
if (!safe_try_feature(try_##FN_NAME_SUFFIX)) { \
30+
/* non-default versions are never exempt from diagnostics */ \
31+
if (!safe_try_feature(try_##FN_NAME_SUFFIX, false)) { \
3132
printf("\tFAIL\n"); \
3233
any_fails = true; \
3334
} \
@@ -36,58 +37,59 @@ static bool any_fails = false;
3637
static void check_##FN_NAME_SUFFIX(void) { \
3738
printf("%s\n", #FMV_FEATURE); \
3839
fflush(stdout); \
39-
if (safe_try_feature(try_##FN_NAME_SUFFIX)) { \
40+
/* default versions are allowed to UPASS when IS_EXEMPT = true */ \
41+
if (safe_try_feature(try_##FN_NAME_SUFFIX, IS_EXEMPT)) { \
4042
printf("\tUPASS\n"); \
4143
any_fails = true; \
4244
} \
4345
}
4446
#else
45-
#define CHECK(FN_NAME_SUFFIX, FMV_FEATURE, TARGET_GUARD, BODY) \
47+
#define CHECK(FN_NAME_SUFFIX, FMV_FEATURE, TARGET_GUARD, IS_EXEMPT, BODY) \
4648
static void check_##FN_NAME_SUFFIX(void) { \
4749
printf("%s\n", #FMV_FEATURE); \
4850
}
4951
#endif
5052

51-
CHECK(flagm, flagm, flagm, {
53+
CHECK(flagm, flagm, flagm, false, {
5254
asm volatile (
5355
"cfinv" "\n"
5456
"cfinv" "\n"
5557
);
5658
})
57-
CHECK(flagm2, flagm2, arch=armv8.5-a, {
59+
CHECK(flagm2, flagm2, arch=armv8.5-a, false, {
5860
asm volatile (
5961
"axflag" "\n"
6062
"xaflag" "\n"
6163
);
6264
})
63-
CHECK(dotprod, dotprod, dotprod, {
65+
CHECK(dotprod, dotprod, dotprod, false, {
6466
asm volatile (
6567
"udot v0.4S,v1.16B,v2.16B"
6668
: : : "v0"
6769
);
6870
})
69-
CHECK(sha3, sha3, sha3, {
71+
CHECK(sha3, sha3, sha3, false, {
7072
asm volatile (
7173
"fmov d0, #0" "\n"
7274
"fmov d1, #0" "\n"
7375
"eor3 v0.16b, v0.16b, v0.16b, v0.16b" "\n"
7476
: : : "v0"
7577
);
7678
})
77-
CHECK(rdm, rdm, rdm, {
79+
CHECK(rdm, rdm, rdm, false, {
7880
asm volatile (
7981
"sqrdmlah s0, s1, s2"
8082
: : : "s0"
8183
);
8284
})
83-
CHECK(lse, lse, lse, {
85+
CHECK(lse, lse, lse, false, {
8486
uint64_t pointee = 0;
8587
asm volatile (
8688
"swp xzr, xzr, [%[pointee]]"
8789
: : [pointee]"r"(&pointee)
8890
);
8991
})
90-
CHECK(sha2, sha2, sha2, {
92+
CHECK(sha2, sha2, sha2, false, {
9193
asm volatile (
9294
"fmov d0, #0" "\n"
9395
"fmov d1, #0" "\n"
@@ -96,96 +98,101 @@ CHECK(sha2, sha2, sha2, {
9698
: : : "v0"
9799
);
98100
})
99-
CHECK(aes, aes, aes, {
101+
CHECK(aes, aes, aes, false, {
100102
asm volatile (
101103
"fmov d0, #0" "\n"
102104
"fmov d1, #0" "\n"
103105
"aesd v0.16B, v0.16B" "\n"
104106
: : : "v0"
105107
);
106108
})
107-
CHECK(pmull, pmull, aes, {
109+
CHECK(pmull, pmull, aes, false, {
108110
asm volatile (
109111
"fmov d0, #0" "\n"
110112
"pmull v0.1q, v0.1d, v0.1d" "\n"
111113
: : : "v0"
112114
);
113115
})
114-
CHECK(rcpc, rcpc, rcpc, {
116+
CHECK(rcpc, rcpc, rcpc, false, {
115117
int x;
116118
asm volatile (
117119
"ldaprb w0, [%0]"
118120
: : "r" (&x) : "w0"
119121
);
120122
})
121-
CHECK(rcpc2, rcpc2, arch=armv8.4-a, {
123+
CHECK(rcpc2, rcpc2, arch=armv8.4-a, false, {
122124
int x;
123125
asm volatile (
124126
"mov x1, %0" "\n"
125127
"ldapurb w0, [x1]" "\n"
126128
: : "r" (&x) : "w0", "x1"
127129
);
128130
})
129-
CHECK(fcma, fcma, fcma, {
131+
CHECK(fcma, fcma, fcma, false, {
130132
asm volatile (
131133
"fmov d0, #0" "\n"
132134
"fcadd v0.2s, v0.2s, v0.2s, #90" "\n"
133135
: : : "v0"
134136
);
135137
})
136-
CHECK(jscvt, jscvt, jscvt, {
138+
CHECK(jscvt, jscvt, jscvt, false, {
137139
asm volatile (
138140
"fmov d0, #0" "\n"
139141
"fjcvtzs w1, d0" "\n"
140142
: : : "w1", "d0"
141143
);
142144
})
143-
CHECK(dpb, dpb, arch=armv8.2-a, {
145+
CHECK(dpb, dpb, arch=armv8.2-a, false, {
144146
int x;
145147
asm volatile (
146148
"dc cvap, %0"
147149
: : "r" (&x)
148150
);
149151
})
150-
CHECK(dpb2, dpb2, arch=armv8.5-a, {
152+
CHECK(dpb2, dpb2, arch=armv8.5-a, false, {
151153
int x;
152154
asm volatile (
153155
"dc cvadp, %0"
154156
: : "r" (&x)
155157
);
156158
})
157-
CHECK(bf16, bf16, bf16, {
159+
CHECK(bf16, bf16, bf16, false, {
158160
asm volatile (
159161
"bfdot v0.4S,v1.8H,v2.8H"
160162
: : : "v0"
161163
);
162164
})
163-
CHECK(i8mm, i8mm, i8mm, {
165+
CHECK(i8mm, i8mm, i8mm, false, {
164166
asm volatile (
165167
"sudot v0.4S,v1.16B,v2.4B[0]"
166168
: : : "v0"
167169
);
168170
})
169-
CHECK(dit, dit, dit, {
171+
CHECK(dit, dit, dit, false, {
170172
asm volatile (
171173
"msr DIT, x0"
172174
: : : "x0"
173175
);
174176
})
175-
CHECK(fp16, fp16, fp16, {
177+
CHECK(fp16, fp16, fp16, false, {
176178
asm volatile (
177179
"fmov h0, #0"
178180
: : : "v0"
179181
);
180182
})
181-
CHECK(ssbs2, ssbs2, ssbs, {
183+
// When running try_ssbs2() on hardware which is affected by the "SSBS not fully
184+
// self-synchronizing" errata, the linux kernel mutes the detection of ssbs2 via
185+
// hardware caps. As a result the default version ends up running the ssbs2 code
186+
// which was expected to trap originally. Passing IS_EXEMPT = true here allows
187+
// the default version to UPASS.
188+
CHECK(ssbs2, ssbs2, ssbs, true, {
182189
asm volatile (
183190
"mrs x0, SSBS" "\n"
184191
"msr SSBS, x0" "\n"
185192
: : : "x0"
186193
);
187194
})
188-
CHECK(bti, bti, bti, {
195+
CHECK(bti, bti, bti, false, {
189196
// The only test for this requires reading a register that is only
190197
// accessible to EL1.
191198
#ifdef __linux__
@@ -206,35 +213,35 @@ CHECK(bti, bti, bti, {
206213
// TODO: implement me on your platform to fix this test!
207214
#endif
208215
})
209-
CHECK(simd, simd, simd, {
216+
CHECK(simd, simd, simd, false, {
210217
asm volatile (
211218
"mov v0.B[0], w0"
212219
: : :
213220
);
214221
})
215-
CHECK(fp, fp, fp, {
222+
CHECK(fp, fp, fp, false, {
216223
asm volatile (
217224
"fmov s0, #0"
218225
: : : "v0"
219226
);
220227
})
221-
CHECK(crc, crc, crc, {
228+
CHECK(crc, crc, crc, false, {
222229
asm volatile ( "crc32b wzr, wzr, wzr");
223230
})
224-
CHECK(sme, sme, sme, {
231+
CHECK(sme, sme, sme, false, {
225232
asm volatile (
226233
"rdsvl x0, #1"
227234
: : : "x0"
228235
);
229236
})
230-
CHECK(sme2, sme2, sme2, {
237+
CHECK(sme2, sme2, sme2, false, {
231238
asm volatile (
232239
"smstart za" "\n"
233240
"zero { zt0 }" "\n"
234241
"smstop za" "\n"
235242
);
236243
})
237-
CHECK(ls64, ls64, ls64, {
244+
CHECK(ls64, ls64, ls64, false, {
238245
long data[8];
239246
asm volatile (
240247
"ld64b x0, [%0]" "\n"
@@ -246,109 +253,109 @@ CHECK(ls64, ls64, ls64, {
246253
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "memory"
247254
);
248255
})
249-
CHECK(f32mm, f32mm, f32mm, {
256+
CHECK(f32mm, f32mm, f32mm, false, {
250257
asm volatile (
251258
"fmmla z0.s, z1.s, z2.s"
252259
: : : "v0"
253260
);
254261
})
255-
CHECK(f64mm, f64mm, f64mm, {
262+
CHECK(f64mm, f64mm, f64mm, false, {
256263
asm volatile (
257264
"fmmla z0.d, z1.d, z2.d"
258265
: : : "v0"
259266
);
260267
})
261-
CHECK(fp16fml, fp16fml, fp16fml, {
268+
CHECK(fp16fml, fp16fml, fp16fml, false, {
262269
asm volatile (
263270
"fmlal v0.2s, v1.2h, v2.2h"
264271
: : : "v0"
265272
);
266273
})
267-
CHECK(frintts, frintts, arch=armv8.5-a, {
274+
CHECK(frintts, frintts, arch=armv8.5-a, false, {
268275
asm volatile (
269276
"frint32z s0, s1"
270277
: : : "v0"
271278
);
272279
})
273-
CHECK(predres, predres, predres, {
280+
CHECK(predres, predres, predres, false, {
274281
asm volatile (
275282
"cfp rctx, x0" "\n"
276283
"dvp rctx, x1" "\n"
277284
"cpp rctx, x2" "\n"
278285
);
279286
})
280-
CHECK(rcpc3, rcpc3, rcpc3, {
287+
CHECK(rcpc3, rcpc3, rcpc3, false, {
281288
long x;
282289
asm volatile (
283290
"stilp wzr, wzr, [%0]"
284291
: : "r" (&x) : "memory"
285292
);
286293
})
287-
CHECK(rng, rng, rng, {
294+
CHECK(rng, rng, rng, false, {
288295
asm volatile (
289296
"mrs x0, rndr" "\n"
290297
"mrs x1, rndrrs" "\n"
291298
: : : "x0", "x1"
292299
);
293300
})
294-
CHECK(sve, sve, sve, {
301+
CHECK(sve, sve, sve, false, {
295302
asm volatile (
296303
"fadda s0, p7, s0, z31.s"
297304
: : : "v0"
298305
);
299306
})
300-
CHECK(sve2, sve2, sve2, {
307+
CHECK(sve2, sve2, sve2, false, {
301308
asm volatile (
302309
"match p15.b, p7/z, z0.b, z1.b"
303310
: : : "p15", "cc"
304311
);
305312
})
306-
CHECK(sve2_bitperm, sve2-bitperm, sve2-bitperm, {
313+
CHECK(sve2_bitperm, sve2-bitperm, sve2-bitperm, false, {
307314
asm volatile (
308315
"bext z0.s, z1.s, z2.s"
309316
: : : "z0"
310317
);
311318
})
312-
CHECK(sve2_sha3, sve2-sha3, sve2-sha3, {
319+
CHECK(sve2_sha3, sve2-sha3, sve2-sha3, false, {
313320
asm volatile (
314321
"rax1 z0.d, z1.d, z2.d"
315322
: : : "z0"
316323
);
317324
})
318-
CHECK(sve2_sm4, sve2-sm4, sve2-sm4, {
325+
CHECK(sve2_sm4, sve2-sm4, sve2-sm4, false, {
319326
asm volatile (
320327
"sm4e z0.s, z0.s, z2.s"
321328
: : : "z0"
322329
);
323330
})
324-
CHECK(wfxt, wfxt, wfxt, {
331+
CHECK(wfxt, wfxt, wfxt, false, {
325332
asm volatile (
326333
"wfet x0" "\n"
327334
"wfit x1" "\n"
328335
);
329336
})
330-
CHECK(sb, sb, sb, {
337+
CHECK(sb, sb, sb, false, {
331338
asm volatile ("sb");
332339
})
333-
CHECK(sm4, sm4, sm4, {
340+
CHECK(sm4, sm4, sm4, false, {
334341
asm volatile (
335342
"sm4e v0.4s, v1.4s"
336343
: : : "v0"
337344
);
338345
})
339-
CHECK(sme_f64f64, sme-f64f64, sme-f64f64, {
346+
CHECK(sme_f64f64, sme-f64f64, sme-f64f64, false, {
340347
asm volatile (
341348
"fmops za0.d, p0/m, p0/m, z0.d, z0.d"
342349
: : : "za"
343350
);
344351
})
345-
CHECK(sme_i16i64, sme-i16i64, sme-i16i64, {
352+
CHECK(sme_i16i64, sme-i16i64, sme-i16i64, false, {
346353
asm volatile (
347354
"smopa za0.d, p0/m, p0/m, z0.h, z0.h"
348355
: : : "za"
349356
);
350357
})
351-
CHECK(mops, mops, mops, {
358+
CHECK(mops, mops, mops, false, {
352359
long dst[64];
353360
long src[64];
354361
size_t n = 32;
@@ -363,15 +370,15 @@ CHECK(mops, mops, mops, {
363370
);
364371
})
365372

366-
static bool safe_try_feature(bool (*try_feature)(void)) {
373+
static bool safe_try_feature(bool (*try_feature)(void), bool is_exempt) {
367374
int child = fork();
368375
if (child) {
369376
int exit_status = -1;
370377
if (child != waitpid(child, &exit_status, 0))
371378
return false;
372379
return exit_status == 0;
373380
} else {
374-
exit(try_feature() ? 0 : 1);
381+
exit((try_feature() && !is_exempt) ? EXIT_SUCCESS : EXIT_FAILURE);
375382
}
376383
}
377384

0 commit comments

Comments
 (0)