[PATCH] Fix SROA regression that allows splits on non byte width integer types

Björn Steinbrink bsteinbr at gmail.com
Thu Mar 27 01:26:45 PDT 2014


r199771 accidently changed the logic that excludes integer types that
are not a byte width multiple. As long as a the TyIsCommon flag is true,
types like i1 aren't rejected. This causes invalid code, because the
reconstructed value will have the missing bits zeroed out.

Moving the width check in front fixes the problem.

Fixes http://llvm.org/bugs/show_bug.cgi?id=19250

---
 lib/Transforms/Scalar/SROA.cpp    | 10 +++++-----
 test/Transforms/SROA/basictest.ll | 27 +++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index ed5e618..714f6db 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -1031,11 +1031,6 @@ static Type *findCommonType(AllocaSlices::const_iterator B,
       UserTy = SI->getValueOperand()->getType();
     }
 
-    if (!UserTy || (Ty && Ty != UserTy))
-      TyIsCommon = false; // Give up on anything but an iN type.
-    else
-      Ty = UserTy;
-
     if (IntegerType *UserITy = dyn_cast_or_null<IntegerType>(UserTy)) {
       // If the type is larger than the partition, skip it. We only encounter
       // this for split integer operations where we want to use the type of the
@@ -1050,6 +1045,11 @@ static Type *findCommonType(AllocaSlices::const_iterator B,
       if (!ITy || ITy->getBitWidth() < UserITy->getBitWidth())
         ITy = UserITy;
     }
+
+    if (!UserTy || (Ty && Ty != UserTy))
+      TyIsCommon = false; // Give up on anything but an iN type.
+    else
+      Ty = UserTy;
   }
 
   return TyIsCommon ? Ty : ITy;
diff --git a/test/Transforms/SROA/basictest.ll b/test/Transforms/SROA/basictest.ll
index dc2b165..70675e6 100644
--- a/test/Transforms/SROA/basictest.ll
+++ b/test/Transforms/SROA/basictest.ll
@@ -1440,3 +1440,30 @@ entry:
   ret void
 }
 
+define i32 @test25({ i1, i32 }*) {
+; This tests that splits only happen on integer types that are byte width multiple
+; CHECK-LABEL: @test25(
+; CHECK: case0:
+; CHECK-NOT: zext i1
+; CHECK: case1:
+; CHECK: ret i32
+entry-block:
+  %arg = alloca { i1, i32 }, align 8
+  %1 = bitcast { i1, i32 }* %0 to i8*
+  %2 = bitcast { i1, i32 }* %arg to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %2, i8* %1, i32 8, i32 4, i1 false)
+  %discrp = getelementptr inbounds { i1, i32 }* %arg, i64 0, i32 0
+  %s = getelementptr inbounds { i1, i32 }* %arg, i64 0, i32 1
+  %discr = load i1* %discrp, align 1
+  br i1 %discr, label %case0, label %case1
+
+case0:                                     ; preds = %entry-block
+  %r0 = load i32* %s
+  ret i32 %r0
+
+case1:
+  %p1 = bitcast i32* %s to i1*
+  %t1 = load i1* %p1
+  %r1 = zext i1 %t1 to i32
+  ret i32 %r1
+}
-- 
1.9.0.rc3



More information about the llvm-commits mailing list