mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Fix an oops in x86 sibcall optimization. If the ByVal callee argument is itself passed as a pointer, then it's obviously not safe to do a tail call.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97797 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2d4e4af45e
commit
4cae133780
@ -2235,7 +2235,8 @@ static
|
||||
bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
|
||||
MachineFrameInfo *MFI, const MachineRegisterInfo *MRI,
|
||||
const X86InstrInfo *TII) {
|
||||
int FI;
|
||||
unsigned Bytes = Arg.getValueType().getSizeInBits() / 8;
|
||||
int FI = INT_MAX;
|
||||
if (Arg.getOpcode() == ISD::CopyFromReg) {
|
||||
unsigned VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
|
||||
if (!VR || TargetRegisterInfo::isPhysicalRegister(VR))
|
||||
@ -2251,25 +2252,30 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
|
||||
if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r) &&
|
||||
Def->getOperand(1).isFI()) {
|
||||
FI = Def->getOperand(1).getIndex();
|
||||
if (MFI->getObjectSize(FI) != Flags.getByValSize())
|
||||
return false;
|
||||
Bytes = Flags.getByValSize();
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg);
|
||||
if (!Ld)
|
||||
} else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
|
||||
if (Flags.isByVal())
|
||||
// ByVal argument is passed in as a pointer but it's now being
|
||||
// derefernced. e.g.
|
||||
// define @foo(%struct.X* %A) {
|
||||
// tail call @bar(%struct.X* byval %A)
|
||||
// }
|
||||
return false;
|
||||
SDValue Ptr = Ld->getBasePtr();
|
||||
FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
|
||||
if (!FINode)
|
||||
return false;
|
||||
FI = FINode->getIndex();
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
|
||||
assert(FI != INT_MAX);
|
||||
if (!MFI->isFixedObjectIndex(FI))
|
||||
return false;
|
||||
return Offset == MFI->getObjectOffset(FI);
|
||||
return Offset == MFI->getObjectOffset(FI) && Bytes == MFI->getObjectSize(FI);
|
||||
}
|
||||
|
||||
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
|
||||
|
@ -195,3 +195,24 @@ bb2:
|
||||
}
|
||||
|
||||
declare i32 @foo6(i32, i32, %struct.t* byval align 4)
|
||||
|
||||
; rdar://r7717598
|
||||
%struct.ns = type { i32, i32 }
|
||||
%struct.cp = type { float, float }
|
||||
|
||||
define %struct.ns* @t13(%struct.cp* %yy) nounwind ssp {
|
||||
; 32: t13:
|
||||
; 32-NOT: jmp
|
||||
; 32: call
|
||||
; 32: ret
|
||||
|
||||
; 64: t13:
|
||||
; 64-NOT: jmp
|
||||
; 64: call
|
||||
; 64: ret
|
||||
entry:
|
||||
%0 = tail call fastcc %struct.ns* @foo7(%struct.cp* byval align 4 %yy, i8 signext 0) nounwind
|
||||
ret %struct.ns* %0
|
||||
}
|
||||
|
||||
declare fastcc %struct.ns* @foo7(%struct.cp* byval align 4, i8 signext) nounwind ssp
|
||||
|
Loading…
Reference in New Issue
Block a user