Skip to content

Commit e82fecc

Browse files
committed
Only consider the highest priority callee when the caller is non-FMV.
Add a corresponding test case.
1 parent b9896b7 commit e82fecc

File tree

2 files changed

+68
-43
lines changed

2 files changed

+68
-43
lines changed

llvm/lib/Transforms/IPO/GlobalOpt.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2761,20 +2761,32 @@ static bool OptimizeNonTrivialIFuncs(
27612761
Function *Callee = Callees[I];
27622762
uint64_t CallerBits = FeatureMask[Caller];
27632763
uint64_t CalleeBits = FeatureMask[Callee];
2764-
// If the feature set of the caller implies the feature set of the
2765-
// highest priority candidate then it shall be picked. In case of
2766-
// identical sets advance the candidate index one position.
2767-
if (CallerBits == CalleeBits)
2768-
++I;
2769-
else if (!implies(CallerBits, CalleeBits)) {
2770-
// Keep advancing the candidate index as long as the caller's
2771-
// features are a subset of the current candidate's.
2772-
while (implies(CalleeBits, CallerBits)) {
2773-
if (++I == Callees.size())
2774-
break;
2775-
CalleeBits = FeatureMask[Callees[I]];
2764+
2765+
// In the case of FMV callers, we know that all higher priority callers
2766+
// than the current one did not get selected at runtime, which helps
2767+
// reason about the callees (if they have versions that mandate presence
2768+
// of the features which we already know are unavailable on this target).
2769+
if (TTI.isMultiversionedFunction(*Caller)) {
2770+
// If the feature set of the caller implies the feature set of the
2771+
// highest priority candidate then it shall be picked. In case of
2772+
// identical sets advance the candidate index one position.
2773+
if (CallerBits == CalleeBits)
2774+
++I;
2775+
else if (!implies(CallerBits, CalleeBits)) {
2776+
// Keep advancing the candidate index as long as the caller's
2777+
// features are a subset of the current candidate's.
2778+
while (implies(CalleeBits, CallerBits)) {
2779+
if (++I == Callees.size())
2780+
break;
2781+
CalleeBits = FeatureMask[Callees[I]];
2782+
}
2783+
continue;
27762784
}
2777-
continue;
2785+
} else {
2786+
// We can't reason much about non-FMV callers. Just pick the highest
2787+
// priority callee if it matches, otherwise bail.
2788+
if (I > 0 || !implies(CallerBits, CalleeBits))
2789+
continue;
27782790
}
27792791
auto &Calls = CallSites[Caller];
27802792
for (CallBase *CS : Calls)

llvm/test/Transforms/GlobalOpt/resolve-fmv-ifunc.ll

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ entry:
201201
}
202202

203203
declare i32 @test_non_fmv_caller._Maes() #6
204+
declare i32 @test_non_fmv_caller._Msm4() #7
204205
declare i32 @test_non_fmv_caller.default() #0
205206

206207
define weak_odr ptr @test_non_fmv_caller.resolver() comdat {
@@ -214,7 +215,7 @@ resolver_entry:
214215
ret ptr %test_non_fmv_caller._Maes.test_non_fmv_caller.default
215216
}
216217

217-
define i32 @caller4() #7 {
218+
define i32 @caller4() #8 {
218219
; CHECK-LABEL: define i32 @caller4(
219220
; CHECK-SAME: ) local_unnamed_addr #[[ATTR7:[0-9]+]] {
220221
; CHECK: [[CALL:%.*]] = tail call i32 @test_non_fmv_caller._Maes()
@@ -224,9 +225,19 @@ entry:
224225
ret i32 %call
225226
}
226227

227-
declare i32 @test_priority._Msve2-sha3() #8
228-
declare i32 @test_priority._Mls64Mssbs() #9
229-
declare i32 @test_priority._MflagmMlseMrng() #10
228+
define i32 @caller5() #9 {
229+
; CHECK-LABEL: define i32 @caller5(
230+
; CHECK-SAME: ) local_unnamed_addr #[[ATTR8:[0-9]+]] {
231+
; CHECK: [[CALL:%.*]] = tail call i32 @test_non_fmv_caller()
232+
;
233+
entry:
234+
%call = tail call i32 @test_non_fmv_caller()
235+
ret i32 %call
236+
}
237+
238+
declare i32 @test_priority._Msve2-sha3() #10
239+
declare i32 @test_priority._Mls64Mssbs() #11
240+
declare i32 @test_priority._MflagmMlseMrng() #12
230241
declare i32 @test_priority.default() #0
231242

232243
define weak_odr ptr @test_priority.resolver() comdat {
@@ -254,19 +265,19 @@ resolver_else2: ; preds = %resolver_else
254265
br label %common.ret
255266
}
256267

257-
define i32 @caller5._MflagmMls64MlseMrngMssbsMsve2-sha3() #11 {
258-
; CHECK-LABEL: define i32 @caller5._MflagmMls64MlseMrngMssbsMsve2-sha3(
259-
; CHECK-SAME: ) local_unnamed_addr #[[ATTR11:[0-9]+]] {
268+
define i32 @caller6._MflagmMls64MlseMrngMssbsMsve2-sha3() #13 {
269+
; CHECK-LABEL: define i32 @caller6._MflagmMls64MlseMrngMssbsMsve2-sha3(
270+
; CHECK-SAME: ) local_unnamed_addr #[[ATTR12:[0-9]+]] {
260271
; CHECK: [[CALL:%.*]] = tail call i32 @test_priority._Mls64Mssbs()
261272
;
262273
entry:
263274
%call = tail call i32 @test_priority()
264275
ret i32 %call
265276
}
266277

