diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 66793e25d..8af73f748 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2230,6 +2230,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 7ab9358af..e49101c34 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -2068,6 +2068,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 aa21bf4ed..236307f58 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 000000000..a8874c596 --- /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)