Skip to content

Commit 062678d

Browse files
[Backport to 16] Implement SPV_INTEL_predicated_io extension (KhronosGroup#3370)
This extension adds predicated load and store instructions. Predicated load performs load from memory if predicate is true; otherwise, it uses default_value as a result. Predicated store performs store of value to memory if predicate is true; otherwise, it does nothing. Spec: intel/llvm#20158 Signed-off-by: Zhang, Yixing <yixing.zhang@intel.com>
1 parent 0983ca9 commit 062678d

File tree

6 files changed

+111
-0
lines changed

6 files changed

+111
-0
lines changed

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,4 @@ EXT(SPV_INTEL_ternary_bitwise_function)
8080
EXT(SPV_INTEL_int4)
8181
EXT(SPV_INTEL_function_variants)
8282
EXT(SPV_INTEL_shader_atomic_bfloat16)
83+
EXT(SPV_INTEL_predicated_io)

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4103,5 +4103,22 @@ class SPIRVTernaryBitwiseFunctionINTELInst : public SPIRVInstTemplateBase {
41034103
_SPIRV_OP(BitwiseFunction, true, 7)
41044104
#undef _SPIRV_OP
41054105

4106+
class SPIRVPredicatedIOINTELInst : public SPIRVInstTemplateBase {
4107+
public:
4108+
std::optional<ExtensionID> getRequiredExtension() const override {
4109+
return ExtensionID::SPV_INTEL_predicated_io;
4110+
}
4111+
SPIRVCapVec getRequiredCapability() const override {
4112+
return getVec(internal::CapabilityPredicatedIOINTEL);
4113+
}
4114+
};
4115+
4116+
#define _SPIRV_OP(x, ...) \
4117+
typedef SPIRVInstTemplate<SPIRVPredicatedIOINTELInst, \
4118+
internal::Op##x##INTEL, __VA_ARGS__> \
4119+
SPIRV##x##INTEL;
4120+
_SPIRV_OP(PredicatedLoad, true, 6, true)
4121+
_SPIRV_OP(PredicatedStore, false, 4, true)
4122+
#undef _SPIRV_OP
41064123
} // namespace SPIRV
41074124
#endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
668668
add(CapabilityFunctionVariantsINTEL, "FunctionVariantsINTEL");
669669
add(CapabilitySpecConditionalINTEL, "SpecConditionalINTEL");
670670
add(internal::CapabilityBFloat16ArithmeticINTEL, "BFloat16ArithmeticINTEL");
671+
add(internal::CapabilityPredicatedIOINTEL, "PredicatedIOINTEL");
671672
}
672673
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
673674

lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ _SPIRV_OP_INTERNAL(ConvertHandleToSamplerINTEL,
3434
internal::ConvertHandleToSamplerINTEL)
3535
_SPIRV_OP_INTERNAL(ConvertHandleToSampledImageINTEL,
3636
internal::ConvertHandleToSampledImageINTEL)
37+
_SPIRV_OP_INTERNAL(PredicatedLoadINTEL,
38+
internal::OpPredicatedLoadINTEL)
39+
_SPIRV_OP_INTERNAL(PredicatedStoreINTEL,
40+
internal::OpPredicatedStoreINTEL)

lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ enum InternalOp {
7171
IOpCooperativeMatrixLoadCheckedINTEL = 6193,
7272
IOpCooperativeMatrixStoreCheckedINTEL = 6194,
7373
IOpCooperativeMatrixConstructCheckedINTEL = 6195,
74+
<<<<<<< HEAD
75+
=======
76+
IOpCooperativeMatrixLoadOffsetINTEL = 6239,
77+
IOpCooperativeMatrixStoreOffsetINTEL = 6240,
78+
IOpPredicatedLoadINTEL = 6258,
79+
IOpPredicatedStoreINTEL = 6259,
80+
>>>>>>> b12cb1c7 (Implement SPV_INTEL_predicated_io extension (#3370))
7481
IOpJointMatrixWorkItemLengthINTEL = 6410,
7582
IOpComplexFMulINTEL = 6415,
7683
IOpComplexFDivINTEL = 6416,
@@ -105,6 +112,7 @@ enum InternalCapability {
105112
ICapabilityBFloat16ArithmeticINTEL = 6226,
106113
ICapabilityAtomicBFloat16AddINTEL = 6255,
107114
ICapabilityAtomicBFloat16MinMaxINTEL = 6256,
115+
ICapabilityPredicatedIOINTEL = 6257,
108116
ICapabilityCooperativeMatrixPrefetchINTEL = 6411,
109117
ICapabilityComplexFloatMulDivINTEL = 6414,
110118
ICapabilityTensorFloat32RoundingINTEL = 6425,
@@ -175,6 +183,11 @@ _SPIRV_OP(Op, ConvertHandleToSampledImageINTEL)
175183

176184
_SPIRV_OP(Capability, AtomicBFloat16AddINTEL)
177185
_SPIRV_OP(Capability, AtomicBFloat16MinMaxINTEL)
186+
187+
_SPIRV_OP(Capability, PredicatedIOINTEL)
188+
_SPIRV_OP(Op, PredicatedLoadINTEL)
189+
_SPIRV_OP(Op, PredicatedStoreINTEL)
190+
178191
#undef _SPIRV_OP
179192

180193
constexpr SourceLanguage SourceLanguagePython =
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; Generated with:
2+
; source.cl:
3+
; int __spirv_PredicatedLoadINTEL(const __global int* pointer, bool predicate, int default_value);
4+
; int __spirv_PredicatedLoadINTEL(const __global int* pointer, bool predicate, int default_value, int memory_operands);
5+
; void __spirv_PredicatedStoreINTEL(const __global int* pointer, int object, bool predicate);
6+
; void __spirv_PredicatedStoreINTEL(const __global int* pointer, int object, bool predicate, int memory_operands);
7+
;
8+
; void foo(const __global int* load_pointer, __global int* store_pointer, int default_value, int store_object, bool predicate) {
9+
; const int memory_ops = 0;
10+
; int result1 = __spirv_PredicatedLoadINTEL(load_pointer, predicate, default_value);
11+
; int result2 = __spirv_PredicatedLoadINTEL(load_pointer, predicate, default_value, memory_ops);
12+
; __spirv_PredicatedStoreINTEL(store_pointer, store_object, predicate);
13+
; __spirv_PredicatedStoreINTEL(store_pointer, store_object, predicate, memory_ops);
14+
; }
15+
; clang -cc1 -cl-std=clc++2021 -triple spir64-unknown-unknown -emit-llvm -finclude-default-header source.cl -o tmp.ll
16+
17+
; RUN: llvm-as %s -o %t.bc
18+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_predicated_io
19+
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
20+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
21+
22+
; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=SPV-IR
23+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
24+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
25+
26+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
27+
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
28+
; CHECK-ERROR-NEXT: SPV_INTEL_predicated_io
29+
30+
; CHECK-SPIRV: Capability PredicatedIOINTEL
31+
; CHECK-SPIRV: Extension "SPV_INTEL_predicated_io"
32+
; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0
33+
; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#Const0:]] 0
34+
; CHECK-SPIRV-DAG: TypeVoid [[#VoidTy:]]
35+
; CHECK-SPIRV-DAG: TypePointer [[#IntPtrTy:]] 5 [[#Int32Ty]]
36+
; CHECK-SPIRV-DAG: TypeBool [[#BoolTy:]]
37+
; CHECK-SPIRV: FunctionParameter [[#IntPtrTy]] [[#LoadPtr:]]
38+
; CHECK-SPIRV: FunctionParameter [[#IntPtrTy]] [[#StorePtr:]]
39+
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#DefaultVal:]]
40+
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#StoreObj:]]
41+
; CHECK-SPIRV: FunctionParameter [[#BoolTy]] [[#Predicate:]]
42+
; CHECK-SPIRV: PredicatedLoadINTEL [[#Int32Ty]] [[#Result1:]] [[#LoadPtr]] [[#Predicate]] [[#DefaultVal]]
43+
; CHECK-SPIRV: PredicatedLoadINTEL [[#Int32Ty]] [[#Result2:]] [[#LoadPtr]] [[#Predicate]] [[#DefaultVal]] [[#Const0]]
44+
; CHECK-SPIRV: PredicatedStoreINTEL [[#StorePtr]] [[#StoreObj]] [[#Predicate]]
45+
; CHECK-SPIRV: PredicatedStoreINTEL [[#StorePtr]] [[#StoreObj]] [[#Predicate]] [[#Const0]]
46+
47+
; CHECK-LLVM: call spir_func i32 @_Z27__spirv_PredicatedLoadINTELPU3AS1ibi(ptr addrspace(1) %{{.*}}, i1 %{{.*}}, i32 %{{.*}})
48+
; CHECK-LLVM: call spir_func i32 @_Z27__spirv_PredicatedLoadINTELPU3AS1ibii(ptr addrspace(1) %{{.*}}, i1 %{{.*}}, i32 %{{.*}}, i32 0)
49+
; CHECK-LLVM: call spir_func void @_Z28__spirv_PredicatedStoreINTELPU3AS1iib(ptr addrspace(1) %{{.*}}, i32 %{{.*}}, i1 %{{.*}})
50+
; CHECK-LLVM: call spir_func void @_Z28__spirv_PredicatedStoreINTELPU3AS1iibi(ptr addrspace(1) %{{.*}}, i32 %{{.*}}, i1 %{{.*}}, i32 0)
51+
52+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
53+
target triple = "spir64-unknown-unknown"
54+
55+
define spir_func void @foo(ptr addrspace(1) %load_pointer, ptr addrspace(1) %store_pointer, i32 %default_value, i32 %store_object, i1 zeroext %predicate) {
56+
entry:
57+
%1 = call spir_func i32 @_Z27__spirv_PredicatedLoadINTELPU3AS1Kibi(ptr addrspace(1) %load_pointer, i1 %predicate, i32 %default_value)
58+
%2 = call spir_func i32 @_Z27__spirv_PredicatedLoadINTELPU3AS1Kibii(ptr addrspace(1) %load_pointer, i1 %predicate, i32 %default_value, i32 0)
59+
call spir_func void @_Z28__spirv_PredicatedStoreINTELPU3AS1Kiib(ptr addrspace(1) %store_pointer, i32 %store_object, i1 %predicate)
60+
call spir_func void @_Z28__spirv_PredicatedStoreINTELPU3AS1Kiibi(ptr addrspace(1) %store_pointer, i32 %store_object, i1 %predicate, i32 0)
61+
ret void
62+
}
63+
64+
declare spir_func i32 @_Z27__spirv_PredicatedLoadINTELPU3AS1Kibi(ptr addrspace(1), i1, i32)
65+
declare spir_func i32 @_Z27__spirv_PredicatedLoadINTELPU3AS1Kibii(ptr addrspace(1), i1, i32, i32)
66+
declare spir_func void @_Z28__spirv_PredicatedStoreINTELPU3AS1Kiib(ptr addrspace(1), i32, i1)
67+
declare spir_func void @_Z28__spirv_PredicatedStoreINTELPU3AS1Kiibi(ptr addrspace(1), i32, i1, i32)
68+
69+
!opencl.spir.version = !{!0}
70+
!spirv.Source = !{!1}
71+
!llvm.ident = !{!2}
72+
73+
!0 = !{i32 1, i32 2}
74+
!1 = !{i32 4, i32 100000}
75+
!2 = !{!"clang version 17.0.0"}

0 commit comments

Comments
 (0)