[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