Skip to content

Commit 9486c5f

Browse files
committed
[Backport to 19] Use SPV_EXT_long_vector extension for non-standard vector size (#3777)
For a vector type, add `SPV_EXT_long_vector` extension and prioritize it over `SPV_INTEL_vector_compute` whenever the vector type doesn't have a standard component size (2, 3, 4, 8, or 16). [Backport to 19] Keep VectorAnyINTEL for VectorCompute modules with SPV_EXT_long_vector (#3829) #3777 added `SPV_EXT_long_vector` and gave it priority over `SPV_INTEL_vector_compute`: when both extensions are enabled and a vector has a non-standard component count, the translator now emits `CapabilityLongVectorEXT` instead of `CapabilityVectorAnyINTEL`. This regresses `VectorCompute` modules. The offloading flow (producing both `VectorCompute` and non-`VectorCompute` modules) applies a single, fixed extension list uniformly to every device image, so a `VectorCompute` module is translated with both `SPV_INTEL_vector_compute` and `SPV_EXT_long_vector` enabled. Before #3777 such a module emitted `VectorAnyINTEL` for its non-standard vectors; after #3777 it emits `LongVectorEXT`. `VectorCompute` consumers require `VectorAnyINTEL`, so this is a functional regression. Hence, the enabled extension list does not identify a module as `VectorCompute` - the `VectorCompute` metadata (`VCFunction` /`VCGlobalVariable`) does. `IsVectorComputeModule` records the presence of that metadata before type translation. `VectorCompute` modules keep using `VectorAnyINTEL`, restoring the pre-#3777 behavior; all other modules still prefer the multi-vendor `LongVectorEXT` when its extension is enabled.
1 parent 9071f0d commit 9486c5f

12 files changed

Lines changed: 181 additions & 4 deletions

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,4 @@ EXT(SPV_INTEL_sigmoid)
9595
EXT(SPV_INTEL_float4)
9696
EXT(SPV_INTEL_fp_conversions)
9797
EXT(SPV_INTEL_rounded_divide_sqrt)
98+
EXT(SPV_EXT_long_vector)

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ using namespace OCLUtil;
108108

109109
namespace {
110110

111+
// A module is VectorCompute when any function or global variable carries
112+
// VectorCompute metadata.
113+
bool hasVectorComputeMetadata(Module *M) {
114+
return any_of(*M,
115+
[](const Function &F) {
116+
return F.hasFnAttribute(kVCMetadata::VCFunction);
117+
}) ||
118+
any_of(M->globals(), [](const GlobalVariable &GV) {
119+
return GV.hasAttribute(kVCMetadata::VCGlobalVariable);
120+
});
121+
}
122+
111123
static SPIRVWord convertFloatToSPIRVWord(float F) {
112124
union {
113125
float F;
@@ -426,6 +438,20 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
426438
}
427439

428440
if (auto *VecTy = dyn_cast<FixedVectorType>(T)) {
441+
unsigned NumElements = VecTy->getNumElements();
442+
bool IsNonStandardCount =
443+
!(NumElements == 2 || NumElements == 3 || NumElements == 4 ||
444+
NumElements == 8 || NumElements == 16);
445+
if (IsNonStandardCount &&
446+
!BM->isAllowedToUseExtension(ExtensionID::SPV_EXT_long_vector) &&
447+
!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) {
448+
BM->getErrorLog().checkError(
449+
false, SPIRVEC_RequiresExtension,
450+
"SPV_EXT_long_vector or SPV_INTEL_vector_compute\n"
451+
"NOTE: LLVM module contains a vector with an unsupported number of "
452+
"components, translation of which requires one of these extensions");
453+
return nullptr;
454+
}
429455
if (VecTy->getElementType()->isPointerTy() ||
430456
isa<TypedPointerType>(VecTy->getElementType())) {
431457
// SPV_INTEL_masked_gather_scatter extension changes 2.16.1. Universal
@@ -6046,6 +6072,11 @@ bool LLVMToSPIRVBase::translate() {
60466072
if (isEmptyLLVMModule(M))
60476073
BM->addCapability(CapabilityLinkage);
60486074

6075+
// Check before type translation so that SPIRVTypeVector can choose the
6076+
// matching capability.
6077+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute))
6078+
BM->setVectorCompute(hasVectorComputeMetadata(M));
6079+
60496080
if (!lowerBuiltinCallsToVariables(M))
60506081
return false;
60516082

lib/SPIRV/libSPIRV/SPIRVEntry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,8 @@ class SPIRVCapability : public SPIRVEntryNoId<OpCapability> {
920920
return ExtensionID::SPV_INTEL_rounded_divide_sqrt;
921921
case internal::CapabilityDeviceBarrierINTEL:
922922
return ExtensionID::SPV_INTEL_device_barrier;
923+
case CapabilityLongVectorEXT:
924+
return ExtensionID::SPV_EXT_long_vector;
923925
default:
924926
return {};
925927
}

lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class SPIRVModule {
140140
const std::string &) = 0;
141141
void setInvalid() { IsValid = false; }
142142
bool isModuleValid() { return IsValid; }
143+
void setVectorCompute(bool E) { IsVectorCompute = E; }
144+
bool isVectorCompute() const { return IsVectorCompute; }
143145

144146
// Module query functions
145147
virtual SPIRVAddressingModelKind getAddressingModel() = 0;
@@ -659,6 +661,7 @@ class SPIRVModule {
659661

660662
private:
661663
bool IsValid;
664+
bool IsVectorCompute = false;
662665
};
663666

664667

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
629629
add(CapabilityLongCompositesINTEL, "LongCompositesINTEL");
630630
add(CapabilityOptNoneEXT, "OptNoneEXT");
631631
add(CapabilityAtomicFloat16AddEXT, "AtomicFloat16AddEXT");
632+
add(CapabilityLongVectorEXT, "LongVectorEXT");
632633
add(internal::CapabilityAtomicBFloat16AddINTEL, "AtomicBFloat16AddINTEL");
633634
add(internal::CapabilityAtomicBFloat16MinMaxINTEL,
634635
"AtomicBFloat16MinMaxINTEL");

lib/SPIRV/libSPIRV/SPIRVType.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,17 @@ class SPIRVTypeVector : public SPIRVType {
384384
if (CompCount == 8 || CompCount == 16)
385385
V.push_back(CapabilityVector16);
386386

387-
if (Module->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute))
388-
if (CompCount == 1 || (CompCount > 4 && CompCount < 8) ||
389-
(CompCount > 8 && CompCount < 16) || CompCount > 16)
387+
if (CompCount == 1 || (CompCount > 4 && CompCount < 8) ||
388+
(CompCount > 8 && CompCount < 16) || CompCount > 16) {
389+
// A VectorCompute module keeps using CapabilityVectorAnyINTEL;
390+
// otherwise use multi-vendor LongVectorEXT
391+
if (!Module->isVectorCompute() &&
392+
Module->isAllowedToUseExtension(ExtensionID::SPV_EXT_long_vector))
393+
V.push_back(CapabilityLongVectorEXT);
394+
else if (Module->isAllowedToUseExtension(
395+
ExtensionID::SPV_INTEL_vector_compute))
390396
V.push_back(CapabilityVectorAnyINTEL);
397+
}
391398
return V;
392399
}
393400

@@ -401,7 +408,8 @@ class SPIRVTypeVector : public SPIRVType {
401408
SPIRVEntry::validate();
402409
CompType->validate();
403410
#ifndef NDEBUG
404-
if (!(Module->isAllowedToUseExtension(
411+
if (!Module->isAllowedToUseExtension(ExtensionID::SPV_EXT_long_vector) &&
412+
!(Module->isAllowedToUseExtension(
405413
ExtensionID::SPV_INTEL_vector_compute))) {
406414
assert(CompCount == 2 || CompCount == 3 || CompCount == 4 ||
407415
CompCount == 8 || CompCount == 16);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_long_vector,+SPV_INTEL_vector_compute -o %t.spv
3+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --implicit-check-not="Capability VectorAnyINTEL"
4+
; TODO: re-enable spirv-val once it can recognize LongVectorEXT capability (5425).
5+
; RUNx: spirv-val %t.spv
6+
7+
; CHECK-DAG: Capability LongVectorEXT
8+
; CHECK-DAG: Extension "SPV_EXT_long_vector"
9+
10+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
11+
target triple = "spir64-unknown-unknown"
12+
13+
define spir_func void @test_vec1(<1 x float> %v) {
14+
entry:
15+
ret void
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_long_vector,+SPV_INTEL_vector_compute -o %t.spv
3+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --implicit-check-not="Capability VectorAnyINTEL"
4+
; TODO: re-enable spirv-val once it can recognize LongVectorEXT capability (5425).
5+
; RUNx: spirv-val %t.spv
6+
7+
; CHECK-DAG: Capability LongVectorEXT
8+
; CHECK-DAG: Extension "SPV_EXT_long_vector"
9+
10+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
11+
target triple = "spir64-unknown-unknown"
12+
13+
define spir_func void @test_vec5(<5 x float> %v) {
14+
entry:
15+
ret void
16+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_long_vector -o %t.spv
3+
; TODO: re-enable spirv-val once it can recognize LongVectorEXT capability (5425).
4+
; RUNx: spirv-val %t.spv
5+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s
6+
7+
; RUN: llvm-as %s -o %t.bc
8+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=ERROR
9+
10+
; CHECK-DAG: Capability LongVectorEXT
11+
; CHECK-DAG: Extension "SPV_EXT_long_vector"
12+
; CHECK-DAG: TypeFloat [[#F32:]] 32
13+
; CHECK-DAG: TypeVector [[#]] [[#F32]] 1
14+
15+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
16+
target triple = "spir64-unknown-unknown"
17+
18+
define spir_func void @test_vec1(<1 x float> %v1) {
19+
entry:
20+
ret void
21+
}
22+
23+
; ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
24+
; ERROR-NEXT: SPV_EXT_long_vector or SPV_INTEL_vector_compute
25+
26+
define spir_func void @test_no_ext(<1 x float> %v) {
27+
entry:
28+
ret void
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_long_vector -o %t.spv
3+
; TODO: re-enable spirv-val once it can recognize LongVectorEXT capability (5425).
4+
; RUNx: spirv-val %t.spv
5+
; RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s
6+
7+
; RUN: llvm-as %s -o %t.bc
8+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=ERROR
9+
10+
; CHECK-DAG: Capability LongVectorEXT
11+
; CHECK-DAG: Extension "SPV_EXT_long_vector"
12+
; CHECK-DAG: TypeFloat [[#F32:]] 32
13+
; CHECK-DAG: TypeVector [[#]] [[#F32]] 5
14+
15+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
16+
target triple = "spir64-unknown-unknown"
17+
18+
define spir_func void @test_vec5(<5 x float> %v) {
19+
entry:
20+
ret void
21+
}
22+
23+
; ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
24+
; ERROR-NEXT: SPV_EXT_long_vector or SPV_INTEL_vector_compute
25+
26+
define spir_func void @test_no_ext(<5 x float> %v) {
27+
entry:
28+
ret void
29+
}

0 commit comments

Comments
 (0)