Skip to content

Commit 0d1b803

Browse files
authored
[Backport to 14] SPIRVReader: Add OpCopyMemory support (#2779) (#2811)
Add support for translating `OpCopyMemory` into `llvm.memcpy`. Fixes #2769 (cherry picked from commit 8dc0349)
1 parent 6bddb95 commit 0d1b803

File tree

2 files changed

+77
-5
lines changed

2 files changed

+77
-5
lines changed

lib/SPIRV/SPIRVReader.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,9 +1812,28 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
18121812
return mapValue(BV, LI);
18131813
}
18141814

1815+
case OpCopyMemory: {
1816+
auto *BC = static_cast<SPIRVCopyMemory *>(BV);
1817+
llvm::Value *Dst = transValue(BC->getTarget(), F, BB);
1818+
MaybeAlign Align(BC->getAlignment());
1819+
MaybeAlign SrcAlign =
1820+
BC->getSrcAlignment() ? MaybeAlign(BC->getSrcAlignment()) : Align;
1821+
Type *EltTy =
1822+
transType(BC->getSource()->getType()->getPointerElementType());
1823+
uint64_t Size = M->getDataLayout().getTypeStoreSize(EltTy).getFixedValue();
1824+
bool IsVolatile = BC->SPIRVMemoryAccess::isVolatile();
1825+
IRBuilder<> Builder(BB);
1826+
1827+
llvm::Value *Src = transValue(BC->getSource(), F, BB);
1828+
CallInst *CI =
1829+
Builder.CreateMemCpy(Dst, Align, Src, SrcAlign, Size, IsVolatile);
1830+
if (isFuncNoUnwind())
1831+
CI->getFunction()->addFnAttr(Attribute::NoUnwind);
1832+
return mapValue(BV, CI);
1833+
}
1834+
18151835
case OpCopyMemorySized: {
18161836
SPIRVCopyMemorySized *BC = static_cast<SPIRVCopyMemorySized *>(BV);
1817-
CallInst *CI = nullptr;
18181837
llvm::Value *Dst = transValue(BC->getTarget(), F, BB);
18191838
MaybeAlign Align(BC->getAlignment());
18201839
MaybeAlign SrcAlign =
@@ -1823,10 +1842,9 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
18231842
bool IsVolatile = BC->SPIRVMemoryAccess::isVolatile();
18241843
IRBuilder<> Builder(BB);
18251844

1826-
if (!CI) {
1827-
llvm::Value *Src = transValue(BC->getSource(), F, BB);
1828-
CI = Builder.CreateMemCpy(Dst, Align, Src, SrcAlign, Size, IsVolatile);
1829-
}
1845+
llvm::Value *Src = transValue(BC->getSource(), F, BB);
1846+
CallInst *CI =
1847+
Builder.CreateMemCpy(Dst, Align, Src, SrcAlign, Size, IsVolatile);
18301848
if (isFuncNoUnwind())
18311849
CI->getFunction()->addFnAttr(Attribute::NoUnwind);
18321850
return mapValue(BV, CI);

test/OpCopyMemory.spvasm

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; Check SPIRVReader support for OpCopyMemory.
2+
3+
; REQUIRES: spirv-as
4+
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s
5+
; RUN: spirv-val %t.spv
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s
8+
9+
OpCapability Addresses
10+
OpCapability Int16
11+
OpCapability Kernel
12+
OpMemoryModel Physical64 OpenCL
13+
OpEntryPoint Kernel %kernel "copymemory"
14+
OpName %pStruct "pStruct"
15+
OpName %dstStruct "dstStruct"
16+
OpName %pShort "pShort"
17+
OpName %dstShort "dstShort"
18+
OpName %pInt "pInt"
19+
OpName %dstInt "dstInt"
20+
%ushort = OpTypeInt 16 0
21+
%uint = OpTypeInt 32 0
22+
%struct = OpTypeStruct %ushort %uint %ushort
23+
%void = OpTypeVoid
24+
%gptr_struct = OpTypePointer CrossWorkgroup %struct
25+
%pptr_struct = OpTypePointer Function %struct
26+
%gptr_short = OpTypePointer CrossWorkgroup %ushort
27+
%pptr_short = OpTypePointer Function %ushort
28+
%gptr_int = OpTypePointer CrossWorkgroup %uint
29+
%pptr_int = OpTypePointer Function %uint
30+
%kernel_sig = OpTypeFunction %void %gptr_short %gptr_int %gptr_struct
31+
%ushort_42 = OpConstant %ushort 42
32+
%uint_4242 = OpConstant %uint 4242
33+
%struct_init = OpConstantComposite %struct %ushort_42 %uint_4242 %ushort_42
34+
%kernel = OpFunction %void None %kernel_sig
35+
%dstShort = OpFunctionParameter %gptr_short
36+
%dstInt = OpFunctionParameter %gptr_int
37+
%dstStruct = OpFunctionParameter %gptr_struct
38+
%entry = OpLabel
39+
%pShort = OpVariable %pptr_short Function %ushort_42
40+
%pInt = OpVariable %pptr_int Function %uint_4242
41+
%pStruct = OpVariable %pptr_struct Function %struct_init
42+
OpCopyMemory %dstShort %pShort
43+
OpCopyMemory %dstInt %pInt
44+
OpCopyMemory %dstStruct %pStruct
45+
OpReturn
46+
OpFunctionEnd
47+
48+
; CHECK-LABEL: define spir_kernel void @copymemory(i16 addrspace(1)* %dstShort, i32 addrspace(1)* %dstInt, %structtype addrspace(1)* %dstStruct)
49+
; CHECK: %1 = bitcast i16 addrspace(1)* %dstShort to i8 addrspace(1)*
50+
; CHECK: call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %1, i8* bitcast (i16* @pShort to i8*), i64 2, i1 false)
51+
; CHECK: %2 = bitcast i32 addrspace(1)* %dstInt to i8 addrspace(1)*
52+
; CHECK: call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %2, i8* bitcast (i32* @pInt to i8*), i64 4, i1 false)
53+
; CHECK: %3 = bitcast %structtype addrspace(1)* %dstStruct to i8 addrspace(1)*
54+
; CHECK: call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* %3, i8* bitcast (%structtype* @pStruct to i8*), i64 12, i1 false)

0 commit comments

Comments
 (0)