Skip to content

Commit 8ec50d6

Browse files
committed
[AArch64] Fix FMV ifunc resolver usage on old Android APIs. Rename internal compiler-rt FMV functions.
The patch fixes Function Multi Versioning features detection by ifunc resolver on Android API levels < 30. Ifunc hwcaps parameters are not supported on Android API levels 23-29, so all CPU features are set unsupported if they were not initialized before ifunc resolver call. There is no support for ifunc on Android API levels < 23, so Function Multi Versioning is disabled in this case. Also use two underscore prefix for FMV runtime support functions to avoid conflict with user program ones. Differential Revision: https://reviews.llvm.org/D158641
1 parent b141534 commit 8ec50d6

File tree

8 files changed

+46
-27
lines changed

8 files changed

+46
-27
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13524,7 +13524,7 @@ CodeGenFunction::EmitX86CpuSupports(std::array<uint32_t, 4> FeatureMask) {
1352413524
Value *CodeGenFunction::EmitAArch64CpuInit() {
1352513525
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
1352613526
llvm::FunctionCallee Func =
13527-
CGM.CreateRuntimeFunction(FTy, "init_cpu_features_resolver");
13527+
CGM.CreateRuntimeFunction(FTy, "__init_cpu_features_resolver");
1352813528
cast<llvm::GlobalValue>(Func.getCallee())->setDSOLocal(true);
1352913529
cast<llvm::GlobalValue>(Func.getCallee())
1353013530
->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7524,6 +7524,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
75247524

75257525
if (Triple.isAArch64() &&
75267526
(Args.hasArg(options::OPT_mno_fmv) ||
7527+
(Triple.isAndroid() && Triple.isAndroidVersionLT(23)) ||
75277528
getToolChain().GetRuntimeLibType(Args) != ToolChain::RLT_CompilerRT)) {
75287529
// Disable Function Multiversioning on AArch64 target.
75297530
CmdArgs.push_back("-target-feature");

clang/test/CodeGen/attr-target-clones-aarch64.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
4545
// CHECK-NEXT: ret i32 0
4646
// CHECK-LABEL: @ftc.resolver(
4747
// CHECK-NEXT: resolver_entry:
48-
// CHECK-NEXT: call void @init_cpu_features_resolver()
48+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
4949
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
5050
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 16512
5151
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 16512
@@ -77,7 +77,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
7777
// CHECK-NEXT: ret i32 1
7878
// CHECK-LABEL: @ftc_def.resolver(
7979
// CHECK-NEXT: resolver_entry:
80-
// CHECK-NEXT: call void @init_cpu_features_resolver()
80+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
8181
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
8282
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 17592186048512
8383
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 17592186048512
@@ -105,7 +105,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
105105
// CHECK-NEXT: ret i32 2
106106
// CHECK-LABEL: @ftc_dup1.resolver(
107107
// CHECK-NEXT: resolver_entry:
108-
// CHECK-NEXT: call void @init_cpu_features_resolver()
108+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
109109
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
110110
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4096
111111
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4096
@@ -129,7 +129,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
129129
// CHECK-NEXT: ret i32 3
130130
// CHECK-LABEL: @ftc_dup2.resolver(
131131
// CHECK-NEXT: resolver_entry:
132-
// CHECK-NEXT: call void @init_cpu_features_resolver()
132+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
133133
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
134134
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1040
135135
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1040
@@ -177,7 +177,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
177177
// CHECK-NEXT: ret i32 [[ADD5]]
178178
// CHECK-LABEL: @ftc_inline1.resolver(
179179
// CHECK-NEXT: resolver_entry:
180-
// CHECK-NEXT: call void @init_cpu_features_resolver()
180+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
181181
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
182182
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 18014535948435456
183183
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014535948435456
@@ -205,7 +205,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
205205
// CHECK-NEXT: ret ptr @ftc_inline1
206206
// CHECK-LABEL: @ftc_inline2.resolver(
207207
// CHECK-NEXT: resolver_entry:
208-
// CHECK-NEXT: call void @init_cpu_features_resolver()
208+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
209209
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
210210
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 549757911040
211211
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 549757911040
@@ -225,7 +225,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
225225
// CHECK-NEXT: ret ptr @ftc_inline2
226226
// CHECK-LABEL: @ftc_inline3.resolver(
227227
// CHECK-NEXT: resolver_entry:
228-
// CHECK-NEXT: call void @init_cpu_features_resolver()
228+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
229229
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
230230
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70369817919488
231231
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70369817919488

clang/test/CodeGen/attr-target-version.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ int hoo(void) {
153153
// CHECK-NEXT: ret i32 [[ADD3]]
154154
// CHECK-LABEL: @fmv.resolver(
155155
// CHECK-NEXT: resolver_entry:
156-
// CHECK-NEXT: call void @init_cpu_features_resolver()
156+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
157157
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
158158
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 11
159159
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 11
@@ -255,7 +255,7 @@ int hoo(void) {
255255
// CHECK-NEXT: ret i32 [[CALL3]]
256256
// CHECK-LABEL: @fmv_inline.resolver(
257257
// CHECK-NEXT: resolver_entry:
258-
// CHECK-NEXT: call void @init_cpu_features_resolver()
258+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
259259
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
260260
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048608256
261261
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048608256
@@ -358,7 +358,7 @@ int hoo(void) {
358358
// CHECK-NEXT: ret ptr @fmv_e._Mls64
359359
// CHECK-LABEL: @fmv_d.resolver(
360360
// CHECK-NEXT: resolver_entry:
361-
// CHECK-NEXT: call void @init_cpu_features_resolver()
361+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
362362
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
363363
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70368744177664
364364
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70368744177664
@@ -370,7 +370,7 @@ int hoo(void) {
370370
// CHECK-NEXT: ret ptr @fmv_d
371371
// CHECK-LABEL: @fmv_c.resolver(
372372
// CHECK-NEXT: resolver_entry:
373-
// CHECK-NEXT: call void @init_cpu_features_resolver()
373+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
374374
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
375375
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
376376
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656

clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void run_foo_tml() {
5454
// CHECK-NEXT: ret i32 1
5555
// CHECK-LABEL: @_Z7foo_ovli.resolver(
5656
// CHECK-NEXT: resolver_entry:
57-
// CHECK-NEXT: call void @init_cpu_features_resolver()
57+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
5858
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
5959
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4503599627436032
6060
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4503599627436032
@@ -72,7 +72,7 @@ void run_foo_tml() {
7272
// CHECK-NEXT: ret i32 2
7373
// CHECK-LABEL: @_Z7foo_ovlv.resolver(
7474
// CHECK-NEXT: resolver_entry:
75-
// CHECK-NEXT: call void @init_cpu_features_resolver()
75+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
7676
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
7777
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 11258999068426240
7878
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 11258999068426240
@@ -101,7 +101,7 @@ void run_foo_tml() {
101101
// CHECK-NEXT: ret void
102102
// CHECK-LABEL: @_ZN7MyClassIssE7foo_tmlEv.resolver(
103103
// CHECK-NEXT: resolver_entry:
104-
// CHECK-NEXT: call void @init_cpu_features_resolver()
104+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
105105
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
106106
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36310271995674624
107107
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36310271995674624
@@ -121,7 +121,7 @@ void run_foo_tml() {
121121
// CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv
122122
// CHECK-LABEL: @_ZN7MyClassIisE7foo_tmlEv.resolver(
123123
// CHECK-NEXT: resolver_entry:
124-
// CHECK-NEXT: call void @init_cpu_features_resolver()
124+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
125125
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
126126
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36310271995674624
127127
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36310271995674624

clang/test/CodeGenCXX/attr-target-version.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int bar() {
7878
// CHECK-NEXT: ret i32 [[ADD3]]
7979
// CHECK-LABEL: @_ZN7MyClass3gooEi.resolver(
8080
// CHECK-NEXT: resolver_entry:
81-
// CHECK-NEXT: call void @init_cpu_features_resolver()
81+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
8282
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
8383
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1024
8484
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1024
@@ -98,7 +98,7 @@ int bar() {
9898
// CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi
9999
// CHECK-LABEL: @_Z3fooi.resolver(
100100
// CHECK-NEXT: resolver_entry:
101-
// CHECK-NEXT: call void @init_cpu_features_resolver()
101+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
102102
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
103103
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36028797153181696
104104
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36028797153181696
@@ -110,7 +110,7 @@ int bar() {
110110
// CHECK-NEXT: ret ptr @_Z3fooi
111111
// CHECK-LABEL: @_Z3foov.resolver(
112112
// CHECK-NEXT: resolver_entry:
113-
// CHECK-NEXT: call void @init_cpu_features_resolver()
113+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
114114
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
115115
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 268435488
116116
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 268435488

clang/test/Driver/aarch64-features.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
// CHECK: fno-signed-char
88

99
// Check Function Multi Versioning option and rtlib dependency.
10-
// RUN: %clang --target=aarch64-linux-android -rtlib=compiler-rt \
10+
// RUN: %clang --target=aarch64-linux-android23 -rtlib=compiler-rt \
1111
// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-FMV %s
12-
12+
// RUN: %clang --target=aarch64-linux-android -rtlib=compiler-rt \
13+
// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-FMV-OFF %s
1314
// RUN: %clang --target=aarch64-linux-android -rtlib=compiler-rt -mno-fmv \
1415
// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-FMV-OFF %s
16+
// RUN: %clang --target=aarch64-linux-android22 -rtlib=compiler-rt \
17+
// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-FMV-OFF %s
1518

1619
// RUN: %clang --target=aarch64-linux-gnu -rtlib=libgcc \
1720
// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-FMV-OFF %s
18-
1921
// RUN: %clang --target=arm64-unknown-linux -rtlib=libgcc \
2022
// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-FMV-OFF %s
2123

compiler-rt/lib/builtins/cpu_model.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,13 +1239,12 @@ struct {
12391239
// As features grows new fields could be added
12401240
} __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
12411241

1242-
void init_cpu_features_resolver(unsigned long hwcap, const __ifunc_arg_t *arg) {
1242+
static void __init_cpu_features_constructor(unsigned long hwcap,
1243+
const __ifunc_arg_t *arg) {
12431244
#define setCPUFeature(F) __aarch64_cpu_features.features |= 1ULL << F
12441245
#define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr))
12451246
#define extractBits(val, start, number) \
12461247
(val & ((1ULL << number) - 1ULL) << start) >> start
1247-
if (__aarch64_cpu_features.features)
1248-
return;
12491248
unsigned long hwcap2 = 0;
12501249
if (hwcap & _IFUNC_ARG_HWCAP)
12511250
hwcap2 = arg->_hwcap2;
@@ -1427,7 +1426,24 @@ void init_cpu_features_resolver(unsigned long hwcap, const __ifunc_arg_t *arg) {
14271426
setCPUFeature(FEAT_MAX);
14281427
}
14291428

1430-
void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
1429+
void __init_cpu_features_resolver(unsigned long hwcap,
1430+
const __ifunc_arg_t *arg) {
1431+
if (__aarch64_cpu_features.features)
1432+
return;
1433+
#if defined(__ANDROID__)
1434+
// ifunc resolvers don't have hwcaps in arguments on Android API lower
1435+
// than 30. If so, set feature detection done and keep all CPU features
1436+
// unsupported (zeros). To detect this case in runtime we check existence
1437+
// of memfd_create function from Standard C library which was introduced in
1438+
// Android API 30.
1439+
int memfd_create(const char *, unsigned int) __attribute__((weak));
1440+
if (!memfd_create)
1441+
return;
1442+
#endif // defined(__ANDROID__)
1443+
__init_cpu_features_constructor(hwcap, arg);
1444+
}
1445+
1446+
void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
14311447
unsigned long hwcap;
14321448
unsigned long hwcap2;
14331449
// CPU features already initialized.
@@ -1452,7 +1468,7 @@ void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
14521468
arg._size = sizeof(__ifunc_arg_t);
14531469
arg._hwcap = hwcap;
14541470
arg._hwcap2 = hwcap2;
1455-
init_cpu_features_resolver(hwcap | _IFUNC_ARG_HWCAP, &arg);
1471+
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
14561472
#undef extractBits
14571473
#undef getCPUFeature
14581474
#undef setCPUFeature

0 commit comments

Comments
 (0)