The element insertion code in scalar replacement doesn't handle incorrect
authorCameron Zwarich <zwarich@apple.com>
Sun, 23 Oct 2011 07:02:10 +0000 (07:02 +0000)
committerCameron Zwarich <zwarich@apple.com>
Sun, 23 Oct 2011 07:02:10 +0000 (07:02 +0000)
element types, even though the element extraction code does. It is surprising
that this bug has been here for so long. Fixes <rdar://problem/10318778>.

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

lib/Transforms/Scalar/ScalarReplAggregates.cpp
test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll [new file with mode: 0644]

index c6d9123d66117477e7921c7ee768909238b815a7..b89f7306a28888bf5e5ab7d7fd93e4c67660766f 100644 (file)
@@ -806,8 +806,10 @@ ConvertScalar_InsertValue(Value *SV, Value *Old,
         return Builder.CreateBitCast(SV, AllocaType);
 
     // Must be an element insertion.
-    assert(SV->getType() == VTy->getElementType());
-    uint64_t EltSize = TD.getTypeAllocSizeInBits(VTy->getElementType());
+    Type *EltTy = VTy->getElementType();
+    if (SV->getType() != EltTy)
+      SV = Builder.CreateBitCast(SV, EltTy);
+    uint64_t EltSize = TD.getTypeAllocSizeInBits(EltTy);
     unsigned Elt = Offset/EltSize;
     return Builder.CreateInsertElement(Old, SV, Builder.getInt32(Elt));
   }
diff --git a/test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll b/test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll
new file mode 100644 (file)
index 0000000..cd21ff5
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: opt < %s -S -scalarrepl | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
+target triple = "thumbv7-apple-ios5.0.0"
+
+%union.anon = type { <4 x float> }
+
+; CHECK: @test
+; CHECK-NOT: alloca
+
+define void @test() nounwind {
+entry:
+  %u = alloca %union.anon, align 16
+  %u164 = bitcast %union.anon* %u to [4 x i32]*
+  %arrayidx165 = getelementptr inbounds [4 x i32]* %u164, i32 0, i32 0
+  store i32 undef, i32* %arrayidx165, align 4
+  %v186 = bitcast %union.anon* %u to <4 x float>*
+  store <4 x float> undef, <4 x float>* %v186, align 16
+  ret void
+}