From 0353526ed11fc308cf34465e4d14a6cadf8cfb62 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 21 Mar 2008 05:57:20 +0000 Subject: [PATCH] Enable support for returning two long-double values in ST(0)/ST(1). This allows us to compile fp-stack-2results.ll into: _test: fldz fld1 ret which returns 1 in ST(0) and 0 in ST(1). This is needed for x86-64 _Complex long double. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48632 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86CallingConv.td | 6 +++--- lib/Target/X86/X86FloatingPoint.cpp | 5 +---- test/CodeGen/X86/fp-stack-2results.ll | 11 +++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 test/CodeGen/X86/fp-stack-2results.ll diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td index 4f25f1f27a1..70f18c57897 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -38,15 +38,15 @@ def RetCC_X86Common : CallingConv<[ CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[MM0]>>, // Long double types are always returned in ST0 (even with SSE). - CCIfType<[f80], CCAssignToReg<[ST0]>> + CCIfType<[f80], CCAssignToReg<[ST0, ST1]>> ]>; // X86-32 C return-value convention. def RetCC_X86_32_C : CallingConv<[ // The X86-32 calling convention returns FP values in ST0, otherwise it is the // same as the common X86 calling conv. - CCIfType<[f32], CCAssignToReg<[ST0]>>, - CCIfType<[f64], CCAssignToReg<[ST0]>>, + CCIfType<[f32], CCAssignToReg<[ST0, ST1]>>, + CCIfType<[f64], CCAssignToReg<[ST0, ST1]>>, CCDelegateTo ]>; diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index ca965375f2a..d9ab1ed4151 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -1053,9 +1053,6 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) { return; } - assert(0 && "TODO: This code should work, but has never been tested." - "Test it when we have multiple FP return values working"); - // Otherwise, we are returning two values: // 2) If returning the same value for both, we only have one thing in the FP // stack. Consider: RET FP1, FP1 @@ -1083,7 +1080,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) { /// 4) Finally, FirstFPRegOp must be in ST(0) and SecondFPRegOp must be in /// ST(1). Just remove both from our understanding of the stack and return. assert(getStackEntry(0) == FirstFPRegOp && "Unknown regs live"); - assert(getStackEntry(0) == SecondFPRegOp && "Unknown regs live"); + assert(getStackEntry(1) == SecondFPRegOp && "Unknown regs live"); StackTop = 0; return; } diff --git a/test/CodeGen/X86/fp-stack-2results.ll b/test/CodeGen/X86/fp-stack-2results.ll new file mode 100644 index 00000000000..b44d3dd5114 --- /dev/null +++ b/test/CodeGen/X86/fp-stack-2results.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep fldz +; RUN: llvm-as < %s | llc -march=x86-64 | grep fld1 + +; This is basically this code on x86-64: +; _Complex long double test() { return 1.0; } +define {x86_fp80, x86_fp80} @test() { + %A = fpext double 1.0 to x86_fp80 + %B = fpext double 0.0 to x86_fp80 + ret x86_fp80 %A, x86_fp80 %B +} + -- 2.34.1