Fix crash from r158529 on Bullet.
authorPete Cooper <peter_cooper@apple.com>
Sat, 16 Jun 2012 01:43:26 +0000 (01:43 +0000)
committerPete Cooper <peter_cooper@apple.com>
Sat, 16 Jun 2012 01:43:26 +0000 (01:43 +0000)
Dynamic GEPs created by SROA needed to insert extra "i32 0"
operands to index through structs and arrays to get to the
vector being indexed.

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

lib/Transforms/Scalar/ScalarReplAggregates.cpp
test/Transforms/ScalarRepl/dynamic-vector-gep.ll

index 9fc4164cc0e814fd23667842668f8209db8493ff..bc428802e895d6dc6ae1b275e90f4a10998dddef 100644 (file)
@@ -2011,8 +2011,17 @@ void SROA::RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset,
     uint64_t EltIdx = FindElementAndOffset(T, EltOffset, IdxTy);
     NewArgs.push_back(ConstantInt::get(IdxTy, EltIdx));
   }
-  if (NonConstantIdx)
+  if (NonConstantIdx) {
+    Type* GepTy = T;
+    // This GEP has a dynamic index.  We need to add "i32 0" to index through
+    // any structs or arrays in the original type until we get to the vector
+    // to index.
+    while (!isa<VectorType>(GepTy)) {
+      NewArgs.push_back(Constant::getNullValue(i32Ty));
+      GepTy = cast<CompositeType>(GepTy)->getTypeAtIndex(0U);
+    }
     NewArgs.push_back(NonConstantIdx);
+  }
   Instruction *Val = NewElts[Idx];
   if (NewArgs.size() > 1) {
     Val = GetElementPtrInst::CreateInBounds(Val, NewArgs, "", GEPI);
index 48a0da9dabddf4c59fc47941881ebe253d97a5e5..af7f4398d10227c493e85464a59c4cefdab09a7b 100644 (file)
@@ -80,4 +80,59 @@ entry:
   ret float %ret
 }
 
+; CHECK: test5
+; CHECK: %[[alloc0:[\.a-z0-9]*]] = alloca <4 x float>
+; CHECK: %[[alloc1:[\.a-z0-9]*]] = alloca <4 x float>
+; CHECK: store <4 x float> zeroinitializer, <4 x float>* %[[alloc0]]
+; CHECK: store <4 x float> zeroinitializer, <4 x float>* %[[alloc1]]
+; CHECK: %ptr1 = getelementptr inbounds <4 x float>* %[[alloc0]], i32 0, i32 %idx1
+; CHECK: store float 1.000000e+00, float* %ptr1
+; CHECK: %ptr2 = getelementptr inbounds <4 x float>* %[[alloc1]], i32 0, i32 %idx2
+; CHECK: %ret = load float* %ptr2
+
+%vector.pair = type { %vector.anon, %vector.anon }
+%vector.anon = type { %vector }
+%vector = type { <4 x float> }
+
+; Dynamic GEPs on vectors were crashing when the vector was inside a struct
+; as the new GEP for the new alloca might not include all the indices from
+; the original GEP, just the indices it needs to get to the correct offset of
+; some type, not necessarily the dynamic vector.
+; This test makes sure we don't have this crash.
+define float @test5(i32 %idx1, i32 %idx2) {
+entry:
+  %0 = alloca %vector.pair
+  store %vector.pair zeroinitializer, %vector.pair* %0
+  %ptr1 = getelementptr %vector.pair* %0, i32 0, i32 0, i32 0, i32 0, i32 %idx1
+  store float 1.0, float* %ptr1
+  %ptr2 = getelementptr %vector.pair* %0, i32 0, i32 1, i32 0, i32 0, i32 %idx2
+  %ret = load float* %ptr2
+  ret float %ret
+}
+
+; CHECK: test6
+; CHECK: %[[alloc0:[\.a-z0-9]*]] = alloca <4 x float>
+; CHECK: %[[alloc1:[\.a-z0-9]*]] = alloca <4 x float>
+; CHECK: store <4 x float> zeroinitializer, <4 x float>* %[[alloc0]]
+; CHECK: store <4 x float> zeroinitializer, <4 x float>* %[[alloc1]]
+; CHECK: %ptr1 = getelementptr inbounds <4 x float>* %[[alloc0]], i32 0, i32 %idx1
+; CHECK: store float 1.000000e+00, float* %ptr1
+; CHECK: %ptr2 = getelementptr inbounds <4 x float>* %[[alloc1]], i32 0, i32 %idx2
+; CHECK: %ret = load float* %ptr2
+
+%array.pair = type { [2 x %array.anon], %array.anon }
+%array.anon = type { [2 x %vector] }
+
+; This is the same as test5 and tests the same crash, but on arrays.
+define float @test6(i32 %idx1, i32 %idx2) {
+entry:
+  %0 = alloca %array.pair
+  store %array.pair zeroinitializer, %array.pair* %0
+  %ptr1 = getelementptr %array.pair* %0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 %idx1
+  store float 1.0, float* %ptr1
+  %ptr2 = getelementptr %array.pair* %0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 %idx2
+  %ret = load float* %ptr2
+  ret float %ret
+}
+
 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)