Skip to content

Commit e7651e6

Browse files
authored
[SPIRV] Add support for SPV_KHR_bit_instructions (#66215)
Adds support for SPV_KHR_bit_instructions. It is only used whenever we don't need the whole Shader capability, which is a superset of this extension.
1 parent 7b3db80 commit e7651e6

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "SPIRVModuleAnalysis.h"
18+
#include "MCTargetDesc/SPIRVBaseInfo.h"
19+
#include "MCTargetDesc/SPIRVMCTargetDesc.h"
1820
#include "SPIRV.h"
1921
#include "SPIRVSubtarget.h"
2022
#include "SPIRVTargetMachine.h"
@@ -504,7 +506,7 @@ void SPIRV::RequirementHandler::checkSatisfiable(
504506
for (auto Ext : AllExtensions) {
505507
if (ST.canUseExtension(Ext))
506508
continue;
507-
LLVM_DEBUG(dbgs() << "Extension not suported: "
509+
LLVM_DEBUG(dbgs() << "Extension not supported: "
508510
<< getSymbolicOperandMnemonic(
509511
OperandCategory::ExtensionOperand, Ext)
510512
<< "\n");
@@ -523,6 +525,13 @@ void SPIRV::RequirementHandler::addAvailableCaps(const CapabilityList &ToAdd) {
523525
SPIRV::OperandCategory::CapabilityOperand, Cap));
524526
}
525527

528+
void SPIRV::RequirementHandler::removeCapabilityIf(
529+
const Capability::Capability ToRemove,
530+
const Capability::Capability IfPresent) {
531+
if (AvailableCaps.contains(IfPresent))
532+
AvailableCaps.erase(ToRemove);
533+
}
534+
526535
namespace llvm {
527536
namespace SPIRV {
528537
void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
@@ -734,6 +743,16 @@ void addInstrRequirements(const MachineInstr &MI,
734743
break;
735744
}
736745
case SPIRV::OpBitReverse:
746+
case SPIRV::OpBitFieldInsert:
747+
case SPIRV::OpBitFieldSExtract:
748+
case SPIRV::OpBitFieldUExtract:
749+
if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
750+
Reqs.addCapability(SPIRV::Capability::Shader);
751+
break;
752+
}
753+
Reqs.addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
754+
Reqs.addCapability(SPIRV::Capability::BitInstructions);
755+
break;
737756
case SPIRV::OpTypeRuntimeArray:
738757
Reqs.addCapability(SPIRV::Capability::Shader);
739758
break;
@@ -887,6 +906,12 @@ void addInstrRequirements(const MachineInstr &MI,
887906
default:
888907
break;
889908
}
909+
910+
// If we require capability Shader, then we can remove the requirement for
911+
// the BitInstructions capability, since Shader is a superset capability
912+
// of BitInstructions.
913+
Reqs.removeCapabilityIf(SPIRV::Capability::BitInstructions,
914+
SPIRV::Capability::Shader);
890915
}
891916

892917
static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ struct RequirementHandler {
113113
bool isCapabilityAvailable(Capability::Capability Cap) const {
114114
return AvailableCaps.contains(Cap);
115115
}
116+
117+
// Remove capability ToRemove, but only if IfPresent is present.
118+
void removeCapabilityIf(const Capability::Capability ToRemove,
119+
const Capability::Capability IfPresent);
116120
};
117121

118122
using InstrList = SmallVector<MachineInstr *>;

llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "SPIRVSubtarget.h"
14+
#include "MCTargetDesc/SPIRVBaseInfo.h"
1415
#include "SPIRV.h"
1516
#include "SPIRVGlobalRegistry.h"
1617
#include "SPIRVLegalizerInfo.h"
@@ -40,7 +41,11 @@ cl::list<SPIRV::Extension::Extension> Extensions(
4041
clEnumValN(SPIRV::Extension::SPV_KHR_no_integer_wrap_decoration,
4142
"SPV_KHR_no_integer_wrap_decoration",
4243
"Adds decorations to indicate that a given instruction does "
43-
"not cause integer wrapping")));
44+
"not cause integer wrapping"),
45+
clEnumValN(SPIRV::Extension::SPV_KHR_bit_instructions,
46+
"SPV_KHR_bit_instructions",
47+
"This enables bit instructions to be used by SPIR-V modules "
48+
"without requiring the Shader capability")));
4449

4550
// Compare version numbers, but allow 0 to mean unspecified.
4651
static bool isAtLeastVer(uint32_t Target, uint32_t VerToCompareTo) {

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shad
450450
defm CooperativeMatrixNV : CapabilityOperand<5357, 0, 0, [], [Shader]>;
451451
defm ArbitraryPrecisionIntegersINTEL : CapabilityOperand<5844, 0, 0, [SPV_INTEL_arbitrary_precision_integers], [Int8, Int16]>;
452452
defm OptNoneINTEL : CapabilityOperand<6094, 0, 0, [SPV_INTEL_optnone], []>;
453+
defm BitInstructions : CapabilityOperand<6025, 0, 0, [SPV_KHR_bit_instructions], []>;
453454

454455
//===----------------------------------------------------------------------===//
455456
// Multiclass used to define SourceLanguage enum values and at the same time
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s --spirv-extensions=SPV_KHR_bit_instructions -o - | FileCheck %s --check-prefix=CHECK-EXTENSION
2+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-NO-EXTENSION
3+
4+
; CHECK-EXTENSION: OpCapability BitInstructions
5+
; CHECK-EXTENSION-NEXT: OpExtension "SPV_KHR_bit_instructions"
6+
; CHECK-EXTENSION-NOT: OpCabilitity Shader
7+
; CHECK-NO-EXTENSION: OpCapability Shader
8+
; CHECK-NO-EXTENSION-NOT: OpCabilitity BitInstructions
9+
; CHECK-NO-EXTENSION-NOT: OpExtension "SPV_KHR_bit_instructions"
10+
11+
12+
; CHECK-EXTENSION: %[[#int:]] = OpTypeInt 32
13+
; CHECK-EXTENSION: OpBitReverse %[[#int]]
14+
; CHECK-NO-EXTENSION: %[[#int:]] = OpTypeInt 32
15+
; CHECK-NO-EXTENSION: OpBitReverse %[[#int]]
16+
17+
define spir_kernel void @testBitRev(i32 %a, i32 %b, i32 %c, i32 addrspace(1)* nocapture %res) local_unnamed_addr {
18+
entry:
19+
%call = tail call i32 @llvm.bitreverse.i32(i32 %b)
20+
store i32 %call, i32 addrspace(1)* %res, align 4
21+
ret void
22+
}
23+
24+
declare i32 @llvm.bitreverse.i32(i32)

0 commit comments

Comments
 (0)