Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit e49f893

Browse files
committed
Merging r309343:
------------------------------------------------------------------------ r309343 | rnk | 2017-07-27 17:58:35 -0700 (Thu, 27 Jul 2017) | 16 lines [X86] Fix latent bug in sibcall eligibility logic The X86 tail call eligibility logic was correct when it was written, but the addition of inalloca and argument copy elision broke its assumptions. It was assuming that fixed stack objects were immutable. Currently, we aim to emit a tail call if no arguments have to be re-arranged in memory. This code would trace the outgoing argument values back to check if they are loads from an incoming stack object. If the stack argument is immutable, then we won't need to store it back to the stack when we tail call. Fortunately, stack objects track their mutability, so we can just make the obvious check to fix the bug. This was http://crbug.com/749826 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@309577 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 56b1ef7 commit e49f893

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,6 +3984,13 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
39843984
if (Offset != MFI.getObjectOffset(FI))
39853985
return false;
39863986

3987+
// If this is not byval, check that the argument stack object is immutable.
3988+
// inalloca and argument copy elision can create mutable argument stack
3989+
// objects. Byval objects can be mutated, but a byval call intends to pass the
3990+
// mutated memory.
3991+
if (!Flags.isByVal() && !MFI.isImmutableObjectIndex(FI))
3992+
return false;
3993+
39873994
if (VA.getLocVT().getSizeInBits() > Arg.getValueSizeInBits()) {
39883995
// If the argument location is wider than the argument type, check that any
39893996
// extension flags match.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: llc < %s | FileCheck %s
2+
3+
; Make sure we check that forwarded memory arguments are not modified when tail
4+
; calling. inalloca and copy arg elimination make argument slots mutable.
5+
6+
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
7+
target triple = "i386-pc-windows-msvc19.0.24215"
8+
9+
declare x86_stdcallcc void @tail_std(i32)
10+
declare void @capture(i32*)
11+
12+
define x86_thiscallcc void @inalloca(i32* %this, i32* inalloca %args) {
13+
entry:
14+
%val = load i32, i32* %args
15+
store i32 0, i32* %args
16+
tail call x86_stdcallcc void @tail_std(i32 %val)
17+
ret void
18+
}
19+
20+
; CHECK-LABEL: _inalloca: # @inalloca
21+
; CHECK: movl 4(%esp), %[[reg:[^ ]*]]
22+
; CHECK: movl $0, 4(%esp)
23+
; CHECK: pushl %[[reg]]
24+
; CHECK: calll _tail_std@4
25+
; CHECK: retl $4
26+
27+
define x86_stdcallcc void @copy_elide(i32 %arg) {
28+
entry:
29+
%arg.ptr = alloca i32
30+
store i32 %arg, i32* %arg.ptr
31+
call void @capture(i32* %arg.ptr)
32+
tail call x86_stdcallcc void @tail_std(i32 %arg)
33+
ret void
34+
}
35+
36+
; CHECK-LABEL: _copy_elide@4: # @copy_elide
37+
; CHECK: leal {{[0-9]+}}(%esp), %[[reg:[^ ]*]]
38+
; CHECK: pushl %[[reg]]
39+
; CHECK: calll _capture
40+
; ...
41+
; CHECK: calll _tail_std@4
42+
; CHECK: retl $4

0 commit comments

Comments
 (0)