diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2010-03-05 08:38:04 +0000 | 
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2010-03-05 08:38:04 +0000 | 
| commit | 4cae133780aa35b0f40f382286b2c0eb57369fee (patch) | |
| tree | 580aa1cea2f15a1943d3175cd80d122048cfe8d5 | |
| parent | 2d4e4af45e074b6d712ac6fc6ab3e63456e1e24e (diff) | |
| download | external_llvm-4cae133780aa35b0f40f382286b2c0eb57369fee.zip external_llvm-4cae133780aa35b0f40f382286b2c0eb57369fee.tar.gz external_llvm-4cae133780aa35b0f40f382286b2c0eb57369fee.tar.bz2 | |
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
| -rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 22 | ||||
| -rw-r--r-- | test/CodeGen/X86/tailcall2.ll | 21 | 
2 files changed, 35 insertions, 8 deletions
| diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index ca4b902..350ef5a 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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 diff --git a/test/CodeGen/X86/tailcall2.ll b/test/CodeGen/X86/tailcall2.ll index 80bab61..90315fd 100644 --- a/test/CodeGen/X86/tailcall2.ll +++ b/test/CodeGen/X86/tailcall2.ll @@ -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 | 
