[llvm] dae2935 - [SPIR-V] Drop constant zero-sized memcpy/memmove/memset before selection (#201904)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 06:02:31 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-06-09T15:02:26+02:00
New Revision: dae2935b32a673557e7060f8e90e73eaae4d6199

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

LOG: [SPIR-V] Drop constant zero-sized memcpy/memmove/memset before selection (#201904)

A constant zero Size operand is invalid for OpCopyMemorySized, and these
intrinsics are no-ops, so erase them instead of lowering

Added: 
    

Modified: 
    llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
    llvm/test/CodeGen/SPIRV/llvm-intrinsics/memcpy.align.ll
    llvm/test/CodeGen/SPIRV/llvm-intrinsics/memmove.ll
    llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index c3f21fe025bd5..d94e52002fdd3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2263,6 +2263,13 @@ bool SPIRVInstructionSelector::selectCopyMemorySized(MachineInstr &I,
 
 bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
                                                   MachineInstr &I) const {
+  // Zero-sized memcpy/memmove/memset are no-ops.
+  Register SizeReg = I.getOperand(2).getReg();
+  if (MachineInstr *SizeDef = getDefInstrMaybeConstant(SizeReg, MRI);
+      SizeDef && SizeDef->getOpcode() == TargetOpcode::G_CONSTANT &&
+      getIConstVal(SizeReg, MRI) == 0)
+    return true;
+
   Register SrcReg = I.getOperand(1).getReg();
   if (I.getOpcode() == TargetOpcode::G_MEMSET) {
     Register VarReg = getOrCreateMemSetGlobal(I);

diff  --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memcpy.align.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memcpy.align.ll
index 772fa154c0fc5..b4100019a8a0c 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memcpy.align.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memcpy.align.ll
@@ -52,3 +52,12 @@ entry:
   call void @llvm.lifetime.end.p0(i64 16, ptr %4)
   ret void
 }
+
+; CHECK: OpFunction
+; CHECK-NOT: OpCopyMemorySized
+; CHECK: OpFunctionEnd
+define spir_func void @zero(ptr %dst, ptr addrspace(2) %src) {
+entry:
+  call void @llvm.memcpy.p0.p2.i32(ptr align 4 %dst, ptr addrspace(2) align 4 %src, i32 0, i1 false)
+  ret void
+}

diff  --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memmove.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memmove.ll
index 986cab7516245..9e488a5652ab5 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memmove.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memmove.ll
@@ -32,6 +32,10 @@
 ; CHECK: %[[#Cast:]] = OpPtrCastToGeneric %[[#]] %[[#]]
 ; CHECK: OpCopyMemorySized %[[#Cast]] %[[#Phi]] %[[#Const_32_64]] Aligned 8
 
+; CHECK: OpFunction
+; CHECK-NOT: OpCopyMemorySized
+; CHECK: OpFunctionEnd
+
 %struct.SomeStruct = type { <16 x float>, i32, [60 x i8] }
 %class.kfunc = type <{ i32, i32, i32, [4 x i8] }>
 
@@ -81,6 +85,11 @@ merge:                                            ; preds = %entry.merge_crit_ed
   ret void
 }
 
+define spir_kernel void @test_zero_move(ptr addrspace(1) %in, ptr addrspace(1) %out) {
+  call void @llvm.memmove.p1.p1.i32(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 0, i1 false)
+  ret void
+}
+
 declare void @llvm.memmove.p4.p4.i64(ptr addrspace(4) captures(none) writeonly, ptr addrspace(4) captures(none) readonly, i64, i1 immarg)
 
 declare void @llvm.memmove.p1.p1.i32(ptr addrspace(1) captures(none), ptr addrspace(1) captures(none) readonly, i32, i1)

diff  --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll
index dba00b32d5de7..0666dcb25da28 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/memset.ll
@@ -85,6 +85,9 @@ define spir_func void @_Z5foo11v(ptr addrspace(4) noalias nocapture sret(ptr add
 
   ;; Volatile
   tail call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %c, i8 %v, i64 %s2, i1 true)
+
+  ;; Constant zero size is a no-op and must not emit OpCopyMemorySized.
+  tail call void @llvm.memset.p0.i32(ptr align 4 %x.bc, i8 21, i32 0, i1 false)
   ret void
 }
 


        


More information about the llvm-commits mailing list