[llvm-commits] [llvm] r160725 - in /llvm/trunk: lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/inreg.ll
Rafael Espindola
rafael.espindola at gmail.com
Wed Jul 25 06:41:11 PDT 2012
Author: rafael
Date: Wed Jul 25 08:41:10 2012
New Revision: 160725
URL: http://llvm.org/viewvc/llvm-project?rev=160725&view=rev
Log:
When a return struct pointer is passed in registers, the called has nothing
to pop.
Modified:
llvm/trunk/lib/Target/X86/X86FastISel.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/test/CodeGen/X86/inreg.ll
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=160725&r1=160724&r2=160725&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Jul 25 08:41:10 2012
@@ -1527,6 +1527,8 @@
return 0;
if (!CS.paramHasAttr(1, Attribute::StructRet))
return 0;
+ if (CS.paramHasAttr(1, Attribute::InReg))
+ return 0;
return 4;
}
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=160725&r1=160724&r2=160725&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Jul 25 08:41:10 2012
@@ -1717,21 +1717,37 @@
/// CallIsStructReturn - Determines whether a call uses struct return
/// semantics.
-static bool CallIsStructReturn(const SmallVectorImpl<ISD::OutputArg> &Outs) {
+enum StructReturnType {
+ NotStructReturn,
+ RegStructReturn,
+ StackStructReturn
+};
+static StructReturnType
+callIsStructReturn(const SmallVectorImpl<ISD::OutputArg> &Outs) {
if (Outs.empty())
- return false;
+ return NotStructReturn;
- return Outs[0].Flags.isSRet();
+ const ISD::ArgFlagsTy &Flags = Outs[0].Flags;
+ if (!Flags.isSRet())
+ return NotStructReturn;
+ if (Flags.isInReg())
+ return RegStructReturn;
+ return StackStructReturn;
}
/// ArgsAreStructReturn - Determines whether a function uses struct
/// return semantics.
-static bool
-ArgsAreStructReturn(const SmallVectorImpl<ISD::InputArg> &Ins) {
+static StructReturnType
+argsAreStructReturn(const SmallVectorImpl<ISD::InputArg> &Ins) {
if (Ins.empty())
- return false;
+ return NotStructReturn;
- return Ins[0].Flags.isSRet();
+ const ISD::ArgFlagsTy &Flags = Ins[0].Flags;
+ if (!Flags.isSRet())
+ return NotStructReturn;
+ if (Flags.isInReg())
+ return RegStructReturn;
+ return StackStructReturn;
}
/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
@@ -2072,7 +2088,7 @@
FuncInfo->setBytesToPopOnReturn(0); // Callee pops nothing.
// If this is an sret function, the return should pop the hidden pointer.
if (!Is64Bit && !IsTailCallConvention(CallConv) && !IsWindows &&
- ArgsAreStructReturn(Ins))
+ argsAreStructReturn(Ins) == StackStructReturn)
FuncInfo->setBytesToPopOnReturn(4);
}
@@ -2162,7 +2178,7 @@
bool Is64Bit = Subtarget->is64Bit();
bool IsWin64 = Subtarget->isTargetWin64();
bool IsWindows = Subtarget->isTargetWindows();
- bool IsStructRet = CallIsStructReturn(Outs);
+ StructReturnType SR = callIsStructReturn(Outs);
bool IsSibcall = false;
if (MF.getTarget().Options.DisableTailCalls)
@@ -2171,8 +2187,9 @@
if (isTailCall) {
// Check if it's really possible to do a tail call.
isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
- isVarArg, IsStructRet, MF.getFunction()->hasStructRetAttr(),
- Outs, OutVals, Ins, DAG);
+ isVarArg, SR != NotStructReturn,
+ MF.getFunction()->hasStructRetAttr(),
+ Outs, OutVals, Ins, DAG);
// Sibcalls are automatically detected tailcalls which do not require
// ABI changes.
@@ -2548,7 +2565,7 @@
getTargetMachine().Options.GuaranteedTailCallOpt))
NumBytesForCalleeToPush = NumBytes; // Callee pops everything
else if (!Is64Bit && !IsTailCallConvention(CallConv) && !IsWindows &&
- IsStructRet)
+ SR == StackStructReturn)
// If this is a call to a struct-return function, the callee
// pops the hidden struct pointer, so we have to push it back.
// This is common for Darwin/X86, Linux & Mingw32 targets.
Modified: llvm/trunk/test/CodeGen/X86/inreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inreg.ll?rev=160725&r1=160724&r2=160725&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/inreg.ll (original)
+++ llvm/trunk/test/CodeGen/X86/inreg.ll Wed Jul 25 08:41:10 2012
@@ -1,19 +1,46 @@
-; RUN: llc < %s -mtriple=i686-pc-linux -mcpu=corei7 | FileCheck %s
+; RUN: llc < %s -mtriple=i686-pc-linux -mcpu=corei7 | FileCheck --check-prefix=DAG %s
+; RUN: llc < %s -mtriple=i686-pc-linux -mcpu=corei7 -O0 | FileCheck --check-prefix=FAST %s
-%struct.s = type { double, float }
+%struct.s1 = type { double, float }
-define void @g() nounwind {
+define void @g1() nounwind {
entry:
- %tmp = alloca %struct.s, align 4
- call void @f(%struct.s* inreg sret %tmp, i32 inreg 41, i32 inreg 42, i32 43)
+ %tmp = alloca %struct.s1, align 4
+ call void @f(%struct.s1* inreg sret %tmp, i32 inreg 41, i32 inreg 42, i32 43)
ret void
- ; CHECK: g:
- ; CHECK: subl {{.*}}, %esp
- ; CHECK-NEXT: $43, (%esp)
- ; CHECK-NEXT: leal 16(%esp), %eax
- ; CHECK-NEXT: movl $41, %edx
- ; CHECK-NEXT: movl $42, %ecx
- ; CHECK-NEXT: calll f
+ ; DAG: g1:
+ ; DAG: subl $[[AMT:.*]], %esp
+ ; DAG-NEXT: $43, (%esp)
+ ; DAG-NEXT: leal 16(%esp), %eax
+ ; DAG-NEXT: movl $41, %edx
+ ; DAG-NEXT: movl $42, %ecx
+ ; DAG-NEXT: calll f
+ ; DAG-NEXT: addl $[[AMT]], %esp
+ ; DAG-NEXT: ret
+
+ ; FAST: g1:
+ ; FAST: subl $[[AMT:.*]], %esp
+ ; FAST-NEXT: leal 8(%esp), %eax
+ ; FAST-NEXT: movl $41, %edx
+ ; FAST-NEXT: movl $42, %ecx
+ ; FAST: $43, (%esp)
+ ; FAST: calll f
+ ; FAST-NEXT: addl $[[AMT]], %esp
+ ; FAST: ret
}
-declare void @f(%struct.s* inreg sret, i32 inreg, i32 inreg, i32)
+declare void @f(%struct.s1* inreg sret, i32 inreg, i32 inreg, i32)
+
+%struct.s2 = type {}
+
+define void @g2(%struct.s2* inreg sret %agg.result) nounwind {
+entry:
+ ret void
+ ; DAG: g2
+ ; DAG-NOT: ret $4
+ ; DAG: .size g2
+
+ ; FAST: g2
+ ; FAST-NOT: ret $4
+ ; FAST: .size g2
+}
More information about the llvm-commits
mailing list