From: Duncan Sands Date: Thu, 4 Nov 2010 21:16:46 +0000 (+0000) Subject: When passing a huge parameter using the byval mechanism, a long X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=1e92ec688624d17b552c88afc956f61da4948cbb;p=oota-llvm.git When passing a huge parameter using the byval mechanism, a long sequence of loads and stores was being generated to perform the copy on the x86 targets if the parameter was less than 4 byte aligned, causing llc to use up vast amounts of memory and time. Use a "rep movs" form instead. PR7170. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118260 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86SelectionDAGInfo.cpp b/lib/Target/X86/X86SelectionDAGInfo.cpp index c59d4074c7a..0c5a0acd9c7 100644 --- a/lib/Target/X86/X86SelectionDAGInfo.cpp +++ b/lib/Target/X86/X86SelectionDAGInfo.cpp @@ -187,19 +187,29 @@ X86SelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl, if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold()) return SDValue(); - /// If not DWORD aligned, call the library. - if ((Align & 3) != 0) + /// If not DWORD aligned, it is more efficient to call the library. However + /// if calling the library is not allowed (AlwaysInline), then soldier on as + /// the code generated here is better than the long load-store sequence we + /// would otherwise get. + if (!AlwaysInline && (Align & 3) != 0) return SDValue(); // If to a segment-relative address space, use the default lowering. if (DstPtrInfo.getAddrSpace() >= 256 || SrcPtrInfo.getAddrSpace() >= 256) return SDValue(); - - // DWORD aligned - EVT AVT = MVT::i32; - if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) // QWORD aligned - AVT = MVT::i64; + + MVT AVT; + if (Align & 1) + AVT = MVT::i8; + else if (Align & 2) + AVT = MVT::i16; + else if (Align & 4) + // DWORD aligned + AVT = MVT::i32; + else + // QWORD aligned + AVT = Subtarget->is64Bit() ? MVT::i64 : MVT::i32; unsigned UBytes = AVT.getSizeInBits() / 8; unsigned CountVal = SizeVal / UBytes; diff --git a/test/CodeGen/Generic/2010-11-04-BigByval.ll b/test/CodeGen/Generic/2010-11-04-BigByval.ll new file mode 100644 index 00000000000..df2ca4c18a0 --- /dev/null +++ b/test/CodeGen/Generic/2010-11-04-BigByval.ll @@ -0,0 +1,11 @@ +; RUN: llc < %s +; PR7170 + +%big = type [131072 x i8] + +declare void @foo(%big* byval align 1) + +define void @bar(%big* byval align 1 %x) { + call void @foo(%big* byval align 1 %x) + ret void +}