[PATCH] Fix SROA regression causing data corruption, fixes PR19250
Duncan P. N. Exon Smith
dexonsmith at apple.com
Mon Jun 9 18:30:53 PDT 2014
+aprantl
> On 2014-Apr-21, at 03:18, Björn Steinbrink <bsteinbr at gmail.com> wrote:
>
> dotdash added you to the CC list for the revision "Fix SROA regression causing data corruption, fixes PR19250".
>
> r199771 accidently broke the logic that makes sure that SROA only splits load
> on byte boundaries. If such a split happens, some bits get lost when
> reassembling loads of wider types, causing data corruption.
>
> Moving the width check up to reject such splits early fixes the problem.
>
Thanks for working on this. A few comments inline.
>
> http://reviews.llvm.org/D3297
>
> Files:
> lib/Transforms/Scalar/SROA.cpp
> test/Transforms/SROA/basictest.ll
>
> Index: lib/Transforms/Scalar/SROA.cpp
> ===================================================================
> --- lib/Transforms/Scalar/SROA.cpp
> +++ lib/Transforms/Scalar/SROA.cpp
> @@ -1031,11 +1031,6 @@
> UserTy = SI->getValueOperand()->getType();
> }
>
> - if (!UserTy || (Ty && Ty != UserTy))
> - TyIsCommon = false; // Give up on anything but an iN type.
I feel like this check (and assignment to `false`) should still be
*here*, before the early `continue`. Can you explain why you moved it?
> - else
> - Ty = UserTy;
(I understand moving the `else` clause.)
> -
> 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 @@
> 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;
> Index: test/Transforms/SROA/basictest.ll
> ===================================================================
> --- test/Transforms/SROA/basictest.ll
> +++ test/Transforms/SROA/basictest.ll
> @@ -1440,3 +1440,30 @@
> ret void
> }
>
> +define i32 @test25({ i1, i32 }*) {
I think you should create a new file for this testcase. Name it after
the problem that's being fixed, and give the function a good name too.
> +; 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
> +}
> <D3297.1.patch>_______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list