Skip to content

Commit 387841b

Browse files
authored
Support for SPV_INTEL_cache_controls (#2140)
Specification: KhronosGroup/SPIRV-Registry#216
1 parent 5b78b0d commit 387841b

File tree

12 files changed

+267
-14
lines changed

12 files changed

+267
-14
lines changed

docs/SPIRVRepresentationInLLVM.rst

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,14 @@ For example:
411411
are translated for image types, but they should be encoded in LLVM IR type name
412412
rather than function metadata.
413413

414-
Function parameter and global variable decoration through metadata
414+
Function parameter, instruction and global variable decoration through metadata
415415
------------------------------------------------------------------
416416

417-
Both function parameters and global variables can be decorated using LLVM
417+
Function parameters, instructions and global variables can be decorated using LLVM
418418
metadata through the metadata names ``spirv.ParameterDecorations`` and
419419
``spirv.Decorations`` respectively. ``spirv.ParameterDecorations`` must be tied
420420
to the kernel function while ``spirv.Decorations`` is tied directly to the
421-
global variable.
421+
instruction or global variable.
422422

423423
A "decoration-node" is a metadata node consisting of one or more operands. The
424424
first operand is an integer literal representing the SPIR-V decoration
@@ -434,7 +434,7 @@ decoration-nodes.
434434
references to decoration-lists, where N is the number of arguments of the
435435
function the metadata is tied to.
436436

437-
``spirv.Decorations`` example:
437+
``spirv.Decorations`` applied on a global variable example:
438438

439439
.. code-block:: llvm
440440
@@ -447,6 +447,18 @@ function the metadata is tied to.
447447
decorates a global variable ``v`` with ``Constant`` and ``LinkageAttributes``
448448
with extra operands ``"v"`` and ``Export`` in SPIR-V.
449449

450+
``spirv.Decorations`` applied on an instruction example:
451+
452+
.. code-block:: llvm
453+
454+
%idx = getelementptr inbounds i32, ptr addrspace(1) %b, i64 1, !spirv.Decorations !1
455+
...
456+
!1 = !{!2}
457+
!2 = !{i32 6442, i32 1, i32 2} ; {CacheControlLoadINTEL, CacheLevel=1, Cached}
458+
459+
decorates getelementptr instruction with CacheControlLoadINTEL decoration with
460+
extra operands ``i32 1`` and ``i32 2``.
461+
450462
``spirv.ParameterDecorations`` example:
451463

452464
.. code-block:: llvm

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,4 @@ EXT(SPV_INTEL_tensor_float32_rounding)
6363
EXT(SPV_EXT_relaxed_printf_string_address_space)
6464
EXT(SPV_INTEL_fpga_argument_interfaces)
6565
EXT(SPV_INTEL_fpga_latency_control)
66+
EXT(SPV_INTEL_cache_controls)

lib/SPIRV/SPIRVReader.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3875,17 +3875,22 @@ transDecorationsToMetadataList(llvm::LLVMContext *Context,
38753875
return MDNode::get(*Context, MDs);
38763876
}
38773877

3878-
void SPIRVToLLVM::transVarDecorationsToMetadata(SPIRVValue *BV, Value *V) {
3879-
if (!BV->isVariable())
3878+
void SPIRVToLLVM::transDecorationsToMetadata(SPIRVValue *BV, Value *V) {
3879+
if (!BV->isVariable() && !BV->isInst())
38803880
return;
38813881

3882-
if (auto *GV = dyn_cast<GlobalVariable>(V)) {
3882+
auto SetDecorationsMetadata = [&](auto V) {
38833883
std::vector<SPIRVDecorate const *> Decorates = BV->getDecorations();
38843884
if (!Decorates.empty()) {
38853885
MDNode *MDList = transDecorationsToMetadataList(Context, Decorates);
3886-
GV->setMetadata(SPIRV_MD_DECORATIONS, MDList);
3886+
V->setMetadata(SPIRV_MD_DECORATIONS, MDList);
38873887
}
3888-
}
3888+
};
3889+
3890+
if (auto *GV = dyn_cast<GlobalVariable>(V))
3891+
SetDecorationsMetadata(GV);
3892+
else if (auto *I = dyn_cast<Instruction>(V))
3893+
SetDecorationsMetadata(I);
38893894
}
38903895

38913896
bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
@@ -3897,7 +3902,7 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
38973902

38983903
// Decoration metadata is only enabled in SPIR-V friendly mode
38993904
if (BM->getDesiredBIsRepresentation() == BIsRepresentation::SPIRVFriendlyIR)
3900-
transVarDecorationsToMetadata(BV, V);
3905+
transDecorationsToMetadata(BV, V);
39013906

39023907
DbgTran->transDbgInfo(BV, V);
39033908
return true;

lib/SPIRV/SPIRVReader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ class SPIRVToLLVM : private BuiltinCallHelper {
256256
SmallVectorImpl<Function *> &Funcs);
257257
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
258258
void transMemAliasingINTELDecorations(SPIRVValue *BV, Value *V);
259-
void transVarDecorationsToMetadata(SPIRVValue *BV, Value *V);
259+
void transDecorationsToMetadata(SPIRVValue *BV, Value *V);
260260
void transFunctionDecorationsToMetadata(SPIRVFunction *BF, Function *F);
261261
void
262262
transFunctionPointerCallArgumentAttributes(SPIRVValue *BV, CallInst *CI,

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2611,6 +2611,48 @@ static void transMetadataDecorations(Metadata *MD, SPIRVEntry *Target) {
26112611
new SPIRVDecorateImplementInCSRINTEL(Target, Value->getZExtValue()));
26122612
break;
26132613
}
2614+
case spv::internal::DecorationCacheControlLoadINTEL: {
2615+
ErrLog.checkError(
2616+
NumOperands == 3, SPIRVEC_InvalidLlvmModule,
2617+
"CacheControlLoadINTEL requires exactly 2 extra operands");
2618+
auto *CacheLevel =
2619+
mdconst::dyn_extract<ConstantInt>(DecoMD->getOperand(1));
2620+
auto *CacheControl =
2621+
mdconst::dyn_extract<ConstantInt>(DecoMD->getOperand(2));
2622+
ErrLog.checkError(CacheLevel, SPIRVEC_InvalidLlvmModule,
2623+
"CacheControlLoadINTEL cache level operand is required "
2624+
"to be an integer");
2625+
ErrLog.checkError(CacheControl, SPIRVEC_InvalidLlvmModule,
2626+
"CacheControlLoadINTEL cache control operand is "
2627+
"required to be an integer");
2628+
2629+
Target->addDecorate(new SPIRVDecorateCacheControlLoadINTEL(
2630+
Target, CacheLevel->getZExtValue(),
2631+
static_cast<internal::LoadCacheControlINTEL>(
2632+
CacheControl->getZExtValue())));
2633+
break;
2634+
}
2635+
case spv::internal::DecorationCacheControlStoreINTEL: {
2636+
ErrLog.checkError(
2637+
NumOperands == 3, SPIRVEC_InvalidLlvmModule,
2638+
"CacheControlStoreINTEL requires exactly 2 extra operands");
2639+
auto *CacheLevel =
2640+
mdconst::dyn_extract<ConstantInt>(DecoMD->getOperand(1));
2641+
auto *CacheControl =
2642+
mdconst::dyn_extract<ConstantInt>(DecoMD->getOperand(2));
2643+
ErrLog.checkError(CacheLevel, SPIRVEC_InvalidLlvmModule,
2644+
"CacheControlStoreINTEL cache level operand is "
2645+
"required to be an integer");
2646+
ErrLog.checkError(CacheControl, SPIRVEC_InvalidLlvmModule,
2647+
"CacheControlStoreINTEL cache control operand is "
2648+
"required to be an integer");
2649+
2650+
Target->addDecorate(new SPIRVDecorateCacheControlStoreINTEL(
2651+
Target, CacheLevel->getZExtValue(),
2652+
static_cast<internal::StoreCacheControlINTEL>(
2653+
CacheControl->getZExtValue())));
2654+
break;
2655+
}
26142656
default: {
26152657
if (NumOperands == 1) {
26162658
Target->addDecorate(new SPIRVDecorate(DecoKind, Target));
@@ -2698,9 +2740,12 @@ bool LLVMToSPIRVBase::transDecoration(Value *V, SPIRVValue *BV) {
26982740
BV->setFPFastMathMode(M);
26992741
}
27002742
}
2701-
if (Instruction *Inst = dyn_cast<Instruction>(V))
2743+
if (Instruction *Inst = dyn_cast<Instruction>(V)) {
27022744
if (shouldTryToAddMemAliasingDecoration(Inst))
27032745
transMemAliasingINTELDecorations(Inst, BV);
2746+
if (auto *IDecoMD = Inst->getMetadata(SPIRV_MD_DECORATIONS))
2747+
transMetadataDecorations(IDecoMD, BV);
2748+
}
27042749

27052750
if (auto *CI = dyn_cast<CallInst>(V)) {
27062751
auto OC = BV->getOpCode();

lib/SPIRV/libSPIRV/SPIRVDecorate.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ class SPIRVDecorate : public SPIRVDecorateGeneric {
201201
case DecorationLatencyControlLabelINTEL:
202202
case DecorationLatencyControlConstraintINTEL:
203203
return ExtensionID::SPV_INTEL_fpga_latency_control;
204+
case internal::DecorationCacheControlLoadINTEL:
205+
case internal::DecorationCacheControlStoreINTEL:
206+
return ExtensionID::SPV_INTEL_cache_controls;
204207
default:
205208
return {};
206209
}
@@ -785,6 +788,37 @@ class SPIRVDecorateImplementInCSRINTEL : public SPIRVDecorate {
785788
Value) {}
786789
};
787790

791+
class SPIRVDecorateCacheControlLoadINTEL : public SPIRVDecorate {
792+
public:
793+
// Complete constructor for SPIRVDecorateCacheControlLoadINTEL
794+
SPIRVDecorateCacheControlLoadINTEL(
795+
SPIRVEntry *TheTarget, SPIRVWord CacheLevel,
796+
spv::internal::LoadCacheControlINTEL CacheControl)
797+
: SPIRVDecorate(spv::internal::DecorationCacheControlLoadINTEL, TheTarget,
798+
CacheLevel, static_cast<SPIRVWord>(CacheControl)){};
799+
800+
SPIRVWord getCacheLevel() const { return Literals.at(0); };
801+
spv::internal::LoadCacheControlINTEL getCacheControl() const {
802+
return static_cast<spv::internal::LoadCacheControlINTEL>(Literals.at(1));
803+
};
804+
};
805+
806+
class SPIRVDecorateCacheControlStoreINTEL : public SPIRVDecorate {
807+
public:
808+
// Complete constructor for SPIRVDecorateCacheControlStoreINTEL
809+
SPIRVDecorateCacheControlStoreINTEL(
810+
SPIRVEntry *TheTarget, SPIRVWord CacheLevel,
811+
spv::internal::StoreCacheControlINTEL CacheControl)
812+
: SPIRVDecorate(spv::internal::DecorationCacheControlStoreINTEL,
813+
TheTarget, CacheLevel,
814+
static_cast<SPIRVWord>(CacheControl)){};
815+
816+
SPIRVWord getCacheLevel() const { return Literals.at(0); };
817+
spv::internal::StoreCacheControlINTEL getCacheControl() const {
818+
return static_cast<spv::internal::StoreCacheControlINTEL>(Literals.at(1));
819+
};
820+
};
821+
788822
} // namespace SPIRV
789823

790824
#endif // SPIRV_LIBSPIRV_SPIRVDECORATE_H

lib/SPIRV/libSPIRV/SPIRVEnum.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,10 @@ template <> inline void SPIRVMap<Decoration, SPIRVCapVec>::init() {
471471
{internal::CapabilityGlobalVariableDecorationsINTEL});
472472
ADD_VEC_INIT(internal::DecorationArgumentAttributeINTEL,
473473
{CapabilityFunctionPointersINTEL});
474+
ADD_VEC_INIT(internal::DecorationCacheControlLoadINTEL,
475+
{internal::CapabilityCacheControlsINTEL});
476+
ADD_VEC_INIT(internal::DecorationCacheControlStoreINTEL,
477+
{internal::CapabilityCacheControlsINTEL});
474478
ADD_VEC_INIT(DecorationConduitKernelArgumentINTEL,
475479
{CapabilityFPGAArgumentInterfacesINTEL});
476480
ADD_VEC_INIT(DecorationRegisterMapKernelArgumentINTEL,

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ template <> inline void SPIRVMap<Decoration, std::string>::init() {
206206
add(internal::DecorationInitModeINTEL, "InitModeINTEL");
207207
add(internal::DecorationImplementInCSRINTEL, "ImplementInCSRINTEL");
208208
add(internal::DecorationArgumentAttributeINTEL, "ArgumentAttributeINTEL");
209+
add(internal::DecorationCacheControlLoadINTEL, "CacheControlLoadINTEL");
210+
add(internal::DecorationCacheControlStoreINTEL, "CacheControlStoreINTEL");
209211

210212
add(DecorationMax, "Max");
211213
}
@@ -645,6 +647,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
645647
"JointMatrixPackedInt2ComponentTypeINTEL");
646648
add(internal::CapabilityJointMatrixPackedInt4ComponentTypeINTEL,
647649
"JointMatrixPackedInt4ComponentTypeINTEL");
650+
add(internal::CapabilityCacheControlsINTEL, "CacheControlsINTEL");
648651
}
649652
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
650653

lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ enum InternalDecoration {
8787
IDecHostAccessINTEL = 6147,
8888
IDecInitModeINTEL = 6148,
8989
IDecImplementInCSRINTEL = 6149,
90-
IDecArgumentAttributeINTEL = 6409
90+
IDecArgumentAttributeINTEL = 6409,
91+
IDecCacheControlLoadINTEL = 6442,
92+
IDecCacheControlStoreINTEL = 6443
9193
};
9294

9395
enum InternalCapability {
@@ -106,7 +108,8 @@ enum InternalCapability {
106108
ICapabilityJointMatrixTF32ComponentTypeINTEL = 6436,
107109
ICapabilityJointMatrixBF16ComponentTypeINTEL = 6437,
108110
ICapabilityJointMatrixPackedInt2ComponentTypeINTEL = 6438,
109-
ICapabilityJointMatrixPackedInt4ComponentTypeINTEL = 6439
111+
ICapabilityJointMatrixPackedInt4ComponentTypeINTEL = 6439,
112+
ICapabilityCacheControlsINTEL = 6441
110113
};
111114

112115
enum InternalFunctionControlMask { IFunctionControlOptNoneINTELMask = 0x10000 };
@@ -140,6 +143,21 @@ enum InternalBuiltIn {
140143
IBuiltInGlobalHWThreadIDINTEL = 6136,
141144
};
142145

146+
enum class LoadCacheControlINTEL {
147+
Uncached = 0,
148+
Cached = 1,
149+
Streaming = 2,
150+
InvalidateAfterRead = 3,
151+
ConstCached = 4
152+
};
153+
154+
enum class StoreCacheControlINTEL {
155+
Uncached = 0,
156+
WriteThrough = 1,
157+
WriteBack = 2,
158+
Streaming = 3
159+
};
160+
143161
#define _SPIRV_OP(x, y) constexpr x x##y = static_cast<x>(I##x##y);
144162
_SPIRV_OP(Capability, JointMatrixINTEL)
145163
_SPIRV_OP(Capability, JointMatrixWIInstructionsINTEL)
@@ -172,6 +190,8 @@ _SPIRV_OP(Op, MaskedScatterINTEL)
172190

173191
_SPIRV_OP(Capability, TensorFloat32RoundingINTEL)
174192
_SPIRV_OP(Op, RoundFToTF32INTEL)
193+
194+
_SPIRV_OP(Capability, CacheControlsINTEL)
175195
#undef _SPIRV_OP
176196

177197
constexpr SourceLanguage SourceLanguagePython =
@@ -233,6 +253,10 @@ constexpr Decoration DecorationImplementInCSRINTEL =
233253
static_cast<Decoration>(IDecImplementInCSRINTEL);
234254
constexpr Decoration DecorationArgumentAttributeINTEL =
235255
static_cast<Decoration>(IDecArgumentAttributeINTEL);
256+
constexpr Decoration DecorationCacheControlLoadINTEL =
257+
static_cast<Decoration>(IDecCacheControlLoadINTEL);
258+
constexpr Decoration DecorationCacheControlStoreINTEL =
259+
static_cast<Decoration>(IDecCacheControlStoreINTEL);
236260

237261
constexpr Capability CapabilityFastCompositeINTEL =
238262
static_cast<Capability>(ICapFastCompositeINTEL);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV
3+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls %t.bc -o %t.spv
4+
; RUN: llvm-spirv -r %t.spv --spirv-target-env=SPV-IR -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
5+
6+
; CHECK-SPIRV-DAG: Load {{[0-9]+}} {{[0-9]+}} [[LoadPtr:[0-9]+]]
7+
; CHECK-SPIRV-DAG: Store [[StorePtr:[0-9]+]]
8+
9+
; CHECK-SPIRV-DAG: Decorate [[LoadPtr]] CacheControlLoadINTEL 0 1
10+
; CHECK-SPIRV-DAG: Decorate [[LoadPtr]] CacheControlLoadINTEL 1 1
11+
; CHECK-SPIRV-DAG: Decorate [[StorePtr]] CacheControlStoreINTEL 0 1
12+
; CHECK-SPIRV-DAG: Decorate [[StorePtr]] CacheControlStoreINTEL 1 2
13+
14+
; CHECK-LLVM: %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %buffer, i64 1, !spirv.Decorations [[LoadMD:![0-9]+]]
15+
; CHECK-LLVM: load i32, ptr addrspace(1) %arrayidx, align 4
16+
17+
; CHECK-LLVM: %arrayidx1 = getelementptr inbounds i32, ptr addrspace(1) %buffer, i64 0, !spirv.Decorations [[StoreMD:![0-9]+]]
18+
; CHECK-LLVM: store i32 %0, ptr addrspace(1) %arrayidx1, align 4
19+
20+
; CHECK-LLVM: [[LoadMD]] = !{[[CC0:![0-9]+]], [[CC1:![0-9]+]]}
21+
; CHECK-LLVM: [[CC0]] = !{i32 6442, i32 0, i32 1}
22+
; CHECK-LLVM: [[CC1]] = !{i32 6442, i32 1, i32 1}
23+
24+
; CHECK-LLVM: [[StoreMD]] = !{[[CC2:![0-9]+]], [[CC3:![0-9]+]]}
25+
; CHECK-LLVM: [[CC2]] = !{i32 6443, i32 0, i32 1}
26+
; CHECK-LLVM: [[CC3]] = !{i32 6443, i32 1, i32 2}
27+
28+
target triple = "spir64-unknown-unknown"
29+
30+
define spir_kernel void @test(ptr addrspace(1) %buffer) {
31+
entry:
32+
%arrayidx = getelementptr inbounds i32, ptr addrspace(1) %buffer, i64 1, !spirv.Decorations !3
33+
%0 = load i32, ptr addrspace(1) %arrayidx, align 4
34+
%arrayidx1 = getelementptr inbounds i32, ptr addrspace(1) %buffer, i64 0, !spirv.Decorations !6
35+
store i32 %0, ptr addrspace(1) %arrayidx1, align 4
36+
ret void
37+
}
38+
39+
!spirv.MemoryModel = !{!0}
40+
!spirv.Source = !{!1}
41+
!opencl.spir.version = !{!2}
42+
!opencl.ocl.version = !{!2}
43+
44+
!0 = !{i32 2, i32 2}
45+
!1 = !{i32 3, i32 102000}
46+
!2 = !{i32 1, i32 2}
47+
!3 = !{!4, !5}
48+
!4 = !{i32 6442, i32 0, i32 1} ; {CacheControlLoadINTEL, CacheLevel=0, Cached}
49+
!5 = !{i32 6442, i32 1, i32 1} ; {CacheControlLoadINTEL, CacheLevel=1, Cached}
50+
!6 = !{!7, !8}
51+
!7 = !{i32 6443, i32 0, i32 1} ; {CacheControlStoreINTEL, CacheLevel=0, WriteThrough}
52+
!8 = !{i32 6443, i32 1, i32 2} ; {CacheControlStoreINTEL, CacheLevel=1, WriteBack}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV
3+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls %t.bc -o %t.spv
4+
; RUN: llvm-spirv -r %t.spv --spirv-target-env=SPV-IR -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
5+
6+
; CHECK-SPIRV-DAG: Store [[StorePtr:[0-9]+]]
7+
8+
; CHECK-SPIRV-DAG: Decorate [[StorePtr]] CacheControlStoreINTEL 0 1
9+
; CHECK-SPIRV-DAG: Decorate [[StorePtr]] CacheControlStoreINTEL 1 3
10+
11+
; CHECK-LLVM: @p = common addrspace(1) global i32 0, align 4, !spirv.Decorations [[GlobalMD:![0-9]+]]
12+
; CHECK-LLVM: store i32 0, ptr addrspace(1) @p, align 4
13+
14+
; CHECK-LLVM-DAG: [[CC0:![0-9]+]] = !{i32 6443, i32 0, i32 1}
15+
; CHECK-LLVM-DAG: [[CC1:![0-9]+]] = !{i32 6443, i32 1, i32 3}
16+
; CHECK-LLVM-DAG: [[GlobalMD]] = {{.*}}[[CC0]]{{.*}}[[CC1]]
17+
18+
target triple = "spir64-unknown-unknown"
19+
20+
@p = common addrspace(1) global i32 0, align 4, !spirv.Decorations !3
21+
22+
define spir_kernel void @test() {
23+
entry:
24+
store i32 0, i32 addrspace(1)* @p, align 4
25+
ret void
26+
}
27+
28+
!spirv.MemoryModel = !{!0}
29+
!spirv.Source = !{!1}
30+
!opencl.spir.version = !{!2}
31+
!opencl.ocl.version = !{!2}
32+
33+
!0 = !{i32 2, i32 2}
34+
!1 = !{i32 3, i32 102000}
35+
!2 = !{i32 1, i32 2}
36+
!3 = !{!4, !5}
37+
!4 = !{i32 6443, i32 0, i32 1} ; {CacheControlStoreINTEL, CacheLevel=0, WriteThrough}
38+
!5 = !{i32 6443, i32 1, i32 3} ; {CacheControlStoreINTEL, CacheLevel=1, Streaming}

0 commit comments

Comments
 (0)