Skip to content

Commit 67941b8

Browse files
KornevNikitavmaksimo
authored andcommitted
Support SPV_INTEL_complex_float_mul_div extension
Spec: intel#5824 Intrinsics: https://reviews.llvm.org/D119284 Co-authored-by: Mikhail Lychkov <[email protected]> Original commit: KhronosGroup/SPIRV-LLVM-Translator@bc94b7c
1 parent b42cc9a commit 67941b8

File tree

6 files changed

+123
-1
lines changed

6 files changed

+123
-1
lines changed

llvm-spirv/include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@ EXT(SPV_INTEL_joint_matrix)
5151
EXT(SPV_INTEL_hw_thread_queries)
5252
EXT(SPV_INTEL_global_variable_decorations)
5353
EXT(SPV_INTEL_non_constant_addrspace_printf)
54+
EXT(SPV_INTEL_complex_float_mul_div)

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,6 +3327,50 @@ _SPIRV_OP(GroupLogicalAnd, true, 6, false, 1)
33273327
_SPIRV_OP(GroupLogicalOr, true, 6, false, 1)
33283328
_SPIRV_OP(GroupLogicalXor, true, 6, false, 1)
33293329
#undef _SPIRV_OP
3330+
3331+
class SPIRVComplexFloat : public SPIRVInstTemplateBase {
3332+
protected:
3333+
void validate() const override {
3334+
SPIRVId Op1 = Ops[0];
3335+
SPIRVId Op2 = Ops[1];
3336+
SPIRVType *Op1Ty, *Op2Ty;
3337+
SPIRVInstruction::validate();
3338+
if (getValue(Op1)->isForward() || getValue(Op2)->isForward())
3339+
return;
3340+
if (getValueType(Op1)->isTypeVector()) {
3341+
Op1Ty = getValueType(Op1)->getVectorComponentType();
3342+
Op2Ty = getValueType(Op2)->getVectorComponentType();
3343+
assert(getValueType(Op1)->getVectorComponentCount() ==
3344+
getValueType(Op2)->getVectorComponentCount() &&
3345+
"Inconsistent Vector component width");
3346+
} else {
3347+
Op1Ty = getValueType(Op1);
3348+
Op2Ty = getValueType(Op2);
3349+
}
3350+
(void)Op1Ty;
3351+
(void)Op2Ty;
3352+
assert(Op1Ty->isTypeFloat() && "Invalid type for complex instruction");
3353+
assert(Op1Ty == Op2Ty && "Invalid type for complex instruction");
3354+
}
3355+
3356+
public:
3357+
SPIRVCapVec getRequiredCapability() const override {
3358+
return getVec(internal::CapabilityComplexFloatMulDivINTEL);
3359+
}
3360+
3361+
llvm::Optional<ExtensionID> getRequiredExtension() const override {
3362+
return ExtensionID::SPV_INTEL_complex_float_mul_div;
3363+
}
3364+
};
3365+
3366+
template <Op OC>
3367+
class SPIRVComplexFloatInst
3368+
: public SPIRVInstTemplate<SPIRVComplexFloat, OC, true, 5, false> {};
3369+
3370+
#define _SPIRV_OP(x) typedef SPIRVComplexFloatInst<internal::Op##x> SPIRV##x;
3371+
_SPIRV_OP(ComplexFMulINTEL)
3372+
_SPIRV_OP(ComplexFDivINTEL)
3373+
#undef _SPIRV_OP
33303374
} // namespace SPIRV
33313375

33323376
#endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
594594
"GlobalVariableDecorationsINTEL");
595595
add(internal::CapabilityNonConstantAddrspacePrintfINTEL,
596596
"NonConstantAddrspacePrintfINTEL");
597+
add(internal::CapabilityComplexFloatMulDivINTEL, "ComplexFloatMulDivINTEL");
597598
}
598599
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
599600

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ _SPIRV_OP_INTERNAL(JointMatrixStoreINTEL, internal::OpJointMatrixStoreINTEL)
1111
_SPIRV_OP_INTERNAL(JointMatrixMadINTEL, internal::OpJointMatrixMadINTEL)
1212
_SPIRV_OP_INTERNAL(JointMatrixWorkItemLengthINTEL,
1313
internal::OpJointMatrixWorkItemLengthINTEL)
14+
_SPIRV_OP_INTERNAL(ComplexFMulINTEL, internal::ComplexFMulINTEL)
15+
_SPIRV_OP_INTERNAL(ComplexFDivINTEL, internal::ComplexFDivINTEL)

llvm-spirv/lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ enum InternalOp {
4444
IOpJointMatrixMadINTEL = 6122,
4545
IOpArithmeticFenceINTEL = 6145,
4646
IOpJointMatrixWorkItemLengthINTEL = 6410,
47+
IOpComplexFMulINTEL = 6415,
48+
IOpComplexFDivINTEL = 6416,
4749
IOpPrev = OpMax - 2,
4850
IOpForward
4951
};
@@ -75,7 +77,8 @@ enum InternalCapability {
7577
ICapabilityHWThreadQueryINTEL = 6134,
7678
ICapFPArithmeticFenceINTEL = 6144,
7779
ICapGlobalVariableDecorationsINTEL = 6146,
78-
ICapabilityNonConstantAddrspacePrintfINTEL = 6411
80+
ICapabilityNonConstantAddrspacePrintfINTEL = 6411,
81+
ICapabilityComplexFloatMulDivINTEL = 6414
7982
};
8083