267-
declare i32 @test_alternative_names._Mdpb2Mfrintts() #12
268-
declare i32 @test_alternative_names._Mflagm2Mfrintts() #13
269-
declare i32 @test_alternative_names._Mrcpc2() #14
278+
declare i32 @test_alternative_names._Mdpb2Mfrintts() #14
279+
declare i32 @test_alternative_names._Mflagm2Mfrintts() #15
280+
declare i32 @test_alternative_names._Mrcpc2() #16
270281
declare i32 @test_alternative_names.default() #0
271282

272283
define weak_odr ptr @test_alternative_names.resolver() comdat {
@@ -294,38 +305,38 @@ resolver_else2: ; preds = %resolver_else
294305
br label %common.ret
295306
}
296307

297-
define i32 @caller6._Mdpb2Mfrintts() #12 {
298-
; CHECK-LABEL: define i32 @caller6._Mdpb2Mfrintts(
299-
; CHECK-SAME: ) local_unnamed_addr #[[ATTR12:[0-9]+]] {
308+
define i32 @caller7._Mdpb2Mfrintts() #14 {
309+
; CHECK-LABEL: define i32 @caller7._Mdpb2Mfrintts(
310+
; CHECK-SAME: ) local_unnamed_addr #[[ATTR13:[0-9]+]] {
300311
; CHECK: [[CALL:%.*]] = tail call i32 @test_alternative_names._Mdpb2Mfrintts()
301312
;
302313
entry:
303314
%call = tail call i32 @test_alternative_names()
304315
ret i32 %call
305316
}
306317

307-
define i32 @caller6._Mfrintts() #15 {
308-
; CHECK-LABEL: define i32 @caller6._Mfrintts(
309-
; CHECK-SAME: ) local_unnamed_addr #[[ATTR15:[0-9]+]] {
318+
define i32 @caller7._Mfrintts() #17 {
319+
; CHECK-LABEL: define i32 @caller7._Mfrintts(
320+
; CHECK-SAME: ) local_unnamed_addr #[[ATTR16:[0-9]+]] {
310321
; CHECK: [[CALL:%.*]] = tail call i32 @test_alternative_names()
311322
;
312323
entry:
313324
%call = tail call i32 @test_alternative_names()
314325
ret i32 %call
315326
}
316327

317-
define i32 @caller6._Mrcpc2() #14 {
318-
; CHECK-LABEL: define i32 @caller6._Mrcpc2(
319-
; CHECK-SAME: ) local_unnamed_addr #[[ATTR14:[0-9]+]] {
328+
define i32 @caller7._Mrcpc2() #16 {
329+
; CHECK-LABEL: define i32 @caller7._Mrcpc2(
330+
; CHECK-SAME: ) local_unnamed_addr #[[ATTR15:[0-9]+]] {
320331
; CHECK: [[CALL:%.*]] = tail call i32 @test_alternative_names._Mrcpc2()
321332
;
322333
entry:
323334
%call = tail call i32 @test_alternative_names()
324335
ret i32 %call
325336
}
326337

327-
define i32 @caller6.default() #0 {
328-
; CHECK-LABEL: define i32 @caller6.default(
338+
define i32 @caller7.default() #0 {
339+
; CHECK-LABEL: define i32 @caller7.default(
329340
; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
330341
; CHECK: [[CALL:%.*]] = tail call i32 @test_alternative_names.default()
331342
;
@@ -341,12 +352,14 @@ attributes #3 = { "fmv-features"="mops" }
341352
attributes #4 = { "fmv-features"="mops,sve2" }
342353
attributes #5 = { "fmv-features"="sme" }
343354
attributes #6 = { "fmv-features"="aes" }
344-
attributes #7 = { "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" }
345-
attributes #8 = { "fmv-features"="sve2-sha3" }
346-
attributes #9 = { "fmv-features"="ls64,ssbs" }
347-
attributes #10 = { "fmv-features"="flagm,lse,rng" }
348-
attributes #11 = { "fmv-features"="flagm,ls64,lse,rng,ssbs,sve2-sha3" }
349-
attributes #12 = { "fmv-features"="dpb2,frintts" }
350-
attributes #13 = { "fmv-features"="flagm2,frintts" }
351-
attributes #14 = { "fmv-features"="rcpc2" }
352-
attributes #15 = { "fmv-features"="frintts" }
355+
attributes #7 = { "fmv-features"="sm4" }
356+
attributes #8 = { "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" }
357+
attributes #9 = { "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,+sm4" }
358+
attributes #10 = { "fmv-features"="sve2-sha3" }
359+
attributes #11 = { "fmv-features"="ls64,ssbs" }
360+
attributes #12 = { "fmv-features"="flagm,lse,rng" }
361+
attributes #13 = { "fmv-features"="flagm,ls64,lse,rng,ssbs,sve2-sha3" }
362+
attributes #14 = { "fmv-features"="dpb2,frintts" }
363+
attributes #15 = { "fmv-features"="flagm2,frintts" }
364+
attributes #16 = { "fmv-features"="rcpc2" }
365+
attributes #17 = { "fmv-features"="frintts" }

0 commit comments

Comments
 (0)