Fix a bug which caused us to miscompile a couple of Ada
authorChris Lattner <sabre@nondot.org>
Mon, 2 Feb 2009 18:02:59 +0000 (18:02 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 2 Feb 2009 18:02:59 +0000 (18:02 +0000)
tests.  Thanks for the beautiful reduced testcase Duncan!

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

lib/Transforms/Scalar/ScalarReplAggregates.cpp
test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll [new file with mode: 0644]

index 29970ecb444fcd6e13caa854ef83e869b247aa01..0765e12876b875f2109c3bf2301ea5a8ad8edc9b 100644 (file)
@@ -1166,12 +1166,17 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) {
 static void MergeInType(const Type *In, uint64_t Offset, const Type *&Accum,
                         const TargetData &TD) {
   // If this is our first type, just use it.
-  if (Accum == 0 || In == Type::VoidTy ||
+  if ((Accum == 0 && Offset == 0) || In == Type::VoidTy ||
       // Or if this is a same type, keep it.
       (In == Accum && Offset == 0)) {
     Accum = In;
     return;
   }
+
+  // Merging something like i32 into offset 8 means that a "field" is merged in
+  // before the basic type is.  Make sure to consider the offset below.
+  if (Accum == 0)
+    Accum = Type::Int8Ty;
   
   if (const VectorType *VATy = dyn_cast<VectorType>(Accum)) {
     if (VATy->getElementType() == In &&
diff --git a/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll b/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll
new file mode 100644 (file)
index 0000000..af34baa
--- /dev/null
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 %x}
+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"
+
+%pair = type { [1 x i32], i32 }
+
+define i32 @f(i32 %x, i32 %y) {
+       %instance = alloca %pair
+       %first = getelementptr %pair* %instance, i32 0, i32 0
+       %cast = bitcast [1 x i32]* %first to i32*
+       store i32 %x, i32* %cast
+       %second = getelementptr %pair* %instance, i32 0, i32 1
+       store i32 %y, i32* %second
+       %v = load i32* %cast
+       ret i32 %v
+}