llvm.org GIT mirror llvm / bb55f79
[IPSCCP] do not break musttail invariant (PR36485) Do not replace results of `musttail` calls with a constant if the call itself can't be removed. Do not zap returns of `musttail` callees, if the call site can't be removed and replaced with a constant. Do not zap returns of `musttail`-calling blocks, this breaks invariant too. Patch by Fedor Indutny Differential Revision: https://reviews.llvm.org/D43695 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326404 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 1 year, 6 months ago
2 changed file(s) with 113 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
222222 /// represented here for efficient lookup.
223223 SmallPtrSet MRVFunctionsTracked;
224224
225 /// MustTailFunctions - Each function here is a callee of non-removable
226 /// musttail call site.
227 SmallPtrSet MustTailCallees;
228
225229 /// TrackingIncomingArguments - This is the set of functions for whose
226230 /// arguments we make optimistic assumptions about and try to prove as
227231 /// constants.
288292 TrackedRetVals.insert(std::make_pair(F, LatticeVal()));
289293 }
290294
295 /// AddMustTailCallee - If the SCCP solver finds that this function is called
296 /// from non-removable musttail call site.
297 void AddMustTailCallee(Function *F) {
298 MustTailCallees.insert(F);
299 }
300
301 /// Returns true if the given function is called from non-removable musttail
302 /// call site.
303 bool isMustTailCallee(Function *F) {
304 return MustTailCallees.count(F);
305 }
306
291307 void AddArgumentTrackedFunction(Function *F) {
292308 TrackingIncomingArguments.insert(F);
293309 }
355371 /// values tracked by the pass.
356372 const SmallPtrSet getMRVFunctionsTracked() {
357373 return MRVFunctionsTracked;
374 }
375
376 /// getMustTailCallees - Get the set of functions which are called
377 /// from non-removable musttail call sites.
378 const SmallPtrSet getMustTailCallees() {
379 return MustTailCallees;
358380 }
359381
360382 /// markOverdefined - Mark the specified value overdefined. This
16711693 IV.isConstant() ? IV.getConstant() : UndefValue::get(V->getType());
16721694 }
16731695 assert(Const && "Constant is nullptr here!");
1696
1697 // Replacing `musttail` instructions with constant breaks `musttail` invariant
1698 // unless the call itself can be removed
1699 CallInst *CI = dyn_cast(V);
1700 if (CI && CI->isMustTailCall() && !CI->isSafeToRemove()) {
1701 CallSite CS(CI);
1702 Function *F = CS.getCalledFunction();
1703
1704 // Don't zap returns of the callee
1705 if (F)
1706 Solver.AddMustTailCallee(F);
1707
1708 DEBUG(dbgs() << " Can\'t treat the result of musttail call : " << *CI
1709 << " as a constant\n");
1710 return false;
1711 }
1712
16741713 DEBUG(dbgs() << " Constant: " << *Const << " = " << *V << '\n');
16751714
16761715 // Replaces all of the uses of a variable with uses of the constant.
18011840 if (!Solver.isArgumentTrackedFunction(&F))
18021841 return;
18031842
1804 for (BasicBlock &BB : F)
1843 // There is a non-removable musttail call site of this function. Zapping
1844 // returns is not allowed.
1845 if (Solver.isMustTailCallee(&F)) {
1846 DEBUG(dbgs() << "Can't zap returns of the function : " << F.getName()
1847 << " due to present musttail call of it\n");
1848 return;
1849 }
1850
1851 for (BasicBlock &BB : F) {
1852 if (CallInst *CI = BB.getTerminatingMustTailCall()) {
1853 DEBUG(dbgs() << "Can't zap return of the block due to present "
1854 << "musttail call : " << *CI << "\n");
1855 return;
1856 }
1857
18051858 if (auto *RI = dyn_cast(BB.getTerminator()))
18061859 if (!isa(RI->getOperand(0)))
18071860 ReturnsToZap.push_back(RI);
1861 }
18081862 }
18091863
18101864 static bool runIPSCCP(Module &M, const DataLayout &DL,
0 ; RUN: opt < %s -ipsccp -S | FileCheck %s
1 ; PR36485
2 ; musttail call result can\'t be replaced with a constant, unless the call
3 ; can be removed
4
5 declare i32 @external()
6
7 define i8* @start(i8 %v) {
8 %c1 = icmp eq i8 %v, 0
9 br i1 %c1, label %true, label %false
10 true:
11 ; CHECK: %ca = musttail call i8* @side_effects(i8 %v)
12 ; CHECK: ret i8* %ca
13 %ca = musttail call i8* @side_effects(i8 %v)
14 ret i8* %ca
15 false:
16 %c2 = icmp eq i8 %v, 1
17 br i1 %c2, label %c2_true, label %c2_false
18 c2_true:
19 %ca1 = musttail call i8* @no_side_effects(i8 %v)
20 ; CHECK: ret i8* null
21 ret i8* %ca1
22 c2_false:
23 ; CHECK: %ca2 = musttail call i8* @dont_zap_me(i8 %v)
24 ; CHECK: ret i8* %ca2
25 %ca2 = musttail call i8* @dont_zap_me(i8 %v)
26 ret i8* %ca2
27 }
28
29 define internal i8* @side_effects(i8 %v) {
30 %i1 = call i32 @external()
31
32 ; since this goes back to `start` the SCPP should be see that the return value
33 ; is always `null`.
34 ; The call can't be removed due to `external` call above, though.
35
36 ; CHECK: %ca = musttail call i8* @start(i8 %v)
37 %ca = musttail call i8* @start(i8 %v)
38
39 ; Thus the result must be returned anyway
40 ; CHECK: ret i8* %ca
41 ret i8* %ca
42 }
43
44 define internal i8* @no_side_effects(i8 %v) readonly nounwind {
45 ; The call to this function is removed, so the return value must be zapped
46 ; CHECK: ret i8* undef
47 ret i8* null
48 }
49
50 define internal i8* @dont_zap_me(i8 %v) {
51 %i1 = call i32 @external()
52
53 ; The call to this function cannot be removed due to side effects. Thus the
54 ; return value should stay as it is, and should not be zapped.
55 ; CHECK: ret i8* null
56 ret i8* null
57 }