aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-06-04 23:37:54 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-06-04 23:37:54 +0000
commitfb4db316d835fa9774d608ac58336a24c7867192 (patch)
treedd84e845d53ad6928fbf8c01beef6adf3d22869a
parent10a05bfff08deb739abe11d05e794440c3ab543f (diff)
downloadexternal_llvm-fb4db316d835fa9774d608ac58336a24c7867192.zip
external_llvm-fb4db316d835fa9774d608ac58336a24c7867192.tar.gz
external_llvm-fb4db316d835fa9774d608ac58336a24c7867192.tar.bz2
Fix a memcpy lowering bug. Even though the memcpy alignment is smaller than the desired alignment, the frame destination alignment may still be larger than the desired alignment. Don't change its alignment to something smaller.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51970 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp5
-rw-r--r--test/CodeGen/X86/2008-06-04-MemCpyLoweringBug.ll19
2 files changed, 22 insertions, 2 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index a9b7381..8d0d344 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2633,8 +2633,9 @@ bool MeetsMaxMemopRequirement(std::vector<MVT::ValueType> &MemOps,
if (AllowUnalign)
VT = MVT::iAny;
} else {
- // Give the stack frame object a larger alignment.
- MFI->setObjectAlignment(FI, NewAlign);
+ // Give the stack frame object a larger alignment if needed.
+ if (MFI->getObjectAlignment(FI) < NewAlign)
+ MFI->setObjectAlignment(FI, NewAlign);
Align = NewAlign;
}
}
diff --git a/test/CodeGen/X86/2008-06-04-MemCpyLoweringBug.ll b/test/CodeGen/X86/2008-06-04-MemCpyLoweringBug.ll
new file mode 100644
index 0000000..d282761
--- /dev/null
+++ b/test/CodeGen/X86/2008-06-04-MemCpyLoweringBug.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -mattr=+sse2 -disable-fp-elim | grep subl | grep 24
+
+ %struct.argument_t = type { i8*, %struct.argument_t*, i32, %struct.ipc_type_t*, i32, void (...)*, void (...)*, void (...)*, void (...)*, void (...)*, i8*, i8*, i8*, i8*, i8*, i32, i32, i32, %struct.routine*, %struct.argument_t*, %struct.argument_t*, %struct.argument_t*, %struct.argument_t*, %struct.argument_t*, %struct.argument_t*, %struct.argument_t*, i32, i32, i32, i32, i32, i32 }
+ %struct.ipc_type_t = type { i8*, %struct.ipc_type_t*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i8*, i32, i32, i32, i32, i32, i32, %struct.ipc_type_t*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }
+ %struct.routine = type opaque
+@"\01LC" = external constant [11 x i8] ; <[11 x i8]*> [#uses=1]
+
+define i8* @InArgMsgField(%struct.argument_t* %arg, i8* %str) nounwind {
+entry:
+ %who = alloca [20 x i8] ; <[20 x i8]*> [#uses=1]
+ %who1 = getelementptr [20 x i8]* %who, i32 0, i32 0 ; <i8*> [#uses=2]
+ call void @llvm.memset.i32( i8* %who1, i8 0, i32 20, i32 1 )
+ call void @llvm.memcpy.i32( i8* %who1, i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i32 11, i32 1 )
+ unreachable
+}
+
+declare void @llvm.memset.i32(i8*, i8, i32, i32) nounwind
+
+declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind