Skip to content

Commit

Permalink
[Backport to 14] SPIRVReader: Add OpCopyMemory support (#2779) (#2811)
Browse files Browse the repository at this point in the history
Add support for translating `OpCopyMemory` into `llvm.memcpy`.

Fixes #2769

(cherry picked from commit 8dc0349)
  • Loading branch information
svenvh authored Oct 30, 2024
1 parent 6bddb95 commit 0d1b803
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 5 deletions.
28 changes: 23 additions & 5 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1812,9 +1812,28 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
return mapValue(BV, LI);
}

case OpCopyMemory: {
auto *BC = static_cast<SPIRVCopyMemory *>(BV);
llvm::Value *Dst = transValue(BC->getTarget(), F, BB);
MaybeAlign Align(BC->getAlignment());
MaybeAlign SrcAlign =
BC->getSrcAlignment() ? MaybeAlign(BC->getSrcAlignment()) : Align;
Type *EltTy =
transType(BC->getSource()->getType()->getPointerElementType());
uint64_t Size = M->getDataLayout().getTypeStoreSize(EltTy).getFixedValue();
bool IsVolatile = BC->SPIRVMemoryAccess::isVolatile();
IRBuilder<> Builder(BB);

llvm::Value *Src = transValue(BC->getSource(), F, BB);
CallInst *CI =
Builder.CreateMemCpy(Dst, Align, Src, SrcAlign, Size, IsVolatile);
if (isFuncNoUnwind())
CI->getFunction()->addFnAttr(Attribute::NoUnwind);
return mapValue(BV, CI);
}

case OpCopyMemorySized: {
SPIRVCopyMemorySized *BC = static_cast<SPIRVCopyMemorySized *>(BV);
CallInst *CI = nullptr;
llvm::Value *Dst = transValue(BC->getTarget(), F, BB);
MaybeAlign Align(BC->getAlignment());
MaybeAlign SrcAlign =
Expand All @@ -1823,10 +1842,9 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
bool IsVolatile = BC->SPIRVMemoryAccess::isVolatile();
IRBuilder<> Builder(BB);

if (!CI) {
llvm::Value *Src = transValue(BC->getSource(), F, BB);
CI = Builder.CreateMemCpy(Dst, Align, Src, SrcAlign, Size, IsVolatile);
}
llvm::Value *Src = transValue(BC->getSource(), F, BB);
CallInst *CI =
Builder.CreateMemCpy(Dst, Align, Src, SrcAlign, Size, IsVolatile);
if (isFuncNoUnwind())
CI->getFunction()->addFnAttr(Attribute::NoUnwind);
return mapValue(BV, CI);
Expand Down
54 changes: 54 additions & 0 deletions test/OpCopyMemory.spvasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
; Check SPIRVReader support for OpCopyMemory.

; REQUIRES: spirv-as
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s
; RUN: spirv-val %t.spv
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s

OpCapability Addresses
OpCapability Int16
OpCapability Kernel
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %kernel "copymemory"
OpName %pStruct "pStruct"
OpName %dstStruct "dstStruct"
OpName %pShort "pShort"
OpName %dstShort "dstShort"
OpName %pInt "pInt"
OpName %dstInt "dstInt"
%ushort = OpTypeInt 16 0
%uint = OpTypeInt 32 0
%struct = OpTypeStruct %ushort %uint %ushort
%void = OpTypeVoid
%gptr_struct = OpTypePointer CrossWorkgroup %struct
%pptr_struct = OpTypePointer Function %struct
%gptr_short = OpTypePointer CrossWorkgroup %ushort
%pptr_short = OpTypePointer Function %ushort
%gptr_int = OpTypePointer CrossWorkgroup %uint
%pptr_int = OpTypePointer Function %uint
%kernel_sig = OpTypeFunction %void %gptr_short %gptr_int %gptr_struct
%ushort_42 = OpConstant %ushort 42
%uint_4242 = OpConstant %uint 4242
%struct_init = OpConstantComposite %struct %ushort_42 %uint_4242 %ushort_42
%kernel = OpFunction %void None %kernel_sig
%dstShort = OpFunctionParameter %gptr_short
%dstInt = OpFunctionParameter %gptr_int
%dstStruct = OpFunctionParameter %gptr_struct
%entry = OpLabel
%pShort = OpVariable %pptr_short Function %ushort_42
%pInt = OpVariable %pptr_int Function %uint_4242
%pStruct = OpVariable %pptr_struct Function %struct_init
OpCopyMemory %dstShort %pShort
OpCopyMemory %dstInt %pInt
OpCopyMemory %dstStruct %pStruct
OpReturn
OpFunctionEnd

; CHECK-LABEL: define spir_kernel void @copymemory(i16 addrspace(1)* %dstShort, i32 addrspace(1)* %dstInt, %structtype addrspace(1)* %dstStruct)
; CHECK: %1 = bitcast i16 addrspace(1)* %dstShort to i8 addrspace(1)*
; CHECK: call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %1, i8* bitcast (i16* @pShort to i8*), i64 2, i1 false)
; CHECK: %2 = bitcast i32 addrspace(1)* %dstInt to i8 addrspace(1)*
; CHECK: call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %2, i8* bitcast (i32* @pInt to i8*), i64 4, i1 false)
; CHECK: %3 = bitcast %structtype addrspace(1)* %dstStruct to i8 addrspace(1)*
; CHECK: call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %3, i8* bitcast (%structtype* @pStruct to i8*), i64 12, i1 false)

0 comments on commit 0d1b803

Please sign in to comment.