When passing a huge parameter using the byval mechanism, a long
authorDuncan Sands <baldrick@free.fr>
Thu, 4 Nov 2010 21:16:46 +0000 (21:16 +0000)
committerDuncan Sands <baldrick@free.fr>
Thu, 4 Nov 2010 21:16:46 +0000 (21:16 +0000)
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

lib/Target/X86/X86SelectionDAGInfo.cpp
test/CodeGen/Generic/2010-11-04-BigByval.ll [new file with mode: 0644]

index c59d4074c7a186831be728c49028cfc7ec1cf408..0c5a0acd9c75f324f59ab671737c9e451db862cf 100644 (file)
@@ -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 (file)
index 0000000..df2ca4c
--- /dev/null
@@ -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
+}