From: Keno Fischer Date: Wed, 20 Aug 2014 19:00:37 +0000 (+0000) Subject: Do not insert a tail call when returning multiple values on X86 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4b1cddbaf030af33fc25259b4afefb56141a8a59;p=oota-llvm.git Do not insert a tail call when returning multiple values on X86 Summary: This fixes http://llvm.org/bugs/show_bug.cgi?id=19530. The problem is that X86ISelLowering erroneously thought the third call was eligible for tail call elimination. It would have been if it's return value was actually the one returned by the calling function, but here that is not the case and additional values are being returned. Test Plan: Test case from the original bug report is included. Reviewers: rafael Reviewed By: rafael Subscribers: rafael, llvm-commits Differential Revision: http://reviews.llvm.org/D4968 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216117 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index af8e1a18808..9cb9e6abbef 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2052,6 +2052,13 @@ bool X86TargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const { UI != UE; ++UI) { if (UI->getOpcode() != X86ISD::RET_FLAG) return false; + // If we are returning more than one value, we can definitely + // not make a tail call see PR19530 + if (UI->getNumOperands() > 4) + return false; + if (UI->getNumOperands() == 4 && + UI->getOperand(UI->getNumOperands()-1).getValueType() != MVT::Glue) + return false; HasRet = true; } diff --git a/test/CodeGen/X86/tailcall-multiret.ll b/test/CodeGen/X86/tailcall-multiret.ll new file mode 100644 index 00000000000..a77a59cd70b --- /dev/null +++ b/test/CodeGen/X86/tailcall-multiret.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=x86_64-linux-gnu -mcpu=core2 | FileCheck %s +; See PR19530 +declare double @llvm.powi.f64(double %Val, i32 %power) +define <3 x double> @julia_foo17589(i32 %arg) { + %tmp1 = call double @llvm.powi.f64(double 1.000000e+00, i32 %arg) +; CHECK: callq __powidf2 + %tmp2 = insertelement <3 x double> undef, double %tmp1, i32 0 + %tmp3 = call double @llvm.powi.f64(double 2.000000e+00, i32 %arg) +; CHECK: callq __powidf2 + %tmp4 = insertelement <3 x double> %tmp2, double %tmp3, i32 1 + %tmp5 = call double @llvm.powi.f64(double 3.000000e+00, i32 %arg) +; CHECK: callq __powidf2 + %tmp6 = insertelement <3 x double> %tmp4, double %tmp5, i32 2 +; CHECK-NOT: TAILCALL + ret <3 x double> %tmp6 +}