Skip to content

Commit cebaf79

Browse files
authored
Remove Bitcast -> llvm.memset optimization in reverse translation (#1447)
It is done in order to avoid llvm.memcpy -> llvm.memset transformation which can be an incorrect assumption. SPIR-V does not have a memset instruction, there is a direct mapping only for `llvm.memcpy` to `OpCopyMemory*`. To handle `llvm.memset`, the input LLVM IR is lowered by `SPIRVRegularizeLLVM` pass. The mentioned optimization tried to restore the memset instruction but it surely does not cover all the possible cases (e.g., memcpy is not a memset inst). Possibly, the number of follow-up fixes for different corner cases can prove that the optimization is not absolutely correct, and it's better to rely on regularize pass.
1 parent 8a0235a commit cebaf79

File tree

4 files changed

+7
-26
lines changed

4 files changed

+7
-26
lines changed

lib/SPIRV/SPIRVReader.cpp

-23
Original file line numberDiff line numberDiff line change
@@ -1756,29 +1756,6 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
17561756
bool IsVolatile = BC->SPIRVMemoryAccess::isVolatile();
17571757
IRBuilder<> Builder(BB);
17581758

1759-
// If we copy from zero-initialized array, we can optimize it to llvm.memset
1760-
if (BC->getSource()->getOpCode() == OpBitcast) {
1761-
SPIRVValue *Source =
1762-
static_cast<SPIRVBitcast *>(BC->getSource())->getOperand(0);
1763-
if (Source->isVariable()) {
1764-
auto *Init = static_cast<SPIRVVariable *>(Source)->getInitializer();
1765-
if (isa<OpConstantNull>(Init)) {
1766-
SPIRVType *Ty = static_cast<SPIRVConstantNull *>(Init)->getType();
1767-
if (isa<OpTypeArray>(Ty)) {
1768-
Type *Int8Ty = Type::getInt8Ty(Dst->getContext());
1769-
llvm::Value *Src = ConstantInt::get(Int8Ty, 0);
1770-
llvm::Value *NewDst = Dst;
1771-
if (!Dst->getType()->getPointerElementType()->isIntegerTy(8)) {
1772-
Type *Int8PointerTy = Type::getInt8PtrTy(
1773-
Dst->getContext(), Dst->getType()->getPointerAddressSpace());
1774-
NewDst = llvm::BitCastInst::CreatePointerCast(Dst, Int8PointerTy,
1775-
"", BB);
1776-
}
1777-
CI = Builder.CreateMemSet(NewDst, Src, Size, Align, IsVolatile);
1778-
}
1779-
}
1780-
}
1781-
}
17821759
if (!CI) {
17831760
llvm::Value *Src = transValue(BC->getSource(), F, BB);
17841761
CI = Builder.CreateMemCpy(Dst, Align, Src, Align, Size, IsVolatile);

test/llvm-intrinsics/memset.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ define spir_func void @_Z5foo11v(%struct.S1 addrspace(4)* noalias nocapture sret
6868
%x.bc = bitcast [4 x i8]* %x to i8*
6969
%1 = bitcast %struct.S1 addrspace(4)* %agg.result to i8 addrspace(4)*
7070
tail call void @llvm.memset.p4i8.i32(i8 addrspace(4)* align 4 %1, i8 0, i32 12, i1 false)
71-
; CHECK-LLVM: call void @llvm.memset.p4i8.i32(i8 addrspace(4)* align 4 %1, i8 0, i32 12, i1 false)
71+
; CHECK-LLVM: call void @llvm.memcpy.p4i8.p2i8.i32(i8 addrspace(4)* align 4 %1, i8 addrspace(2)* align 4 %2, i32 12, i1 false)
7272
tail call void @llvm.memset.p0i8.i32(i8* align 4 %x.bc, i8 21, i32 4, i1 false)
7373
; CHECK-LLVM: call void @llvm.memcpy.p0i8.p2i8.i32(i8* align 4 %x.bc, i8 addrspace(2)* align 4 %3, i32 4, i1 false)
7474

test/transcoding/intrinsic_result_store.ll

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
1010
target triple = "spir64-unknown-unknown"
1111

12+
; CHECK-LLVM: [[ZERO_INIT:@[0-9]+]] = {{.*}} addrspace(2) constant [8 x i8] zeroinitializer
13+
1214
; Function Attrs: convergent noinline nounwind optnone
1315
define spir_kernel void @test_memset(i32 addrspace(1)* %data, i32 %input) #0 !kernel_arg_addr_space !1 !kernel_arg_access_qual !5 !kernel_arg_type !6 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 {
1416
entry:
1517
; CHECK-LLVM: %[[BITCAST_RES:[[:alnum:].]+]] = bitcast i32 addrspace(1)* %{{[[:alnum:].]+}} to i8 addrspace(1)*
1618
%ptr = bitcast i32 addrspace(1)* %data to i8 addrspace(1)*
17-
; CHECK-LLVM: call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 8 %[[BITCAST_RES]], i8 0, i64 8, i1 false)
19+
; CHECK-LLVM: %[[#ZERO_INIT_BITCAST:]] = bitcast [8 x i8] addrspace(2)* [[ZERO_INIT]] to i8 addrspace(2)*
20+
; CHECK-LLVM: call void @llvm.memcpy.p1i8.p2i8.i64(i8 addrspace(1)* align 8 %[[BITCAST_RES]], i8 addrspace(2)* align 8 %[[#ZERO_INIT_BITCAST]], i64 8, i1 false)
1821
call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 8 %ptr, i8 0, i64 8, i1 false)
1922
; CHECK-LLVM: store i8 0, i8 addrspace(1)* %[[BITCAST_RES]]
2023
store i8 0, i8 addrspace(1)* %ptr

test/transcoding/sycl_array_zero_init.ll

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ define weak_odr dso_local spir_kernel void @main() #0 comdat !kernel_arg_addr_sp
2323
%5 = bitcast [3 x i64] addrspace(4)* %4 to i8 addrspace(4)*
2424
; CHECK: %[[V_ARR:[0-9]+]] = bitcast [3 x i64] addrspace(4)* %{{[0-9]+}} to i8 addrspace(4)*
2525
%6 = bitcast [3 x i64] addrspace(4)* @constinit to i8 addrspace(4)*
26+
; CHECK: %[[#CONST_INIT:]] = bitcast [3 x i64] addrspace(4)* @constinit to i8 addrspace(4)*
2627
call void @llvm.memcpy.p4i8.p4i8.i64(i8 addrspace(4)* align 8 %5, i8 addrspace(4)* align 8 %6, i64 24, i1 false), !tbaa.struct !7
27-
; CHECK: call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 8 %[[V_ARR]], i8 0, i64 24, i1 false)
28+
; CHECK: call void @llvm.memcpy.p4i8.p4i8.i64(i8 addrspace(4)* align 8 %[[V_ARR]], i8 addrspace(4)* align 8 %[[#CONST_INIT]], i64 24, i1 false)
2829
%7 = bitcast %array* %1 to i8*
2930
call void @llvm.lifetime.end.p0i8(i64 24, i8* %7) #2
3031
ret void

0 commit comments

Comments
 (0)