Skip to content

Commit 68c2b04

Browse files
badervladimirlaz
authored andcommitted
Improve llvm.memmove intrinsic support (#494)
- Add support for "partial" move - Teach the pass to look through addrspace cast - Add support for multiple casts Signed-off-by: Alexey Bader <[email protected]>
1 parent 4fdcbaa commit 68c2b04

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

llvm-spirv/lib/SPIRV/SPIRVLowerMemmove.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,12 @@ class SPIRVLowerMemmove : public ModulePass,
7575
report_fatal_error("llvm.memmove of non-constant length not supported",
7676
false);
7777
auto *Length = cast<ConstantInt>(I.getLength());
78-
if (isa<BitCastInst>(Src))
79-
// The source could be bit-cast from another type,
80-
// need the original type for the allocation of the temporary variable
81-
SrcTy = cast<BitCastInst>(Src)->getOperand(0)->getType();
78+
auto *S = Src;
79+
// The source could be bit-cast or addrspacecast from another type,
80+
// need the original type for the allocation of the temporary variable
81+
while (isa<BitCastInst>(S) || isa<AddrSpaceCastInst>(S))
82+
S = cast<CastInst>(S)->getOperand(0);
83+
SrcTy = S->getType();
8284
MaybeAlign Align = I.getSourceAlign();
8385
auto Volatile = I.isVolatile();
8486
Value *NumElements = nullptr;
@@ -87,9 +89,13 @@ class SPIRVLowerMemmove : public ModulePass,
8789
NumElements = Builder.getInt32(SrcTy->getArrayNumElements());
8890
ElementsCount = SrcTy->getArrayNumElements();
8991
}
90-
if (Mod->getDataLayout().getTypeSizeInBits(SrcTy->getPointerElementType()) *
91-
ElementsCount !=
92-
Length->getZExtValue() * 8)
92+
if (((ElementsCount > 1) && (Mod->getDataLayout().getTypeSizeInBits(
93+
SrcTy->getPointerElementType()) *
94+
ElementsCount !=
95+
Length->getZExtValue() * 8)) ||
96+
((ElementsCount == 1) &&
97+
(Mod->getDataLayout().getTypeSizeInBits(
98+
SrcTy->getPointerElementType()) < Length->getZExtValue() * 8)))
9399
report_fatal_error("Size of the memcpy should match the allocated memory",
94100
false);
95101

llvm-spirv/test/transcoding/llvm.memmove.ll

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,46 @@
1717
; CHECK-SPIRV: Bitcast [[i8Ty]] [[tmp3:[0-9]+]] [[mem]]
1818
; CHECK-SPIRV: LifetimeStop [[tmp3]] [[size]]
1919

20+
; CHECK-SPIRV: GenericCastToPtr {{[0-9]+}} [[out:[0-9]+]]
21+
; CHECK-SPIRV: Variable {{[0-9]+}} [[mem:[0-9]+]] 7
22+
; CHECK-SPIRV: Bitcast [[i8Ty:[0-9]+]] [[tmp0:[0-9]+]] [[mem]]
23+
; CHECK-SPIRV: LifetimeStart [[tmp0]] [[size:[0-9]+]]
24+
; CHECK-SPIRV: Bitcast [[i8Ty]] [[tmp1:[0-9]+]] [[mem]]
25+
; CHECK-SPIRV: CopyMemorySized [[tmp1]] {{[0-9]+}} {{[0-9]+}}
26+
; CHECK-SPIRV: Bitcast [[i8Ty]] [[tmp2:[0-9]+]] [[mem]]
27+
; CHECK-SPIRV: CopyMemorySized [[out]] [[tmp2]] {{[0-9]+}}
28+
; CHECK-SPIRV: Bitcast [[i8Ty]] [[tmp3:[0-9]+]] [[mem]]
29+
; CHECK-SPIRV: LifetimeStop [[tmp3]] [[size]]
30+
2031
; CHECK-LLVM-NOT: llvm.memmove
2132