8184
enum InternalFunctionControlMask { IFunctionControlOptNoneINTELMask = 0x10000 };
@@ -109,6 +112,10 @@ _SPIRV_OP(BuiltIn, SubDeviceIDINTEL)
109112
_SPIRV_OP(BuiltIn, GlobalHWThreadIDINTEL)
110113

111114
_SPIRV_OP(Capability, NonConstantAddrspacePrintfINTEL)
115+
116+
_SPIRV_OP(Capability, ComplexFloatMulDivINTEL)
117+
_SPIRV_OP(Op, ComplexFMulINTEL)
118+
_SPIRV_OP(Op, ComplexFDivINTEL)
112119
#undef _SPIRV_OP
113120

114121
constexpr Op OpForward = static_cast<Op>(IOpForward);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_complex_float_mul_div
3+
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
4+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
5+
6+
; RUN: llvm-spirv %t.spv -o %t.rev.bc -r
7+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
8+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
9+
10+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
11+
12+
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
13+
; CHECK-ERROR-NEXT: SPV_INTEL_complex_float_mul_div
14+
15+
; CHECK-SPIRV: Capability ComplexFloatMulDivINTEL
16+
; CHECK-SPIRV: Extension "SPV_INTEL_complex_float_mul_div"
17+
; CHECK-SPIRV: TypeFloat [[#TyFloat32:]] 32
18+
; CHECK-SPIRV: TypeVector [[#TyVec2Float32:]] [[#TyFloat32]] 2
19+
; CHECK-SPIRV: ComplexFDivINTEL [[#TyVec2Float32]] [[#]] [[#]] [[#]]
20+
; CHECK-SPIRV: ComplexFMulINTEL [[#TyVec2Float32]] [[#]] [[#]] [[#]]
21+
22+
; CHECK-LLVM: call spir_func <2 x float> @_Z24__spirv_ComplexFDivINTEL{{.*}}(<2 x float>{{.*}}, <2 x float>{{.*}})
23+
; CHECK-LLVM: call spir_func <2 x float> @_Z24__spirv_ComplexFMulINTEL{{.*}}(<2 x float>{{.*}}, <2 x float>{{.*}})
24+
25+
; ModuleID = 'complex-operations'
26+
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024"
27+
target triple = "spir-unknown-unknown"
28+
29+
%"struct.std::complex" = type { %structtype }
30+
%structtype = type { float, float }
31+
32+
; Function Attrs: nounwind
33+
define spir_func void @_Z19cmul_kernel_complexPSt7complexIfES1_S1_(%"struct.std::complex"* noalias nocapture readonly %a, %"struct.std::complex"* noalias nocapture readonly %b, %"struct.std::complex"* noalias nocapture %c) #0 {
34+
entry:
35+
%0 = bitcast %"struct.std::complex"* %a to <2 x float>*
36+
%1 = load <2 x float>, <2 x float>* %0, align 4
37+
%2 = bitcast %"struct.std::complex"* %b to <2 x float>*
38+
%3 = load <2 x float>, <2 x float>* %2, align 4
39+
%4 = call spir_func <2 x float> @_Z24__spirv_ComplexFDivINTELDv2_fS_(<2 x float> %1, <2 x float> %3) #0
40+
%ref.tmp.sroa.0.0..sroa_cast5 = bitcast %"struct.std::complex"* %c to <2 x float>*
41+
store <2 x float> %4, <2 x float>* %ref.tmp.sroa.0.0..sroa_cast5, align 4
42+
%5 = call spir_func <2 x float> @_Z24__spirv_ComplexFMulINTELDv2_fS_(<2 x float> %1, <2 x float> %3) #0
43+
store <2 x float> %5, <2 x float>* %ref.tmp.sroa.0.0..sroa_cast5, align 4
44+
ret void
45+
}
46+
47+
; Function Attrs: nounwind
48+
declare spir_func <2 x float> @_Z24__spirv_ComplexFDivINTELDv2_fS_(<2 x float>, <2 x float>) #0
49+
50+
; Function Attrs: nounwind
51+
declare spir_func <2 x float> @_Z24__spirv_ComplexFMulINTELDv2_fS_(<2 x float>, <2 x float>) #0
52+
53+
attributes #0 = { nounwind }
54+
55+
!spirv.MemoryModel = !{!0}
56+
!opencl.enable.FP_CONTRACT = !{}
57+
!spirv.Source = !{!1}
58+
!opencl.spir.version = !{!0}
59+
!opencl.ocl.version = !{!1}
60+
!opencl.used.extensions = !{!2}
61+
!opencl.used.optional.core.features = !{!2}
62+
!spirv.Generator = !{!3}
63+
64+
!0 = !{i32 1, i32 2}
65+
!1 = !{i32 0, i32 0}
66+
!2 = !{}
67+
!3 = !{i16 6, i16 14}

0 commit comments

Comments
 (0)