Fix a nasty miscompilation of 176.gcc on linux/x86 where we synthesized
authorChris Lattner <sabre@nondot.org>
Tue, 28 Oct 2008 05:49:35 +0000 (05:49 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 28 Oct 2008 05:49:35 +0000 (05:49 +0000)
a memset using 16-byte XMM stores, but where the stack realignment code
didn't work.  Until it does (PR2962) disable use of xmm regs in memcpy
and memset formation for linux and other targets with insufficiently
aligned stacks.

This is part of PR2888

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58317 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/2008-10-27-StackRealignment.ll [new file with mode: 0644]

index 3dbedba7b96a123a3a52ace908cad4e9d82186bb..a10f8a8daafd59a28e7e713a0f5bbc3e4df40871 100644 (file)
@@ -850,10 +850,15 @@ unsigned X86TargetLowering::getByValTypeAlignment(const Type *Ty) const {
 MVT
 X86TargetLowering::getOptimalMemOpType(uint64_t Size, unsigned Align,
                                        bool isSrcConst, bool isSrcStr) const {
-  if ((isSrcConst || isSrcStr) && Subtarget->hasSSE2() && Size >= 16)
-    return MVT::v4i32;
-  if ((isSrcConst || isSrcStr) && Subtarget->hasSSE1() && Size >= 16)
-    return MVT::v4f32;
+  // FIXME: This turns off use of xmm stores for memset/memcpy on targets like
+  // linux.  This is because the stack realignment code can't handle certain
+  // cases like PR2962.  This should be removed when PR2962 is fixed.
+  if (Subtarget->getStackAlignment() >= 16) {
+    if ((isSrcConst || isSrcStr) && Subtarget->hasSSE2() && Size >= 16)
+      return MVT::v4i32;
+    if ((isSrcConst || isSrcStr) && Subtarget->hasSSE1() && Size >= 16)
+      return MVT::v4f32;
+  }
   if (Subtarget->is64Bit() && Size >= 8)
     return MVT::i64;
   return MVT::i32;
diff --git a/test/CodeGen/X86/2008-10-27-StackRealignment.ll b/test/CodeGen/X86/2008-10-27-StackRealignment.ll
new file mode 100644 (file)
index 0000000..d8b0e70
--- /dev/null
@@ -0,0 +1,22 @@
+; Linux doesn't support stack realignment for functions with allocas (PR2888).
+; Until it does, we shouldn't use movaps to access the stack.  On targets with
+; sufficiently aligned stack (e.g. darwin) we should.
+
+; RUN: llvm-as < %s | llc -mtriple=i386-pc-linux-gnu -mcpu=yonah | not grep movaps
+; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin9 -mcpu=yonah | grep movaps | count 2
+
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-pc-linux-gnu"
+  
+define void @foo(i32 %t) nounwind {
+  %tmp1210 = alloca i8, i32 32, align 4
+  call void @llvm.memset.i64(i8* %tmp1210, i8 0, i64 32, i32 4)
+  
+  %x = alloca i8, i32 %t
+  call void @dummy(i8* %x)
+  ret void
+}
+
+declare void @dummy(i8* %x)
+declare void @llvm.memset.i64(i8*, i8, i64, i32) nounwind