aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Scalar/SROA.cpp12
-rw-r--r--test/Transforms/SROA/basictest.ll20
2 files changed, 23 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index 41e96d6..91d5240 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -1694,20 +1694,14 @@ isIntegerWideningViable(const DataLayout &TD, Type *AllocaTy,
!canConvertValue(TD, IntTy, AllocaTy))
return false;
- // If we have no actual uses of this partition, we're forming a fully
- // splittable partition. Assume all the operations are easy to widen (they
- // are if they're splittable), and just check that it's a good idea to form
- // a single integer.
- if (I == E)
- return TD.isLegalInteger(SizeInBits);
-
uint64_t Size = TD.getTypeStoreSize(AllocaTy);
// While examining uses, we ensure that the alloca has a covering load or
// store. We don't want to widen the integer operations only to fail to
// promote due to some other unsplittable entry (which we may make splittable
- // later).
- bool WholeAllocaOp = false;
+ // later). However, if there are only splittable uses, go ahead and assume
+ // that we cover the alloca.
+ bool WholeAllocaOp = (I != E) ? false : TD.isLegalInteger(SizeInBits);
for (; I != E; ++I)
if (!isIntegerWideningViableForPartitioning(TD, AllocaTy, AllocBeginOffset,
diff --git a/test/Transforms/SROA/basictest.ll b/test/Transforms/SROA/basictest.ll
index ca52dce..9e5a261 100644
--- a/test/Transforms/SROA/basictest.ll
+++ b/test/Transforms/SROA/basictest.ll
@@ -1317,3 +1317,23 @@ define void @PR15805(i1 %a, i1 %b) {
%cond = load i64* %cond.in, align 8
ret void
}
+
+define void @PR16651(i8* %a) {
+; This test case caused a crash due to the volatile memcpy in combination with
+; lowering to integer loads and stores of a width other than that of the original
+; memcpy.
+;
+; CHECK-LABEL: @PR16651(
+; CHECK: alloca i16
+; CHECK: alloca i8
+; CHECK: alloca i8
+; CHECK: unreachable
+
+entry:
+ %b = alloca i32, align 4
+ %b.cast = bitcast i32* %b to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %b.cast, i8* %a, i32 4, i32 4, i1 true)
+ %b.gep = getelementptr inbounds i8* %b.cast, i32 2
+ load i8* %b.gep, align 2
+ unreachable
+}