33+
; CHECK-LLVM-LABEL: @test_struct
2234
; CHECK-LLVM: [[local:%[0-9]+]] = alloca %struct.SomeStruct
2335
; CHECK-LLVM: [[tmp1:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type:i[0-9]+\*]]
2436
; CHECK-LLVM: call void @llvm.lifetime.start.p0i8({{i[0-9]+}} {{-?[0-9]+}}, [[type]] [[tmp1]])
2537
; CHECK-LLVM: [[tmp2:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type]]
26-
; CHECK-LLVM: call void @llvm.memcpy
27-
; CHECK-LLVM: ([[type]] align 64 [[tmp2]],
28-
; CHECK-LLVM: {{i[0-9]+}} [[size:[0-9]+]]
38+
; CHECK-LLVM: call void @llvm.memcpy.p0i8.p1i8.i32
39+
; CHECK-LLVM-SAME: ([[type]] align 64 [[tmp2]],
40+
; CHECK-LLVM-SAME: {{i[0-9]+}} [[size:[0-9]+]]
2941
; CHECK-LLVM: [[tmp3:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type]]
30-
; CHECK-LLVM: call void @llvm.memcpy
31-
; CHECK-LLVM: , [[type]] align 64 [[tmp3]], {{i[0-9]+}} [[size]]
42+
; CHECK-LLVM: call void @llvm.memcpy.p1i8.p0i8.i32
43+
; CHECK-LLVM-SAME: , [[type]] align 64 [[tmp3]], {{i[0-9]+}} [[size]]
44+
; CHECK-LLVM: [[tmp4:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type]]
45+
; CHECK-LLVM: call void @llvm.lifetime.end.p0i8({{i[0-9]+}} {{-?[0-9]+}}, [[type]] [[tmp4]])
46+
47+
; CHECK-LLVM-LABEL: @copy_struct
48+
; CHECK-LLVM: [[out:%[0-9]+]] = addrspacecast i8 addrspace(4)* %2 to i8 addrspace(1)*
49+
; CHECK-LLVM: [[local:%[0-9]+]] = alloca %struct.SomeStruct
50+
; CHECK-LLVM: [[tmp1:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type:i[0-9]+\*]]
51+
; CHECK-LLVM: call void @llvm.lifetime.start.p0i8({{i[0-9]+}} {{-?[0-9]+}}, [[type]] [[tmp1]])
52+
; CHECK-LLVM: [[tmp2:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type]]
53+
; CHECK-LLVM: call void @llvm.memcpy.p0i8.p1i8.i32
54+
; CHECK-LLVM-SAME: ([[type]] align 64 [[tmp2]],
55+
; CHECK-LLVM-SAME: {{i[0-9]+}} [[size:[0-9]+]]
56+
; CHECK-LLVM: [[tmp3:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type]]
57+
; CHECK-LLVM: call void @llvm.memcpy.p1i8.p0i8.i32
58+
; CHECK-LLVM-SAME: align 64 [[out]]
59+
; CHECK-LLVM-SAME: , [[type]] align 64 [[tmp3]], {{i[0-9]+}} [[size]]
3260
; CHECK-LLVM: [[tmp4:%[0-9]+]] = bitcast %struct.SomeStruct* [[local]] to [[type]]
3361
; CHECK-LLVM: call void @llvm.lifetime.end.p0i8({{i[0-9]+}} {{-?[0-9]+}}, [[type]] [[tmp4]])
3462

@@ -45,6 +73,14 @@ define spir_kernel void @test_struct(%struct.SomeStruct addrspace(1)* nocapture
4573
ret void
4674
}
4775

76+
define spir_func void @copy_struct(%struct.SomeStruct addrspace(1)* nocapture readonly %in, %struct.SomeStruct addrspace(4)* nocapture %out) {
77+
%1 = bitcast %struct.SomeStruct addrspace(1)* %in to i8 addrspace(1)*
78+
%2 = bitcast %struct.SomeStruct addrspace(4)* %out to i8 addrspace(4)*
79+
%3 = addrspacecast i8 addrspace(4)* %2 to i8 addrspace(1)*
80+
call void @llvm.memmove.p1i8.p1i8.i32(i8 addrspace(1)* align 64 %3, i8 addrspace(1)* align 64 %1, i32 68, i1 false)
81+
ret void
82+
}
83+
4884
; Function Attrs: nounwind
4985
declare void @llvm.memmove.p1i8.p1i8.i32(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture readonly, i32, i1) #1
5086

0 commit comments

Comments
 (0)