Skip to content

Commit 89f5141

Browse files
committed
[Backport to 15] 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 15] 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 e271ca3 commit 89f5141

12 files changed

Lines changed: 177 additions & 4 deletions

File tree

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,4 @@ EXT(SPV_INTEL_sigmoid)
9292
EXT(SPV_INTEL_float4)
9393
EXT(SPV_INTEL_fp_conversions)
9494
EXT(SPV_INTEL_rounded_divide_sqrt)
95+
EXT(SPV_EXT_long_vector)

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,20 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
359359
}
360360

361361
if (auto *VecTy = dyn_cast<FixedVectorType>(T)) {
362+
unsigned NumElements = VecTy->getNumElements();
363+
bool IsNonStandardCount =
364+
!(NumElements == 2 || NumElements == 3 || NumElements == 4 ||
365+
NumElements == 8 || NumElements == 16);
366+
if (IsNonStandardCount &&
367+
!BM->isAllowedToUseExtension(ExtensionID::SPV_EXT_long_vector) &&
368+
!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) {
369+
BM->getErrorLog().checkError(
370+
false, SPIRVEC_RequiresExtension,
371+
"SPV_EXT_long_vector or SPV_INTEL_vector_compute\n"
372+
"NOTE: LLVM module contains a vector with an unsupported number of "
373+
"components, translation of which requires one of these extensions");
374+
return nullptr;
375+
}
362376
if (VecTy->getElementType()->isPointerTy()) {
363377
// SPV_INTEL_masked_gather_scatter extension changes 2.16.1. Universal
364378
// Validation Rules:
@@ -5091,12 +5105,29 @@ bool isEmptyLLVMModule(Module *M) {
50915105
M->global_empty(); // No global variables
50925106
}
50935107

5108+
// A module is VectorCompute when any function or global variable carries
5109+
// VectorCompute metadata.
5110+
static bool hasVectorComputeMetadata(Module *M) {
5111+
return any_of(*M,
5112+
[](const Function &F) {
5113+
return F.hasFnAttribute(kVCMetadata::VCFunction);
5114+
}) ||
5115+
any_of(M->globals(), [](const GlobalVariable &GV) {
5116+
return GV.hasAttribute(kVCMetadata::VCGlobalVariable);
5117+
});
5118+
}
5119+
50945120
bool LLVMToSPIRVBase::translate() {
50955121
BM->setGeneratorVer(KTranslatorVer);
50965122

50975123
if (isEmptyLLVMModule(M))
50985124
BM->addCapability(CapabilityLinkage);
50995125

5126+
// Check before type translation so that SPIRVTypeVector can choose the
5127+
// matching capability.
5128+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute))
5129+
BM->setVectorCompute(hasVectorComputeMetadata(M));
5130+
51005131
// Use the type scavenger to recover pointer element types.
51015132
Scavenger = std::make_unique<SPIRVTypeScavenger>(*M);
51025133

lib/SPIRV/libSPIRV/SPIRVEntry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,8 @@ class SPIRVCapability : public SPIRVEntryNoId<OpCapability> {
913913
return ExtensionID::SPV_INTEL_rounded_divide_sqrt;
914914
case internal::CapabilityDeviceBarrierINTEL:
915915
return ExtensionID::SPV_INTEL_device_barrier;
916+
case CapabilityLongVectorEXT:
917+
return ExtensionID::SPV_EXT_long_vector;
916918
default:
917919
return {};
918920
}

lib/SPIRV/libSPIRV/SPIRVModule.h

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

143145
// Module query functions
144146
virtual SPIRVAddressingModelKind getAddressingModel() = 0;
@@ -648,6 +650,7 @@ class SPIRVModule {
648650

649651
private:
650652
bool IsValid;
653+
bool IsVectorCompute = false;
651654
};
652655

653656
#ifdef _SPIRV_SUPPORT_TEXT_FMT

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
608608
add(CapabilityLongCompositesINTEL, "LongCompositesINTEL");
609609
add(CapabilityOptNoneEXT, "OptNoneEXT");
610610
add(CapabilityAtomicFloat16AddEXT, "AtomicFloat16AddEXT");
611+
add(CapabilityLongVectorEXT, "LongVectorEXT");
611612
add(CapabilityDebugInfoModuleINTEL, "DebugInfoModuleINTEL");
612613
add(CapabilitySplitBarrierINTEL, "SplitBarrierINTEL");
613614
add(CapabilityGlobalVariableFPGADecorationsINTEL,

lib/SPIRV/libSPIRV/SPIRVType.h

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

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

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

0 commit comments

Comments
 (0)