[llvm] f988efb - [AMDGPU] Run early-cse<memssa> at the end of the full-LTO pipeline (#208461)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 18 23:23:27 PDT 2026


Author: michaelselehov
Date: 2026-07-19T08:23:22+02:00
New Revision: f988efbef5854243f9f518e9334dfee08ff2e1de

URL: https://github.com/llvm/llvm-project/commit/f988efbef5854243f9f518e9334dfee08ff2e1de
DIFF: https://github.com/llvm/llvm-project/commit/f988efbef5854243f9f518e9334dfee08ff2e1de.diff

LOG: [AMDGPU] Run early-cse<memssa> at the end of the full-LTO pipeline (#208461)

The regular (non-LTO) and ThinLTO function simplification pipelines run
an
EarlyCSE-with-MemorySSA pass near the start of the function pass
sequence, but
the full-LTO postlink pipeline does not. Without it, a redundant
load/store
round-trip can survive all the way to codegen; the later GVN/DSE in the
LTO
pipeline do not catch this particular pattern. 
    
Rather than touch the target-independent LTO pipeline, register
early-cse<memssa> through the AMDGPU FullLinkTimeOptimizationLast
extension
point, so it runs at the end of the full-LTO middle-end (before codegen)
only
for AMDGPU.
    
    Assisted-by: Claude Opus

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
    llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll
    llvm/test/Transforms/PhaseOrdering/AMDGPU/infer-address-space.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 8c2732630e2e6..6fdaf6248e986 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -1111,6 +1111,13 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
 
   PB.registerFullLinkTimeOptimizationLastEPCallback(
       [this](ModulePassManager &PM, OptimizationLevel Level) {
+        // Clean up redundant memory round-trips that the full-LTO pipeline,
+        // unlike the non-LTO/ThinLTO ones, otherwise leaves for codegen.
+        if (Level != OptimizationLevel::O0) {
+          PM.addPass(createModuleToFunctionPassAdaptor(
+              EarlyCSEPass(/*UseMemorySSA=*/true)));
+        }
+
         // When we are using -fgpu-rdc, we can only run accelerator code
         // selection after linking to prevent, otherwise we end up removing
         // potentially reachable symbols that were exported as external in other

diff  --git a/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll b/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll
index 0fe839585b67d..df40dfd000def 100644
--- a/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll
+++ b/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll
@@ -9,8 +9,10 @@
 ; RUN: opt -mtriple=amdgpu--amdhsa -S -passes="lto-pre-link<O3>" -print-pipeline-passes -amdgpu-internalize-symbols %s -o - | FileCheck --check-prefix=PRE %s
 
 
+; CHECK: early-cse<memssa>
 ; CHECK: amdgpu-attributor
 ; O0-NOT: amdgpu-attributor
+; O0-NOT: early-cse<memssa>
 
 ; PRE-NOT: internalize
 ; PRE-NOT: amdgpu-attributor

diff  --git a/llvm/test/Transforms/PhaseOrdering/AMDGPU/infer-address-space.ll b/llvm/test/Transforms/PhaseOrdering/AMDGPU/infer-address-space.ll
index 168083f285b03..4313a0e0903dc 100644
--- a/llvm/test/Transforms/PhaseOrdering/AMDGPU/infer-address-space.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AMDGPU/infer-address-space.ll
@@ -42,9 +42,7 @@ define void @caller(ptr addrspace(1) %ptr_as1, i32 %value) {
 ; NO-INFER-NEXT:    store i32 [[VALUE]], ptr addrspace(5) [[VAL_FIELD]], align 4
 ; NO-INFER-NEXT:    [[GENERIC_INPUT:%.*]] = addrspacecast ptr addrspace(1) [[PTR_AS1]] to ptr
 ; NO-INFER-NEXT:    store ptr [[GENERIC_INPUT]], ptr addrspace(5) [[DATA]], align 8
-; NO-INFER-NEXT:    [[RETRIEVED_PTR:%.*]] = load ptr, ptr addrspace(5) [[DATA]], align 8
-; NO-INFER-NEXT:    [[RETRIEVED_VAL:%.*]] = load i32, ptr addrspace(5) [[VAL_FIELD]], align 4
-; NO-INFER-NEXT:    call void @callee(ptr [[RETRIEVED_PTR]], i32 [[RETRIEVED_VAL]])
+; NO-INFER-NEXT:    call void @callee(ptr [[GENERIC_INPUT]], i32 [[VALUE]])
 ; NO-INFER-NEXT:    ret void
 ;
   %data = alloca %struct.data, align 8, addrspace(5)


        


More information about the llvm-commits mailing list