[llvm] [RISCV][GlobalISel] Call `tryEmitMemcpyInline` for G_MEMCPY_INLINE (PR #192671)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 17 08:13:16 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: Gábor Spaits (spaits)

<details>
<summary>Changes</summary>

Before this, MIR that contained G_MEMCPY_INLINE has failed in the lagalization stage.

This patch also adds a C++ implementation for `tryCombineAll` and renames and calls the TD generated implementation to `tryCombineAllImpl`. (Just like it happens on AArch64.)

The test added was inspired by `llvm/test/CodeGen/Mips/GlobalISel/mips-prelegalizer-combiner/inline-memcpy.mir` .

---
Full diff: https://github.com/llvm/llvm-project/pull/192671.diff


3 Files Affected:

- (modified) llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp (+14) 
- (modified) llvm/lib/Target/RISCV/RISCVCombine.td (+1) 
- (added) llvm/test/CodeGen/RISCV/GlobalISel/prelegalizer-combiner/inline-memcpy.mir (+63) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp b/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
index f652f74c8bdc7..b1ae7f0e3caeb 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
@@ -55,6 +55,7 @@ class RISCVPreLegalizerCombinerImpl : public Combiner {
   static const char *getName() { return "RISCV00PreLegalizerCombiner"; }
 
   bool tryCombineAll(MachineInstr &I) const override;
+  bool tryCombineAllImpl(MachineInstr &I) const;
 
 private:
 #define GET_GICOMBINER_CLASS_MEMBERS
@@ -154,6 +155,19 @@ bool RISCVPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
   return Impl.combineMachineInstrs();
 }
 
+bool RISCVPreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
+  if (tryCombineAllImpl(MI))
+    return true;
+
+  unsigned Opc = MI.getOpcode();
+  switch (Opc) {
+  case TargetOpcode::G_MEMCPY_INLINE:
+    return Helper.tryEmitMemcpyInline(MI);
+  }
+
+  return false;
+}
+
 char RISCVPreLegalizerCombiner::ID = 0;
 INITIALIZE_PASS_BEGIN(RISCVPreLegalizerCombiner, DEBUG_TYPE,
                       "Combine RISC-V machine instrs before legalization", false,
diff --git a/llvm/lib/Target/RISCV/RISCVCombine.td b/llvm/lib/Target/RISCV/RISCVCombine.td
index a06b60d8cce07..1083558e8c163 100644
--- a/llvm/lib/Target/RISCV/RISCVCombine.td
+++ b/llvm/lib/Target/RISCV/RISCVCombine.td
@@ -13,6 +13,7 @@ include "llvm/Target/GlobalISel/Combine.td"
 
 def RISCVPreLegalizerCombiner: GICombiner<
   "RISCVPreLegalizerCombinerImpl", [all_combines]> {
+  let CombineAllMethodName = "tryCombineAllImpl";
 }
 
 def RISCVO0PreLegalizerCombiner: GICombiner<
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/prelegalizer-combiner/inline-memcpy.mir b/llvm/test/CodeGen/RISCV/GlobalISel/prelegalizer-combiner/inline-memcpy.mir
new file mode 100644
index 0000000000000..66575c71a9f7b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/prelegalizer-combiner/inline-memcpy.mir
@@ -0,0 +1,63 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -O0 -mtriple=riscv32 -run-pass=riscv-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=RISCV32
+# RUN: llc -O0 -mtriple=riscv64 -run-pass=riscv-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=RISCV64
+
+--- |
+  declare void @llvm.memcpy.inline.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64 immarg, i1 immarg) #0
+
+  define void @test_memcpy_inline(ptr nocapture %dst, ptr nocapture readonly %src) local_unnamed_addr {
+  entry:
+    %0 = bitcast ptr %dst to ptr
+    %1 = bitcast ptr %src to ptr
+    tail call void @llvm.memcpy.inline.p0.p0.i64(ptr align 4 %0, ptr align 4 %1, i64 2, i1 false)
+    ret void
+  }
+
+  attributes #0 = { argmemonly nofree nounwind willreturn }
+...
+
+---
+name:            test_memcpy_inline
+alignment:       4
+liveins:
+  - { reg: '$x10', virtual-reg: '' }
+  - { reg: '$x11', virtual-reg: '' }
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11
+
+    ; RISCV32-LABEL: name: test_memcpy_inline
+    ; RISCV32: liveins: $x10, $x11
+    ; RISCV32-NEXT: {{  $}}
+    ; RISCV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+    ; RISCV32-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+    ; RISCV32-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY1]](p0) :: (load (s8) from %ir.1, align 4)
+    ; RISCV32-NEXT: G_STORE [[LOAD]](s8), [[COPY]](p0) :: (store (s8) into %ir.0, align 4)
+    ; RISCV32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+    ; RISCV32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY1]], [[C]](s32)
+    ; RISCV32-NEXT: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[PTR_ADD]](p0) :: (load (s8) from %ir.1 + 1, basealign 4)
+    ; RISCV32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C]](s32)
+    ; RISCV32-NEXT: G_STORE [[LOAD1]](s8), [[PTR_ADD1]](p0) :: (store (s8) into %ir.0 + 1, basealign 4)
+    ; RISCV32-NEXT: PseudoRET
+    ;
+    ; RISCV64-LABEL: name: test_memcpy_inline
+    ; RISCV64: liveins: $x10, $x11
+    ; RISCV64-NEXT: {{  $}}
+    ; RISCV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+    ; RISCV64-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+    ; RISCV64-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY1]](p0) :: (load (s8) from %ir.1, align 4)
+    ; RISCV64-NEXT: G_STORE [[LOAD]](s8), [[COPY]](p0) :: (store (s8) into %ir.0, align 4)
+    ; RISCV64-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+    ; RISCV64-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY1]], [[C]](s64)
+    ; RISCV64-NEXT: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[PTR_ADD]](p0) :: (load (s8) from %ir.1 + 1, basealign 4)
+    ; RISCV64-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C]](s64)
+    ; RISCV64-NEXT: G_STORE [[LOAD1]](s8), [[PTR_ADD1]](p0) :: (store (s8) into %ir.0 + 1, basealign 4)
+    ; RISCV64-NEXT: PseudoRET
+    %0:_(p0) = COPY $x10
+    %1:_(p0) = COPY $x11
+    %2:_(s64) = G_CONSTANT i64 2
+    %3:_(s32) = G_TRUNC %2(s64)
+    G_MEMCPY_INLINE %0(p0), %1(p0), %3(s32) :: (store (s8) into %ir.0, align 4), (load (s8) from %ir.1, align 4)
+    PseudoRET
+
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/192671


More information about the llvm-commits mailing list