llvm.org GIT mirror llvm / 0df9abb
Fix PR7272 in -tailcallelim instead of the inliner The -tailcallelim pass should be checking if byval or inalloca args can be captured before marking calls as tail calls. This was the real root cause of PR7272. With a better fix in place, revert the inliner change from r105255. The test case it introduced still passes and has been moved to test/Transforms/Inline/byval-tail-call.ll. Reviewers: chandlerc Differential Revision: http://reviews.llvm.org/D3403 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206789 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 5 years ago
5 changed file(s) with 56 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
203203 }
204204 }
205205
206 // If any byval or inalloca args are captured, exit. They are also allocated
207 // in our stack frame.
208 for (Argument &Arg : F.args()) {
209 if (Arg.hasByValOrInAllocaAttr())
210 PointerMayBeCaptured(&Arg, &ACT);
211 if (ACT.Captured)
212 return false;
213 }
214
206215 // Second pass, change any tail recursive calls to loops.
207216 //
208217 // FIXME: The code generator produces really bad code when an 'escaping
585585 if (CS.isByValArgument(ArgNo)) {
586586 ActualArg = HandleByValArgument(ActualArg, TheCall, CalledFunc, IFI,
587587 CalledFunc->getParamAlignment(ArgNo+1));
588
589 // Calls that we inline may use the new alloca, so we need to clear
590 // their 'tail' flags if HandleByValArgument introduced a new alloca and
591 // the callee has calls.
592 if (ActualArg != *AI) {
593 MustClearTailCallFlags = true;
588 if (ActualArg != *AI)
594589 ByValInit.push_back(std::make_pair(ActualArg, (Value*) *AI));
595 }
596
597590 }
598591
599592 VMap[I] = ActualArg;
+0
-25
test/Transforms/Inline/2010-05-31-ByvalTailcall.ll less more
None ; RUN: opt < %s -tailcallelim -inline -instcombine -dse -S | FileCheck %s
1 ; PR7272
2
3 ; When inlining through a byval call site, the inliner creates allocas which may
4 ; be used by inlined calls, so any inlined calls need to have their 'tail' flags
5 ; cleared. If not then you can get nastiness like with this testcase, where the
6 ; (inlined) call to 'ext' in 'foo' was being passed an uninitialized value.
7
8 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
9 target triple = "i386-pc-linux-gnu"
10
11 declare void @ext(i32*)
12
13 define void @bar(i32* byval %x) {
14 call void @ext(i32* %x)
15 ret void
16 }
17
18 define void @foo(i32* %x) {
19 ; CHECK-LABEL: define void @foo(
20 ; CHECK: llvm.lifetime.start
21 ; CHECK: store i32 %2, i32* %x
22 call void @bar(i32* byval %x)
23 ret void
24 }
0 ; RUN: opt < %s -tailcallelim -inline -instcombine -dse -S | FileCheck %s
1 ; PR7272
2
3 ; Calls that capture byval parameters cannot be marked as tail calls. Other
4 ; tails that don't capture byval parameters can still be tail calls.
5
6 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
7 target triple = "i386-pc-linux-gnu"
8
9 declare void @ext(i32*)
10
11 define void @bar(i32* byval %x) {
12 call void @ext(i32* %x)
13 ret void
14 }
15
16 define void @foo(i32* %x) {
17 ; CHECK-LABEL: define void @foo(
18 ; CHECK: llvm.lifetime.start
19 ; CHECK: store i32 %2, i32* %x
20 call void @bar(i32* byval %x)
21 ret void
22 }
23
24 define internal void @qux(i32* byval %x) {
25 call void @ext(i32* %x)
26 tail call void @ext(i32* null)
27 ret void
28 }
29 define void @frob(i32* %x) {
30 ; CHECK-LABEL: define void @frob(
31 ; CHECK: alloca i32
32 ; CHECK: {{^ *}}call void @ext(
33 ; CHECK: tail call void @ext(i32* null)
34 ; CHECK: ret void
35 tail call void @qux(i32* byval %x)
36 ret void
37 }
142142 call void @noarg()
143143 ret i32* null
144144 }
145
146 ; Don't tail call if a byval arg is captured.
147 define void @test9(i32* byval %a) {
148 ; CHECK-LABEL: define void @test9(
149 ; CHECK: {{^ *}}call void @use(
150 call void @use(i32* %a)
151 ret void
152 }