[llvm] cf41616 - [Instcombine] Disable memcpy of alloca bypass for instruction sources
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 14 07:57:20 PDT 2021
Thank you.
I think we will see similar issues get exposed in other places that
use `isDereferenceableAndAlignedPointer()`.
Roman
On Wed, Apr 14, 2021 at 5:52 PM Benjamin Kramer via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
>
> Author: Benjamin Kramer
> Date: 2021-04-14T16:52:09+02:00
> New Revision: cf4161673c7e7c7c57d8115468bfcc9988f43d36
>
> URL: https://github.com/llvm/llvm-project/commit/cf4161673c7e7c7c57d8115468bfcc9988f43d36
> DIFF: https://github.com/llvm/llvm-project/commit/cf4161673c7e7c7c57d8115468bfcc9988f43d36.diff
>
> LOG: [Instcombine] Disable memcpy of alloca bypass for instruction sources
>
> This transformation is fundamentally broken when it comes to dominance,
> it just happened to work when the source of the memcpy can be moved into
> the place of the alloca. The bug shows up a lot more often since
> 077bff39d46364035a5dcfa32fc69910ad0975d0 allows the source to be a
> switch.
>
> It would be possible to check dominance of the source and all its
> operands, but that seems very heavy for instcombine.
>
> Added:
>
>
> Modified:
> llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
> llvm/test/Transforms/InstCombine/tmp-alloca-bypass.ll
>
> Removed:
>
>
>
> ################################################################################
> diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
> index 3ca54958cc79..dd4c15e4cdb1 100644
> --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
> +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
> @@ -407,10 +407,9 @@ Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
> TheSrc, AllocaAlign, DL, &AI, &AC, &DT);
> if (AllocaAlign <= SourceAlign &&
> isDereferenceableForAllocaSize(TheSrc, &AI, DL) &&
> - (!isa<Instruction>(TheSrc) || all_of(AI.users(), [&](const User *U) {
> - return DT.dominates(cast<Instruction>(TheSrc), cast<Instruction>(U));
> - }))) {
> - // FIXME: can the dominance restriction be relaxed by sinking instrns?
> + !isa<Instruction>(TheSrc)) {
> + // FIXME: Can we sink instructions without violating dominance when TheSrc
> + // is an instruction instead of a constant or argument?
> LLVM_DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n');
> LLVM_DEBUG(dbgs() << " memcpy = " << *Copy << '\n');
> unsigned SrcAddrSpace = TheSrc->getType()->getPointerAddressSpace();
>
> diff --git a/llvm/test/Transforms/InstCombine/tmp-alloca-bypass.ll b/llvm/test/Transforms/InstCombine/tmp-alloca-bypass.ll
> index 9a87e8a68f8e..7fb531d7fa08 100644
> --- a/llvm/test/Transforms/InstCombine/tmp-alloca-bypass.ll
> +++ b/llvm/test/Transforms/InstCombine/tmp-alloca-bypass.ll
> @@ -31,5 +31,29 @@ define void @test(i8*%out) {
> ret void
> }
>
> +define void @test2() {
> +; CHECK-LABEL: @test2(
> +; CHECK-NEXT: bb:
> +; CHECK-NEXT: [[I:%.*]] = alloca [[T0:%.*]], align 8
> +; CHECK-NEXT: [[I1:%.*]] = call i32 @func(%t0* undef)
> +; CHECK-NEXT: [[I2:%.*]] = icmp eq i32 [[I1]], 2503
> +; CHECK-NEXT: [[I3:%.*]] = select i1 [[I2]], i8* bitcast (%t0* @g0 to i8*), i8* bitcast (%t0* @g1 to i8*)
> +; CHECK-NEXT: [[I4:%.*]] = bitcast %t0* [[I]] to i8*
> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(16) [[I4]], i8* noundef nonnull align 8 dereferenceable(16) [[I3]], i64 16, i1 false)
> +; CHECK-NEXT: [[I5:%.*]] = call i32 @func(%t0* nonnull byval([[T0]]) [[I]])
> +; CHECK-NEXT: unreachable
> +;
> +bb:
> + %i = alloca %t0, align 8
> + %i1 = call i32 @func(%t0* undef)
> + %i2 = icmp eq i32 %i1, 2503
> + %i3 = select i1 %i2, i8* bitcast (%t0* @g0 to i8*), i8* bitcast (%t0* @g1 to i8*)
> + %i4 = bitcast %t0* %i to i8*
> + call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(16) %i4, i8* noundef nonnull align 8 dereferenceable(16) %i3, i64 16, i1 false)
> + %i5 = call i32 @func(%t0* nonnull byval(%t0) %i)
> + unreachable
> +}
> +
> +declare i32 @func(%t0*)
> declare i1 @get_cond()
> declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list