From fd18a762a033e6e7589d1d10f9346e4adea7def4 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Tue, 27 Jul 2021 10:09:30 -0700 Subject: [PATCH] Enabling the copy-constant-to-alloca optimization in more instances Patch by Mohammad Fawaz This patch allows lifetime calls to be ignored (and later erased) if we know that the copy-constant-to-alloca optimization is going to happen. The case that is missed is when the global variable is in a different address space than the alloca (as shown in the example added to the lit test.) This used to work before https://github.com/llvm/llvm-project/commit/6da31fa4a61d68af21dfa1e144e726ed6d77903e Differential Revision: https://reviews.llvm.org/D106573 --- .../InstCombineLoadStoreAlloca.cpp | 2 ++ .../InstCombine/memcpy-from-global.ll | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 73fdcc05de0..a8474e27383 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -272,6 +272,8 @@ bool PointerReplacer::collectUsers(Instruction &I) { return false; } else if (isa(Inst)) { Worklist.insert(Inst); + } else if (Inst->isLifetimeStartOrEnd()) { + continue; } else { LLVM_DEBUG(dbgs() << "Cannot handle pointer user: " << *U << '\n'); return false; diff --git a/test/Transforms/InstCombine/memcpy-from-global.ll b/test/Transforms/InstCombine/memcpy-from-global.ll index 62ee15351f0..e5f197f94da 100644 --- a/test/Transforms/InstCombine/memcpy-from-global.ll +++ b/test/Transforms/InstCombine/memcpy-from-global.ll @@ -73,6 +73,7 @@ declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* nocapture, i8 addrspace @G = constant %T {i8 1, [123 x i8] zeroinitializer } @H = constant [2 x %U] zeroinitializer, align 16 +@I = internal addrspace(1) constant [4 x float] zeroinitializer , align 4 define void @test2() { ; CHECK-LABEL: @test2( @@ -323,4 +324,22 @@ entry: ret void } +; Should replace alloca with global even when the global is in a different address space +define float @test11(i64 %i) { +; CHECK-LABEL: @test11( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x float], [4 x float] addrspace(1)* @I, i64 0, i64 %i +; CHECK-NEXT: [[LD:%.*]] = load float, float addrspace(1)* [[GEP]] +; CHECK-NEXT: ret float [[LD]] + +entry: + %a = alloca [4 x float], align 4 + %b = bitcast [4 x float]* %a to i8* + call void @llvm.lifetime.start.p0i8(i64 16, i8* %b) + call void @llvm.memcpy.p0i8.p1i8.i64(i8* align 4 %b, i8 addrspace(1)* align 4 bitcast ([4 x float] addrspace(1)* @I to i8 addrspace(1)*), i64 16, i1 false) + %g = getelementptr inbounds [4 x float], [4 x float]* %a, i64 0, i64 %i + %r = load float, float* %g, align 4 + ret float %r +} + attributes #0 = { null_pointer_is_valid }