Skip to content

Commit 9773c8b

Browse files
committed
[FnSpecialization] Allow specialization of indirect function calls exposed by specialization
1 parent da77758 commit 9773c8b

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

llvm/lib/Transforms/IPO/FunctionSpecialization.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,23 +234,33 @@ Cost InstCostVisitor::getCodeSizeSavingsForUser(Instruction *User, Value *Use,
234234

235235
Cost CodeSize = 0;
236236
auto isChainableCall = [&](Instruction *I) -> bool {
237+
if (!CallUsers || !UseEdge)
238+
return false;
237239
if (CallInst *CI = dyn_cast<CallInst>(I);
238240
CI && CI->getIntrinsicID() == llvm::Intrinsic::not_intrinsic) {
239241
LLVM_DEBUG(
240242
dbgs() << "FnSpecialization: Found constant forwarded via a call "
241243
<< *C << "\n");
242244
Function *F = CI->getCalledFunction();
243-
if (F && CallUsers && UseEdge) { // Avoid function pointers
245+
if (F) { // Avoid function pointers
244246
unsigned Idx = CI->getArgOperandNo(UseEdge);
245247
LLVM_DEBUG(dbgs() << "FnSpecialization: Function called: "
246248
<< F->getName() << " argument number: " << Idx
247249
<< "\n");
248250
(*CallUsers)[CI].first.push_back({Idx, C});
249251
(*CallUsers)[CI].second = F;
250252
return true;
253+
} else if (Use == CI->getCalledOperand()) {
254+
LLVM_DEBUG(dbgs() << "FnSpecialization: Found call to constant "
255+
"function pointer.\n");
256+
Function *CF = dyn_cast<Function>(C);
257+
assert(CF && "Indirect call to a non-Function type");
258+
(*CallUsers)[CI].second = CF;
251259
} else {
252260
LLVM_DEBUG(
253261
dbgs() << "FnSpecialization: Could not find call function.\n");
262+
unsigned Idx = CI->getArgOperandNo(UseEdge);
263+
(*CallUsers)[CI].first.push_back({Idx, C});
254264
}
255265
}
256266
return false;

llvm/test/Transforms/FunctionSpecialization/compiler-crash-60191.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ define i32 @f2(i32 %offset) {
6060
}
6161

6262
; Tests that `func` has been specialized and it didn't cause compiler crash.
63+
; CHECK-DAG: func.specialized.4
64+
; CHECK-DAG: func.specialized.5
6365
; CHECK-DAG: func.specialized.1
64-
; CHECK-DAG: func.specialized.2
65-
; CHECK-DAG: func.specialized.3
6666

llvm/test/Transforms/FunctionSpecialization/track-ptr-return.ll

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ entry:
4848
; CHECK-NEXT: [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true)
4949
; CHECK-NEXT: [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false)
5050
; CHECK-NEXT: [[C1:%.*]] = call i64 @compute.specialized.3(ptr @plus)
51-
; CHECK-NEXT: [[C2:%.*]] = call i64 @compute.specialized.4(ptr @minus)
52-
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[C1]], [[C2]]
53-
; CHECK-NEXT: ret i64 [[ADD]]
51+
; CHECK-NEXT: [[C2:%.*]] = call i64 @compute.specialized.5(ptr @minus)
52+
; CHECK-NEXT: ret i64 2
5453
;
5554
;
5655
; CHECK-LABEL: define ptr @select_op(
@@ -87,15 +86,27 @@ entry:
8786
; CHECK-LABEL: define internal i64 @compute.specialized.3(
8887
; CHECK-SAME: ptr [[OP:%.*]]) {
8988
; CHECK-NEXT: [[ENTRY:.*:]]
90-
; CHECK-NEXT: [[RES:%.*]] = call i64 @plus(i64 1)
91-
; CHECK-NEXT: ret i64 [[RES]]
89+
; CHECK-NEXT: [[RES:%.*]] = call i64 @plus.specialized.4(i64 1)
90+
; CHECK-NEXT: ret i64 poison
9291
;
9392
;
94-
; CHECK-LABEL: define internal i64 @compute.specialized.4(
93+
; CHECK-LABEL: define internal i64 @plus.specialized.4(
94+
; CHECK-SAME: i64 [[X:%.*]]) {
95+
; CHECK-NEXT: [[ENTRY:.*:]]
96+
; CHECK-NEXT: ret i64 poison
97+
;
98+
;
99+
; CHECK-LABEL: define internal i64 @compute.specialized.5(
95100
; CHECK-SAME: ptr [[OP:%.*]]) {
96101
; CHECK-NEXT: [[ENTRY:.*:]]
97-
; CHECK-NEXT: [[RES:%.*]] = call i64 @minus(i64 1)
98-
; CHECK-NEXT: ret i64 [[RES]]
102+
; CHECK-NEXT: [[RES:%.*]] = call i64 @minus.specialized.6(i64 1)
103+
; CHECK-NEXT: ret i64 poison
104+
;
105+
;
106+
; CHECK-LABEL: define internal i64 @minus.specialized.6(
107+
; CHECK-SAME: i64 [[X:%.*]]) {
108+
; CHECK-NEXT: [[ENTRY:.*:]]
109+
; CHECK-NEXT: ret i64 poison
99110
;
100111
;
101112
; NOLIT-LABEL: define i64 @main() {

0 commit comments

Comments
 (0)