From d6cd5630c4eb7219845f6fe5a4a22281cc37ab7b Mon Sep 17 00:00:00 2001 From: Viktoria Maximova Date: Fri, 12 Apr 2024 19:46:44 +0200 Subject: [PATCH 1/2] [SPIR-V 1.4] Add CopyLogical instruction (#2484) There is no mapping to LLVM instructions, so it can be used only via SPIR-V friendly translation. This addresses p1. of #2460 (cherry picked from commit 8518a6f72fd586c9222f34bb3b9fa31a5fa9cb5d) --- lib/SPIRV/SPIRVReader.cpp | 4 ++++ lib/SPIRV/libSPIRV/SPIRVInstruction.h | 25 +++++++++++++++++++++++++ lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 1 + test/OpCopyLogical.spvasm | 25 +++++++++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 test/OpCopyLogical.spvasm diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index b6c5e91106..0bc451ac26 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2156,6 +2156,10 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, LoadInst *LI = new LoadInst(Ty, AI, "", BB); return mapValue(BV, LI); } + case OpCopyLogical: { + SPIRVCopyLogical *CL = static_cast(BV); + return mapValue(BV, transSPIRVBuiltinFromInst(CL, BB)); + } case OpAccessChain: case OpInBoundsAccessChain: diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h index 30375313d4..fbecfc0470 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -2049,6 +2049,31 @@ class SPIRVCopyObject : public SPIRVInstruction { SPIRVId Operand; }; +class SPIRVCopyLogical : public SPIRVInstruction { +public: + const static Op OC = OpCopyLogical; + + // Complete constructor + SPIRVCopyLogical(SPIRVType *TheType, SPIRVId TheId, SPIRVValue *TheOperand, + SPIRVBasicBlock *TheBB) + : SPIRVInstruction(4, OC, TheType, TheId, TheBB), + Operand(TheOperand->getId()) { + validate(); + assert(TheBB && "Invalid BB"); + } + // Incomplete constructor + SPIRVCopyLogical() : SPIRVInstruction(OC), Operand(SPIRVID_INVALID) {} + + SPIRVValue *getOperand() { return getValue(Operand); } + std::vector getOperands() override { return {getOperand()}; } + +protected: + _SPIRV_DEF_ENCDEC3(Type, Id, Operand) + + void validate() const override { SPIRVInstruction::validate(); } + SPIRVId Operand; +}; + class SPIRVCopyMemory : public SPIRVInstruction, public SPIRVMemoryAccess { public: const static Op OC = OpCopyMemory; diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h index aa21bf4ed2..236307f582 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h @@ -330,6 +330,7 @@ _SPIRV_OP(GroupNonUniformBitwiseXor, 361) _SPIRV_OP(GroupNonUniformLogicalAnd, 362) _SPIRV_OP(GroupNonUniformLogicalOr, 363) _SPIRV_OP(GroupNonUniformLogicalXor, 364) +_SPIRV_OP(CopyLogical, 400) _SPIRV_OP(PtrEqual, 401) _SPIRV_OP(PtrNotEqual, 402) _SPIRV_OP(PtrDiff, 403) diff --git a/test/OpCopyLogical.spvasm b/test/OpCopyLogical.spvasm new file mode 100644 index 0000000000..a8874c5961 --- /dev/null +++ b/test/OpCopyLogical.spvasm @@ -0,0 +1,25 @@ +; Check support of OpCopyLogical instruction that was added in SPIR-V 1.4 + +; REQUIRES: spirv-as +; RUN: spirv-as --target-env spv1.4 -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 +; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM + OpCapability Addresses + OpCapability Kernel + OpMemoryModel Physical32 OpenCL + OpEntryPoint Kernel %1 "test" + OpName %entry "entry" + %void = OpTypeVoid + %_struct_4 = OpTypeStruct + %_struct_5 = OpTypeStruct + %6 = OpConstantComposite %_struct_4 + %7 = OpTypeFunction %void + %1 = OpFunction %void None %7 + %entry = OpLabel + %8 = OpCopyLogical %_struct_5 %6 + OpReturn + OpFunctionEnd + +; CHECK-LLVM: @_Z19__spirv_CopyLogical12structtype.0(ptr sret(%structtype) %[[#]], %structtype.0 zeroinitializer) From be55b8c2f4c44e8d18b5a2df92da228079dec6d1 Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Fri, 8 Nov 2024 13:09:51 -0800 Subject: [PATCH 2/2] [Backport to 16] Generate load and store for OpCopyLogical (#2825) fixes #2768 Generate an LLVM memcpy for OpCopyLogical, rather than a call to an OpCopyLogical function. (cherry picked from commit 1a1bf17d9e8684cd826e4278e78f63aa80e2e2ca) --- lib/SPIRV/SPIRVReader.cpp | 17 ++++++++++++++++- test/OpCopyLogical.spvasm | 6 ++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 0bc451ac26..8f6e6fa669 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2158,7 +2158,22 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, } case OpCopyLogical: { SPIRVCopyLogical *CL = static_cast(BV); - return mapValue(BV, transSPIRVBuiltinFromInst(CL, BB)); + + auto *SrcTy = transType(CL->getOperand()->getType()); + auto *DstTy = transType(CL->getType()); + + assert(M->getDataLayout().getTypeStoreSize(SrcTy).getFixedValue() == + M->getDataLayout().getTypeStoreSize(DstTy).getFixedValue() && + "Size mismatch in OpCopyLogical"); + + IRBuilder<> Builder(BB); + + auto *SrcAI = Builder.CreateAlloca(SrcTy); + Builder.CreateAlignedStore(transValue(CL->getOperand(), F, BB), SrcAI, + SrcAI->getAlign()); + + auto *LI = Builder.CreateAlignedLoad(DstTy, SrcAI, SrcAI->getAlign()); + return mapValue(BV, LI); } case OpAccessChain: diff --git a/test/OpCopyLogical.spvasm b/test/OpCopyLogical.spvasm index a8874c5961..7af03a1d69 100644 --- a/test/OpCopyLogical.spvasm +++ b/test/OpCopyLogical.spvasm @@ -3,7 +3,7 @@ ; REQUIRES: spirv-as ; RUN: spirv-as --target-env spv1.4 -o %t.spv %s ; RUN: spirv-val %t.spv -; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc ; RUN: llvm-dis %t.rev.bc ; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM OpCapability Addresses @@ -22,4 +22,6 @@ OpReturn OpFunctionEnd -; CHECK-LLVM: @_Z19__spirv_CopyLogical12structtype.0(ptr sret(%structtype) %[[#]], %structtype.0 zeroinitializer) +; CHECK-LLVM: [[ALLOCA:%[a-z0-9.]+]] = alloca [[SRC_TYPE:%[a-z0-9.]+]], align 8 +; CHECK-LLVM: store [[SRC_TYPE]] zeroinitializer, ptr [[ALLOCA]], align 8 +; CHECK-LLVM: [[DST:%[a-z0-9.]+]] = load [[DST_TYPE:%[a-z0-9.]+]], ptr [[ALLOCA]], align 8