[llvm] [GlobalISel] Avoid redundant copy for zero-offset GEPs (PR #203029)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 09:20:57 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Cullen Rhodes (c-rhodes)
<details>
<summary>Changes</summary>
Handle zero-offset GEPs early to avoid creating a separate vreg for the
GEP result and copying the base pointer into it.
Improves CTMark geomean -0.14% on aarch64-O0-g, with consumer-typeset
-0.86%.
https://llvm-compile-time-tracker.com/compare.php?from=2de2edb943fe1b83d79bdffa03606eb8c5452e9b&to=d3d5a4af0e7a58ea7b3a1e8c02b34fa380695e62&stat=instructions%3Au
Assisted-by: codex
---
Full diff: https://github.com/llvm/llvm-project/pull/203029.diff
5 Files Affected:
- (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+3)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/translate-gep.ll (+1-2)
- (modified) llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll (+18-24)
- (modified) llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll (+3-4)
- (modified) llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll (+2-4)
``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 28755da8327aa..37a6edd90974a 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1661,6 +1661,9 @@ bool IRTranslator::translateGetElementPtr(const User &U,
WantSplatVector = VectorWidth > 1;
}
+ if (cast<GEPOperator>(U).hasAllZeroIndices())
+ return translateCopy(U, Op0, MIRBuilder);
+
// We might need to splat the base pointer into a vector if the offsets
// are vectors.
if (WantSplatVector && !PtrTy.isVector()) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/translate-gep.ll b/llvm/test/CodeGen/AArch64/GlobalISel/translate-gep.ll
index 06b9359d0078b..641efb51dd72a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/translate-gep.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/translate-gep.ll
@@ -40,8 +40,7 @@ define ptr @first_offset_trivial(ptr %addr) {
; CHECK-NEXT: liveins: $x0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
- ; CHECK-NEXT: $x0 = COPY [[COPY1]](p0)
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](p0)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%res = getelementptr %type, ptr %addr, i32 0
ret ptr %res
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
index fd3fe171a99e0..acf478b364436 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
@@ -9,15 +9,13 @@ define { float, float } @add_complex_float(ptr %a, ptr %b) {
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
; MIPS32-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
- ; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
- ; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY2]](p0) :: (load (s32) from %ir..realp)
+ ; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir..realp)
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; MIPS32-NEXT: %5:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
- ; MIPS32-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD %5(p0) :: (load (s32) from %ir..imagp)
- ; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY1]](p0)
- ; MIPS32-NEXT: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[COPY3]](p0) :: (load (s32) from %ir..realp1)
- ; MIPS32-NEXT: %9:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY1]], [[C]](s32)
- ; MIPS32-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD %9(p0) :: (load (s32) from %ir..imagp3)
+ ; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
+ ; MIPS32-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %ir..imagp)
+ ; MIPS32-NEXT: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[COPY1]](p0) :: (load (s32) from %ir..realp1)
+ ; MIPS32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY1]], [[C]](s32)
+ ; MIPS32-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD1]](p0) :: (load (s32) from %ir..imagp3)
; MIPS32-NEXT: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[LOAD]], [[LOAD2]]
; MIPS32-NEXT: [[FADD1:%[0-9]+]]:_(s32) = G_FADD [[LOAD1]], [[LOAD3]]
; MIPS32-NEXT: $f0 = COPY [[FADD]](s32)
@@ -47,15 +45,13 @@ define { double, double } @add_complex_double(ptr %a, ptr %b) {
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
; MIPS32-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
- ; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
- ; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[COPY2]](p0) :: (load (s64) from %ir..realp)
+ ; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[COPY]](p0) :: (load (s64) from %ir..realp)
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; MIPS32-NEXT: %5:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
- ; MIPS32-NEXT: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD %5(p0) :: (load (s64) from %ir..imagp)
- ; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY1]](p0)
- ; MIPS32-NEXT: [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[COPY3]](p0) :: (load (s64) from %ir..realp1)
- ; MIPS32-NEXT: %9:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY1]], [[C]](s32)
- ; MIPS32-NEXT: [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD %9(p0) :: (load (s64) from %ir..imagp3)
+ ; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
+ ; MIPS32-NEXT: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD]](p0) :: (load (s64) from %ir..imagp)
+ ; MIPS32-NEXT: [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[COPY1]](p0) :: (load (s64) from %ir..realp1)
+ ; MIPS32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY1]], [[C]](s32)
+ ; MIPS32-NEXT: [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD1]](p0) :: (load (s64) from %ir..imagp3)
; MIPS32-NEXT: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[LOAD]], [[LOAD2]]
; MIPS32-NEXT: [[FADD1:%[0-9]+]]:_(s64) = G_FADD [[LOAD1]], [[LOAD3]]
; MIPS32-NEXT: $d0 = COPY [[FADD]](s64)
@@ -89,11 +85,10 @@ define void @call_ret_complex_float(ptr %z) {
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f0
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $f2
; MIPS32-NEXT: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
- ; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; MIPS32-NEXT: %5:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
- ; MIPS32-NEXT: G_STORE [[COPY1]](s32), [[COPY3]](p0) :: (store (s32) into %ir..realp)
- ; MIPS32-NEXT: G_STORE [[COPY2]](s32), %5(p0) :: (store (s32) into %ir..imagp)
+ ; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
+ ; MIPS32-NEXT: G_STORE [[COPY1]](s32), [[COPY]](p0) :: (store (s32) into %ir..realp)
+ ; MIPS32-NEXT: G_STORE [[COPY2]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir..imagp)
; MIPS32-NEXT: RetRA
entry:
%call = call { float, float } @ret_complex_float()
@@ -118,11 +113,10 @@ define void @call_ret_complex_double(ptr %z) {
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $d0
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $d1
; MIPS32-NEXT: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
- ; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; MIPS32-NEXT: %5:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
- ; MIPS32-NEXT: G_STORE [[COPY1]](s64), [[COPY3]](p0) :: (store (s64) into %ir..realp)
- ; MIPS32-NEXT: G_STORE [[COPY2]](s64), %5(p0) :: (store (s64) into %ir..imagp)
+ ; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
+ ; MIPS32-NEXT: G_STORE [[COPY1]](s64), [[COPY]](p0) :: (store (s64) into %ir..realp)
+ ; MIPS32-NEXT: G_STORE [[COPY2]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir..imagp)
; MIPS32-NEXT: RetRA
entry:
%call = call { double, double } @ret_complex_double()
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll
index 39fd348ecf799..133c79178f116 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll
@@ -10,11 +10,10 @@ define void @ZeroInit(ptr noalias sret(%struct.S) %agg.result) {
; MIPS32-NEXT: {{ $}}
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
- ; MIPS32-NEXT: G_STORE [[C]](s32), [[COPY1]](p0) :: (store (s32) into %ir.x)
+ ; MIPS32-NEXT: G_STORE [[C]](s32), [[COPY]](p0) :: (store (s32) into %ir.x)
; MIPS32-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; MIPS32-NEXT: %4:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C1]](s32)
- ; MIPS32-NEXT: G_STORE [[C]](s32), %4(p0) :: (store (s32) into %ir.y)
+ ; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C1]](s32)
+ ; MIPS32-NEXT: G_STORE [[C]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.y)
; MIPS32-NEXT: RetRA
entry:
%x = getelementptr inbounds %struct.S, ptr %agg.result, i32 0, i32 0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll b/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
index cf973aa68ffd7..70a2a9e578342 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
@@ -804,8 +804,7 @@ define void @test_sret(ptr sret(%struct.all) align 8 %result) #0 {
; X86-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
; X86-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (p0) from %fixed-stack.0, align 16)
; X86-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 104
- ; X86-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[LOAD]](p0)
- ; X86-NEXT: G_STORE [[C]](s8), [[COPY]](p0) :: (store (s8) into %ir.c, align 8)
+ ; X86-NEXT: G_STORE [[C]](s8), [[LOAD]](p0) :: (store (s8) into %ir.c, align 8)
; X86-NEXT: $eax = COPY [[LOAD]](p0)
; X86-NEXT: RET 0, $eax
;
@@ -815,8 +814,7 @@ define void @test_sret(ptr sret(%struct.all) align 8 %result) #0 {
; X64-NEXT: {{ $}}
; X64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $rdi
; X64-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 104
- ; X64-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
- ; X64-NEXT: G_STORE [[C]](s8), [[COPY1]](p0) :: (store (s8) into %ir.c, align 8)
+ ; X64-NEXT: G_STORE [[C]](s8), [[COPY]](p0) :: (store (s8) into %ir.c, align 8)
; X64-NEXT: $rax = COPY [[COPY]](p0)
; X64-NEXT: RET 0, $rax
entry:
``````````
</details>
https://github.com/llvm/llvm-project/pull/203029
More information about the llvm-commits
mailing list