From 42ab5dc5a5dd6c79476104bdc921afa2a18559cf Mon Sep 17 00:00:00 2001 From: Anshil Gandhi Date: Wed, 11 Jan 2023 16:59:21 +0100 Subject: [PATCH] [InstCombine] Handle PHI nodes in isOnlyCopiedFromConstantMemory() As long as the memcpy occurs on a phi input (rather than the phi output), we can look through phi nodes in isOnlyCopiedFromConstantMemory(). This is split out of D136201, to only handle the case where the address spaces are the same, and no pointer rewrite is necessary. --- llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 7 +++++++ llvm/test/Transforms/InstCombine/replace-alloca-phi.ll | 8 ++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 8c9b027..640ba90 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -72,6 +72,13 @@ isOnlyCopiedFromConstantMemory(AAResults *AA, AllocaInst *V, continue; } + if (isa(I)) { + // We set IsOffset=true, to forbid the memcpy from occurring after the + // phi: If one of the phi operands is not based on the alloca, we + // would incorrectly omit a write. + Worklist.emplace_back(I, true); + continue; + } if (isa(I) || isa(I)) { // If uses of the bitcast are ok, we are ok. Worklist.emplace_back(I, IsOffset); diff --git a/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll b/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll index 15baf86..4e8aef9 100644 --- a/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll +++ b/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll @@ -152,13 +152,11 @@ exit: define i32 @remove_alloca_ptr_arg(i1 %c, ptr %ptr) { ; CHECK-LABEL: @remove_alloca_ptr_arg( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(32) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(32) @g1, i64 32, i1 false) ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] ; CHECK: if: ; CHECK-NEXT: br label [[JOIN]] ; CHECK: join: -; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[IF]] ], [ [[PTR:%.*]], [[ENTRY:%.*]] ] +; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ @g1, [[IF]] ], [ [[PTR:%.*]], [[ENTRY:%.*]] ] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[PHI]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; @@ -269,11 +267,9 @@ join: define i32 @phi_loop(i1 %c) { ; CHECK-LABEL: @phi_loop( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(32) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(32) @g1, i64 32, i1 false) ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[PTR_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ @g1, [[ENTRY:%.*]] ], [ [[PTR_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[PTR_NEXT]] = getelementptr i8, ptr [[PTR]], i64 4 ; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]] ; CHECK: exit: -- 2.7.4