|
| 1 | +/*========================== begin_copyright_notice ============================ |
| 2 | + |
| 3 | +Copyright (C) 2026 Intel Corporation |
| 4 | + |
| 5 | +SPDX-License-Identifier: MIT |
| 6 | + |
| 7 | +============================= end_copyright_notice ===========================*/ |
| 8 | + |
| 9 | +// Predicate-flattening regression test for IGCCSPIRVSupportTblGen. |
| 10 | +// Each extension exercises one or more PlatformSupport TD shapes; the CHECK |
| 11 | +// lines pin the exact Pred:: template emitted into the .inc. |
| 12 | +// |
| 13 | +// CHECK-DAG is used because the generator emits extensions in TableGen's |
| 14 | +// internal record order, not source order. Each pattern is unique enough |
| 15 | +// that DAG matching is unambiguous. |
| 16 | +// |
| 17 | +// RUN: igcc-spirv-support-tblgen -gen-igcc-spirv-extension-support-header \ |
| 18 | +// RUN: -I %spirv_extensions_inc %s | FileCheck %s |
| 19 | + |
| 20 | +include "SPIRVExtensions_Common.td" |
| 21 | + |
| 22 | +// Fake platform/core symbols. Their string names flow straight through the |
| 23 | +// generator into the emitted Pred:: template arguments — they don't need to |
| 24 | +// be real PRODUCT_FAMILY / GFXCORE_FAMILY enumerators because the generator |
| 25 | +// never resolves them and FileCheck only inspects the textual output. |
| 26 | +def CORE_A : CoreFamily<"CORE_A">; |
| 27 | +def CORE_B : CoreFamily<"CORE_B">; |
| 28 | +def PLAT_X : Platform<"PLAT_X">; |
| 29 | +def PLAT_Y : Platform<"PLAT_Y">; |
| 30 | +def PLAT_Z : Platform<"PLAT_Z">; |
| 31 | + |
| 32 | +def XYGroup : PlatformGroup<[PLAT_X, PLAT_Y]>; |
| 33 | + |
| 34 | +// --- AllPlatformSupport singleton --------------------------------------- |
| 35 | +def Ext_All : Extension<"Ext_All", |
| 36 | + [ Capability<"Cap_All"> ], |
| 37 | + "https://example.com/Ext_All", |
| 38 | + AllPlatformSupport>; |
| 39 | +// CHECK-DAG: {"Ext_All", "https://example.com/Ext_All", Pred::AllPlatformSupport, nullptr, |
| 40 | +// CHECK-DAG: {"Cap_All", Pred::AllPlatformSupport, nullptr, |
| 41 | + |
| 42 | +// --- isCoreChildOf ------------------------------------------------------ |
| 43 | +def Ext_CoreChild : Extension<"Ext_CoreChild", |
| 44 | + [ Capability<"Cap_CoreChild"> ], |
| 45 | + "https://example.com/Ext_CoreChild", |
| 46 | + isCoreChildOf<CORE_A>>; |
| 47 | +// CHECK-DAG: {"Ext_CoreChild", "https://example.com/Ext_CoreChild", Pred::isCoreChildOf<CORE_A>, nullptr, |
| 48 | +// CHECK-DAG: {"Cap_CoreChild", Pred::isCoreChildOf<CORE_A>, nullptr, |
| 49 | + |
| 50 | +// --- ExactCoreFamily ---------------------------------------------------- |
| 51 | +def Ext_ExactCore : Extension<"Ext_ExactCore", |
| 52 | + [ Capability<"Cap_ExactCore"> ], |
| 53 | + "https://example.com/Ext_ExactCore", |
| 54 | + ExactCoreFamily<CORE_B>>; |
| 55 | +// CHECK-DAG: {"Ext_ExactCore", "https://example.com/Ext_ExactCore", Pred::ExactCoreFamily<CORE_B>, nullptr, |
| 56 | +// CHECK-DAG: {"Cap_ExactCore", Pred::ExactCoreFamily<CORE_B>, nullptr, |
| 57 | + |
| 58 | +// --- isProductChildOf --------------------------------------------------- |
| 59 | +def Ext_ProductChild : Extension<"Ext_ProductChild", |
| 60 | + [ Capability<"Cap_ProductChild"> ], |
| 61 | + "https://example.com/Ext_ProductChild", |
| 62 | + isProductChildOf<PLAT_X>>; |
| 63 | +// CHECK-DAG: {"Ext_ProductChild", "https://example.com/Ext_ProductChild", Pred::isProductChildOf<PLAT_X>, nullptr, |
| 64 | +// CHECK-DAG: {"Cap_ProductChild", Pred::isProductChildOf<PLAT_X>, nullptr, |
| 65 | + |
| 66 | +// --- ExactPlatform ------------------------------------------------------ |
| 67 | +def Ext_ExactPlatform : Extension<"Ext_ExactPlatform", |
| 68 | + [ Capability<"Cap_ExactPlatform"> ], |
| 69 | + "https://example.com/Ext_ExactPlatform", |
| 70 | + ExactPlatform<PLAT_Y>>; |
| 71 | +// CHECK-DAG: {"Ext_ExactPlatform", "https://example.com/Ext_ExactPlatform", Pred::ExactPlatform<PLAT_Y>, nullptr, |
| 72 | +// CHECK-DAG: {"Cap_ExactPlatform", Pred::ExactPlatform<PLAT_Y>, nullptr, |
| 73 | + |
| 74 | +// --- isInGroup (variadic over group members) ---------------------------- |
| 75 | +def Ext_InGroup : Extension<"Ext_InGroup", |
| 76 | + [ Capability<"Cap_InGroup"> ], |
| 77 | + "https://example.com/Ext_InGroup", |
| 78 | + isInGroup<XYGroup>>; |
| 79 | +// CHECK-DAG: {"Ext_InGroup", "https://example.com/Ext_InGroup", Pred::isInGroup<PLAT_X, PLAT_Y>, nullptr, |
| 80 | +// CHECK-DAG: {"Cap_InGroup", Pred::isInGroup<PLAT_X, PLAT_Y>, nullptr, |
| 81 | + |
| 82 | +// --- AnyOf, AllOf, Not (composed) --------------------------------------- |
| 83 | +def Ext_Composed : Extension<"Ext_Composed", |
| 84 | + [ Capability<"Cap_Composed"> ], |
| 85 | + "https://example.com/Ext_Composed", |
| 86 | + AllOf<[ isCoreChildOf<CORE_A>, |
| 87 | + Not<ExactPlatform<PLAT_Z>>, |
| 88 | + AnyOf<[ ExactPlatform<PLAT_X>, ExactPlatform<PLAT_Y> ]> ]>>; |
| 89 | +// CHECK-DAG: {"Ext_Composed", "https://example.com/Ext_Composed", Pred::AllOf<Pred::isCoreChildOf<CORE_A>, Pred::Not<Pred::ExactPlatform<PLAT_Z>>, Pred::AnyOf<Pred::ExactPlatform<PLAT_X>, Pred::ExactPlatform<PLAT_Y>>>, nullptr, |
| 90 | +// CHECK-DAG: {"Cap_Composed", Pred::AllOf<Pred::isCoreChildOf<CORE_A>, Pred::Not<Pred::ExactPlatform<PLAT_Z>>, Pred::AnyOf<Pred::ExactPlatform<PLAT_X>, Pred::ExactPlatform<PLAT_Y>>>, nullptr, |
| 91 | + |
| 92 | +// --- NotSupported singleton --------------------------------------------- |
| 93 | +// NotSupported collapses to nullptr in BOTH the extension column and the |
| 94 | +// capability column (emitTierColumn special-cases it). The capability |
| 95 | +// inherits NotSupported from the extension via InheritFromExtension default. |
| 96 | +def Ext_None : Extension<"Ext_None", |
| 97 | + [ Capability<"Cap_None"> ], |
| 98 | + "https://example.com/Ext_None", |
| 99 | + NotSupported>; |
| 100 | +// CHECK-DAG: {"Ext_None", "https://example.com/Ext_None", nullptr, nullptr, |
| 101 | +// CHECK-DAG: {"Cap_None", nullptr, nullptr, |
| 102 | + |
| 103 | +// --- InheritFromCapabilities aggregation -------------------------------- |
| 104 | +// Extension column collapses to nullptr (signalling aggregate mode); |
| 105 | +// per-capability columns carry the real predicates. |
| 106 | +def Ext_Aggregate : Extension<"Ext_Aggregate", |
| 107 | + [ Capability<"Cap_Aggr_A", isCoreChildOf<CORE_A>>, |
| 108 | + Capability<"Cap_Aggr_B", ExactPlatform<PLAT_Z>> ], |
| 109 | + "https://example.com/Ext_Aggregate", |
| 110 | + InheritFromCapabilities>; |
| 111 | +// CHECK-DAG: {"Ext_Aggregate", "https://example.com/Ext_Aggregate", nullptr, nullptr, |
| 112 | +// CHECK-DAG: {"Cap_Aggr_A", Pred::isCoreChildOf<CORE_A>, nullptr, |
| 113 | +// CHECK-DAG: {"Cap_Aggr_B", Pred::ExactPlatform<PLAT_Z>, nullptr, |
| 114 | + |
| 115 | +// --- Experimental tier (separate column) -------------------------------- |
| 116 | +// Capability ID is "0" because the extension has no production support |
| 117 | +// (formatCapabilityId requires both Ext.ProductionSupport and |
| 118 | +// Cap.ProductionSupport to be non-null before reporting a real ID). |
| 119 | +def Ext_Exp_experimental : ExperimentalExtension<"Ext_Exp", |
| 120 | + [ Capability<"Cap_Exp"> ], |
| 121 | + "https://example.com/Ext_Exp", |
| 122 | + ExactPlatform<PLAT_X>>; |
| 123 | +// CHECK-DAG: {"Ext_Exp", "https://example.com/Ext_Exp", nullptr, Pred::ExactPlatform<PLAT_X>, |
| 124 | +// CHECK-DAG: {"Cap_Exp", nullptr, Pred::ExactPlatform<PLAT_X>, 0}, |
| 125 | + |
| 126 | +// --- Dual definition: production + experimental on the same name -------- |
| 127 | +def Ext_Dual : Extension<"Ext_Dual", |
| 128 | + [ Capability<"Cap_Dual"> ], |
| 129 | + "https://example.com/Ext_Dual", |
| 130 | + isCoreChildOf<CORE_A>>; |
| 131 | +def Ext_Dual_experimental : ExperimentalExtension<"Ext_Dual", |
| 132 | + [ Capability<"Cap_Dual"> ], |
| 133 | + "https://example.com/Ext_Dual", |
| 134 | + isCoreChildOf<CORE_B>>; |
| 135 | +// CHECK-DAG: {"Ext_Dual", "https://example.com/Ext_Dual", Pred::isCoreChildOf<CORE_A>, Pred::isCoreChildOf<CORE_B>, |
| 136 | +// CHECK-DAG: {"Cap_Dual", Pred::isCoreChildOf<CORE_A>, Pred::isCoreChildOf<CORE_B>, |
| 137 | + |
| 138 | +// --- Capability ID handling -------------------------------------------- |
| 139 | +// Default (Cap.Id == -1): the generator emits a static_cast over |
| 140 | +// spv::Capability<Name> from the vendored SPIRV-Headers, so the consumer |
| 141 | +// compiles iff <Name> exists in spv::. |
| 142 | +// CapabilityWithManualId<Name, Id>: the generator emits the literal ID |
| 143 | +// followed by 'u'. Use this for capabilities not yet in the headers. |
| 144 | +// Manual and default IDs can be mixed within one extension. |
| 145 | +def Ext_IdMix : Extension<"Ext_IdMix", |
| 146 | + [ Capability<"Cap_IdDefault">, |
| 147 | + CapabilityWithManualId<"Cap_IdManual", 4242> ], |
| 148 | + "https://example.com/Ext_IdMix", |
| 149 | + AllPlatformSupport>; |
| 150 | +// CHECK-DAG: {"Cap_IdDefault", Pred::AllPlatformSupport, nullptr, static_cast<uint32_t>(spv::CapabilityCap_IdDefault)}, |
| 151 | +// CHECK-DAG: {"Cap_IdManual", Pred::AllPlatformSupport, nullptr, 4242u}, |
| 152 | + |
| 153 | +// Manual ID on an experimental-only extension still collapses to "0", |
| 154 | +// because formatCapabilityId gates the ID on production support being |
| 155 | +// present at BOTH the extension and capability levels. |
| 156 | +def Ext_IdExp_experimental : ExperimentalExtension<"Ext_IdExp", |
| 157 | + [ CapabilityWithManualId<"Cap_IdExp", 7777> ], |
| 158 | + "https://example.com/Ext_IdExp", |
| 159 | + AllPlatformSupport>; |
| 160 | +// CHECK-DAG: {"Cap_IdExp", nullptr, Pred::AllPlatformSupport, 0}, |
0 commit comments