[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