From 446ff28df1242fcd11ce1df18af9c944afdcbdd3 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 25 Sep 2012 05:32:34 +0000 Subject: [PATCH] Fix an illegal tailcall opt where the callee returns a double via xmm while caller returns x86_fp80 via st0. rdar://12229511 llvm-svn: 164588 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 10 ++++++++- llvm/lib/Target/X86/X86ISelLowering.h | 1 + llvm/test/CodeGen/X86/tailcall-64.ll | 29 ++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index b2b94794f205..cb803f891576 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2198,7 +2198,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Check if it's really possible to do a tail call. isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg, SR != NotStructReturn, - MF.getFunction()->hasStructRetAttr(), + MF.getFunction()->hasStructRetAttr(), CLI.RetTy, Outs, OutVals, Ins, DAG); // Sibcalls are automatically detected tailcalls which do not require @@ -2718,6 +2718,7 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, bool isVarArg, bool isCalleeStructRet, bool isCallerStructRet, + Type *RetTy, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SmallVectorImpl &Ins, @@ -2729,6 +2730,13 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, // If -tailcallopt is specified, make fastcc functions tail-callable. const MachineFunction &MF = DAG.getMachineFunction(); const Function *CallerF = DAG.getMachineFunction().getFunction(); + + // If the function return type is x86_fp80 and the callee return type is not, + // then the FP_EXTEND of the call result is not a nop. It's not safe to + // perform a tailcall optimization here. + if (CallerF->getReturnType()->isX86_FP80Ty() && !RetTy->isX86_FP80Ty()) + return false; + CallingConv::ID CallerCC = CallerF->getCallingConv(); bool CCMatch = CallerCC == CalleeCC; diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 653654f28ac4..a5773294f8c2 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -744,6 +744,7 @@ namespace llvm { bool isVarArg, bool isCalleeStructRet, bool isCallerStructRet, + Type *RetTy, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SmallVectorImpl &Ins, diff --git a/llvm/test/CodeGen/X86/tailcall-64.ll b/llvm/test/CodeGen/X86/tailcall-64.ll index adc862006082..ecc253ba587e 100644 --- a/llvm/test/CodeGen/X86/tailcall-64.ll +++ b/llvm/test/CodeGen/X86/tailcall-64.ll @@ -1,6 +1,4 @@ -; RUN: llc < %s | FileCheck %s -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-apple-darwin11.4.0" +; RUN: llc -mtriple=x86_64-apple-macosx -mcpu=core2 < %s | FileCheck %s declare i64 @testi() @@ -132,3 +130,28 @@ entry: %call = tail call i32 (i8*, ...)* %0(i8* null, i32 0, i32 0, i32 0, i32 0, i32 0) nounwind ret i32 %call } + +define x86_fp80 @fp80_call(x86_fp80 %x) nounwind { +entry: +; CHECK: fp80_call: +; CHECK: jmp _fp80_callee + %call = tail call x86_fp80 @fp80_callee(x86_fp80 %x) nounwind + ret x86_fp80 %call +} + +declare x86_fp80 @fp80_callee(x86_fp80) + +; rdar://12229511 +define x86_fp80 @trunc_fp80(x86_fp80 %x) nounwind { +entry: +; CHECK: trunc_fp80 +; CHECK: callq _trunc +; CHECK-NOT: jmp _trunc +; CHECK: ret + %conv = fptrunc x86_fp80 %x to double + %call = tail call double @trunc(double %conv) nounwind readnone + %conv1 = fpext double %call to x86_fp80 + ret x86_fp80 %conv1 +} + +declare double @trunc(double) nounwind readnone