Missing a getNumOperands check.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 2 Nov 2007 01:26:22 +0000 (01:26 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 2 Nov 2007 01:26:22 +0000 (01:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43630 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/2007-11-01-ISelCrash.ll [new file with mode: 0644]

index 3180e647033e3b5f470ee6bf99424bcd1ca664f6..7bd01b09cce8ae6ea89f1bafa4526ed1b4d03a16 100644 (file)
@@ -1451,42 +1451,45 @@ unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize,
 }
 
 /// IsEligibleForTailCallElimination - Check to see whether the next instruction
-// following the call is a return. A function is eligible if caller/callee
-// calling conventions match, currently only fastcc supports tail calls, and the
-// function CALL is immediatly followed by a RET.
+/// following the call is a return. A function is eligible if caller/callee
+/// calling conventions match, currently only fastcc supports tail calls, and
+/// the function CALL is immediatly followed by a RET.
 bool X86TargetLowering::IsEligibleForTailCallOptimization(SDOperand Call,
                                                       SDOperand Ret,
                                                       SelectionDAG& DAG) const {
-  bool IsEligible = false;
+  if (!PerformTailCallOpt)
+    return false;
 
   // Check whether CALL node immediatly preceeds the RET node and whether the
   // return uses the result of the node or is a void return.
-  if ((Ret.getNumOperands() == 1 && 
-       (Ret.getOperand(0)== SDOperand(Call.Val,1) ||
-        Ret.getOperand(0)== SDOperand(Call.Val,0))) ||
-      (Ret.getOperand(0)== SDOperand(Call.Val,Call.Val->getNumValues()-1) &&
-       Ret.getOperand(1)== SDOperand(Call.Val,0))) {
+  unsigned NumOps = Ret.getNumOperands();
+  if ((NumOps == 1 && 
+       (Ret.getOperand(0) == SDOperand(Call.Val,1) ||
+        Ret.getOperand(0) == SDOperand(Call.Val,0))) ||
+      (NumOps == 2 &&
+       Ret.getOperand(0) == SDOperand(Call.Val,Call.Val->getNumValues()-1) &&
+       Ret.getOperand(1) == SDOperand(Call.Val,0))) {
     MachineFunction &MF = DAG.getMachineFunction();
     unsigned CallerCC = MF.getFunction()->getCallingConv();
     unsigned CalleeCC = cast<ConstantSDNode>(Call.getOperand(1))->getValue();
     if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) {
       SDOperand Callee = Call.getOperand(4);
       // On elf/pic %ebx needs to be livein.
-      if(getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
-         Subtarget->isPICStyleGOT()) {
-        // Can only do local tail calls with PIC.
-        GlobalValue * GV = 0;
-        GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
-        if(G != 0 &&
-           (GV = G->getGlobal()) &&
-           (GV->hasHiddenVisibility() || GV->hasProtectedVisibility()))
-          IsEligible=true;
-      } else {
-        IsEligible=true;
-      }
+      if (getTargetMachine().getRelocationModel() != Reloc::PIC_ ||
+          !Subtarget->isPICStyleGOT())
+        return true;
+
+      // Can only do local tail calls with PIC.
+      GlobalValue * GV = 0;
+      GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
+      if(G != 0 &&
+         (GV = G->getGlobal()) &&
+         (GV->hasHiddenVisibility() || GV->hasProtectedVisibility()))
+        return true;
     }
   }
-  return IsEligible;
+
+  return false;
 }
 
 SDOperand X86TargetLowering::LowerX86_TailCallTo(SDOperand Op, 
diff --git a/test/CodeGen/X86/2007-11-01-ISelCrash.ll b/test/CodeGen/X86/2007-11-01-ISelCrash.ll
new file mode 100644 (file)
index 0000000..8994bf9
--- /dev/null
@@ -0,0 +1,10 @@
+        %"struct.K::JL" = type <{ i8 }>
+        %struct.jv = type { i64 }
+
+declare fastcc i64 @f(i32, %"struct.K::JL"*, i8*, i8*, %struct.jv*)
+
+define void @t(%"struct.K::JL"* %obj, i8* %name, i8* %sig, %struct.jv* %args) {
+entry:
+        %tmp5 = tail call fastcc i64 @f( i32 1, %"struct.K::JL"* %obj, i8* %name, i8* %sig, %struct.jv* %args )         ; <i64> [#uses=0]
+        ret void
+}