Skip to content

Commit 9bd6042

Browse files
committed
Directly return promoted direct call instead of rely on stripPointerCast.
Summary: stripPointerCast is not reliably returning the value that's being type-casted. Instead it may look further at function attributes to further propagate the value. Instead of relying on stripPOintercast, the more reliable solution is to directly use the pointer to the promoted direct call. Reviewers: tejohnson, davidxl Reviewed By: tejohnson Subscribers: llvm-commits, sanjoy Differential Revision: https://reviews.llvm.org/D38603 llvm-svn: 315077
1 parent afe5057 commit 9bd6042

File tree

4 files changed

+50
-11
lines changed

4 files changed

+50
-11
lines changed

llvm/lib/Transforms/IPO/SampleProfile.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,8 @@ bool SampleProfileLoader::inlineHotFunctions(
790790
// as a result, we do not have profile info for the branch
791791
// probability. We set the probability to 80% taken to indicate
792792
// that the static call is likely taken.
793-
Instruction *DI = dyn_cast<Instruction>(
794-
promoteIndirectCall(I, R->getValue(), 80, 100, false, ORE)
795-
->stripPointerCasts());
793+
Instruction *DI = promoteIndirectCall(
794+
I, R->getValue(), 80, 100, false, ORE);
796795
PromotedInsns.insert(I);
797796
// If profile mismatches, we should not attempt to inline DI.
798797
if ((isa<CallInst>(DI) || isa<InvokeInst>(DI)) &&

llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -461,11 +461,13 @@ static Instruction *insertCallRetCast(const Instruction *Inst,
461461
// MergeBB is the bottom BB of the if-then-else-diamond after the
462462
// transformation. For invoke instruction, the edges from DirectCallBB and
463463
// IndirectCallBB to MergeBB are removed before this call (during
464-
// createIfThenElse).
464+
// createIfThenElse). Stores the pointer to the Instruction that cast
465+
// the direct call in \p CastInst.
465466
static Instruction *createDirectCallInst(const Instruction *Inst,
466467
Function *DirectCallee,
467468
BasicBlock *DirectCallBB,
468-
BasicBlock *MergeBB) {
469+
BasicBlock *MergeBB,
470+
Instruction *&CastInst) {
469471
Instruction *NewInst = Inst->clone();
470472
if (CallInst *CI = dyn_cast<CallInst>(NewInst)) {
471473
CI->setCalledFunction(DirectCallee);
@@ -499,7 +501,8 @@ static Instruction *createDirectCallInst(const Instruction *Inst,
499501
}
500502
}
501503

502-
return insertCallRetCast(Inst, NewInst, DirectCallee);
504+
CastInst = insertCallRetCast(Inst, NewInst, DirectCallee);
505+
return NewInst;
503506
}
504507

505508
// Create a PHI to unify the return values of calls.
@@ -559,15 +562,17 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst,
559562
createIfThenElse(Inst, DirectCallee, Count, TotalCount, &DirectCallBB,
560563
&IndirectCallBB, &MergeBB);
561564

565+
// If the return type of the NewInst is not the same as the Inst, a CastInst
566+
// is needed for type casting. Otherwise CastInst is the same as NewInst.
567+
Instruction *CastInst = nullptr;
562568
Instruction *NewInst =
563-
createDirectCallInst(Inst, DirectCallee, DirectCallBB, MergeBB);
569+
createDirectCallInst(Inst, DirectCallee, DirectCallBB, MergeBB, CastInst);
564570

565571
if (AttachProfToDirectCall) {
566572
SmallVector<uint32_t, 1> Weights;
567573
Weights.push_back(Count);
568574
MDBuilder MDB(NewInst->getContext());
569-
if (Instruction *DI = dyn_cast<Instruction>(NewInst->stripPointerCasts()))
570-
DI->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
575+
NewInst->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
571576
}
572577

573578
// Move Inst from MergeBB to IndirectCallBB.
@@ -589,10 +594,10 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst,
589594
// We don't need to update the operand from NormalDest for DirectCallBB.
590595
// Pass nullptr here.
591596
fixupPHINodeForNormalDest(Inst, II->getNormalDest(), MergeBB,
592-
IndirectCallBB, NewInst);
597+
IndirectCallBB, CastInst);
593598
}
594599

595-
insertCallRetPHI(Inst, NewInst, DirectCallee);
600+
insertCallRetPHI(Inst, CastInst, DirectCallee);
596601

597602
DEBUG(dbgs() << "\n== Basic Blocks After ==\n");
598603
DEBUG(dbgs() << *BB << *DirectCallBB << *IndirectCallBB << *MergeBB << "\n");

llvm/test/Transforms/SampleProfile/Inputs/indirect-call.prof

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ test_norecursive_inline:3000:0
2424
test_noinline_bitcast:3000:0
2525
1: foo_direct_i32:3000
2626
1: 3000
27+
return_arg_caller:3000:0
28+
1: foo_inline1:3000
29+
11: 3000
30+
2: return_arg:3000
31+
1: 3000

llvm/test/Transforms/SampleProfile/indirect-call.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,32 @@ define void @test_norecursive_inline() !dbg !24 {
9292
ret void
9393
}
9494

95+
define i32* @return_arg(i32* readnone returned) !dbg !29{
96+
ret i32* %0
97+
}
98+
99+
; CHECK-LABEL: @return_arg_caller
100+
; When the promoted indirect call returns a parameter that was defined by the
101+
; return value of a previous direct call. Checks both direct call and promoted
102+
; indirect call are inlined.
103+
define i32* @return_arg_caller(i32* (i32*)* nocapture) !dbg !30{
104+
; CHECK-NOT: call i32* @foo_inline1
105+
; CHECK: if.true.direct_targ:
106+
; CHECK-NOT: call
107+
; CHECK: if.false.orig_indirect:
108+
; CHECK: call
109+
%2 = call i32* @foo_inline1(i32* null), !dbg !31
110+
%cmp = icmp ne i32* %2, null
111+
br i1 %cmp, label %then, label %else
112+
113+
then:
114+
%3 = tail call i32* %0(i32* %2), !dbg !32
115+
ret i32* %3
116+
117+
else:
118+
ret i32* null
119+
}
120+
95121
@x = global i32 0, align 4
96122
@y = global void ()* null, align 8
97123

@@ -176,3 +202,7 @@ define void @test_direct() !dbg !22 {
176202
!26 = distinct !DISubprogram(name: "test_noinline_bitcast", scope: !1, file: !1, line: 12, unit: !0)
177203
!27 = !DILocation(line: 13, scope: !26)
178204
!28 = distinct !DISubprogram(name: "foo_direct_i32", scope: !1, file: !1, line: 11, unit: !0)
205+
!29 = distinct !DISubprogram(name: "return_arg", scope: !1, file: !1, line: 11, unit: !0)
206+
!30 = distinct !DISubprogram(name: "return_arg_caller", scope: !1, file: !1, line: 11, unit: !0)
207+
!31 = !DILocation(line: 12, scope: !30)
208+
!32 = !DILocation(line: 13, scope: !30)

0 commit comments

Comments
 (0)