Skip to content

Commit 2cd8b78

Browse files
authored
Add --spirv-ext-inst option (#2382)
Add option --spirv-ext-inst=[none|OpenCL.std] to control what external instructions can be used when translating form LLVM IR to SPIR-V.
1 parent c621918 commit 2cd8b78

File tree

5 files changed

+59
-5
lines changed

5 files changed

+59
-5
lines changed

include/LLVMSPIRVOpts.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ enum class ExtensionID : uint32_t {
9999
Last,
100100
};
101101

102+
enum class ExtInst : uint32_t { None, OpenCL };
103+
102104
enum class BIsRepresentation : uint32_t { OpenCL12, OpenCL20, SPIRVFriendlyIR };
103105

104106
enum class FPContractMode : uint32_t { On, Off, Fast };
@@ -180,6 +182,14 @@ class TranslatorOpts {
180182
return true;
181183
}
182184

185+
void setExtInst(ExtInst Value) {
186+
// --spirv-ext-inst supersedes --spirv-replace-fmuladd-with-ocl-mad
187+
ReplaceLLVMFmulAddWithOpenCLMad = false;
188+
ExtInstValue = Value;
189+
}
190+
191+
ExtInst getExtInst() const { return ExtInstValue; }
192+
183193
void setDesiredBIsRepresentation(BIsRepresentation Value) {
184194
DesiredRepresentationOfBIs = Value;
185195
}
@@ -238,6 +248,8 @@ class TranslatorOpts {
238248
// SPIR-V to LLVM translation options
239249
bool GenKernelArgNameMD = false;
240250
std::unordered_map<uint32_t, uint64_t> ExternalSpecialization;
251+
// Extended instruction set to use when translating from LLVM IR to SPIR-V
252+
ExtInst ExtInstValue = ExtInst::None;
241253
// Representation of built-ins, which should be used while translating from
242254
// SPIR-V to back to LLVM IR
243255
BIsRepresentation DesiredRepresentationOfBIs = BIsRepresentation::OpenCL12;

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4206,7 +4206,8 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
42064206
// If allowed, let's replace llvm.fmuladd.* with mad from OpenCL extended
42074207
// instruction set, as it has the same semantic for FULL_PROFILE OpenCL
42084208
// devices (implementation-defined for EMBEDDED_PROFILE).
4209-
if (BM->shouldReplaceLLVMFmulAddWithOpenCLMad()) {
4209+
if (BM->shouldReplaceLLVMFmulAddWithOpenCLMad() ||
4210+
BM->getExtInst() == SPIRV::ExtInst::OpenCL) {
42104211
std::vector<SPIRVValue *> Ops{transValue(II->getArgOperand(0), BB),
42114212
transValue(II->getArgOperand(1), BB),
42124213
transValue(II->getArgOperand(2), BB)};

lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ class SPIRVModule {
570570
return SPIRVEIS_Debug;
571571
}
572572

573+
ExtInst getExtInst() const { return TranslationOpts.getExtInst(); }
574+
573575
BIsRepresentation getDesiredBIsRepresentation() const {
574576
return TranslationOpts.getDesiredBIsRepresentation();
575577
}

test/llvm-intrinsics/fmuladd.ll

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
; RUN: llvm-as %s -o %t.bc
22
; RUN: llvm-spirv %t.bc -o %t-default.spv
3-
; RUN: llvm-spirv %t.bc --spirv-replace-fmuladd-with-ocl-mad=true -o %t-replace.spv
4-
; RUN: llvm-spirv %t.bc --spirv-replace-fmuladd-with-ocl-mad=false -o %t-break.spv
3+
; RUN: llvm-spirv %t-default.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,REPLACE
4+
5+
; preferred option for controlling fmuladd generation
6+
; RUN: llvm-spirv %t.bc --spirv-ext-inst=OpenCL.std -o %t-replace.spv
7+
; RUN: llvm-spirv %t.bc --spirv-ext-inst=none -o %t-break.spv
58
; RUN: spirv-val %t-replace.spv
69
; RUN: spirv-val %t-break.spv
7-
; RUN: llvm-spirv %t-default.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,REPLACE
810
; RUN: llvm-spirv %t-replace.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,REPLACE
911
; RUN: llvm-spirv %t-break.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,BREAK
1012

13+
; legacy option for controlling fmuladd generation
14+
; RUN: llvm-spirv %t.bc --spirv-replace-fmuladd-with-ocl-mad=true -o %t-replace.legacy.spv
15+
; RUN: llvm-spirv %t.bc --spirv-replace-fmuladd-with-ocl-mad=false -o %t-break.legacy.spv
16+
; RUN: spirv-val %t-replace.legacy.spv
17+
; RUN: spirv-val %t-break.legacy.spv
18+
; RUN: llvm-spirv %t-replace.legacy.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,REPLACE
19+
; RUN: llvm-spirv %t-break.legacy.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,BREAK
20+
1121
; COMMON-NOT: llvm.fmuladd
1222

1323
; COMMON: TypeFloat [[f32:[0-9]+]] 32

tools/llvm-spirv/llvm-spirv.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ static cl::opt<bool> SPIRVGenKernelArgNameMD(
135135
cl::desc("Enable generating OpenCL kernel argument name "
136136
"metadata"));
137137

138+
static cl::opt<SPIRV::ExtInst> ExtInst(
139+
"spirv-ext-inst",
140+
cl::desc("Specify the extended instruction set to use when "
141+
"translating from a LLVM intrinsic function to SPIR-V. "
142+
"If none, some LLVM intrinsic functions will be emulated."),
143+
cl::values(clEnumValN(SPIRV::ExtInst::None, "none",
144+
"No extended instructions"),
145+
clEnumValN(SPIRV::ExtInst::OpenCL, "OpenCL.std",
146+
"OpenCL.std extended instruction set")),
147+
cl::init(SPIRV::ExtInst::None));
148+
138149
static cl::opt<SPIRV::BIsRepresentation> BIsRepresentation(
139150
"spirv-target-env",
140151
cl::desc("Specify a representation of different SPIR-V Instructions which "
@@ -253,7 +264,7 @@ static cl::opt<SPIRV::DebugInfoEIS> DebugEIS(
253264
static cl::opt<bool> SPIRVReplaceLLVMFmulAddWithOpenCLMad(
254265
"spirv-replace-fmuladd-with-ocl-mad",
255266
cl::desc("Allow replacement of llvm.fmuladd.* intrinsic with OpenCL mad "
256-
"instruction from OpenCL extended instruction set"),
267+
"instruction from OpenCL extended instruction set (deprecated)"),
257268
cl::init(true));
258269

259270
static cl::opt<SPIRV::BuiltinFormat> SPIRVBuiltinFormat(
@@ -708,6 +719,24 @@ int main(int Ac, char **Av) {
708719
return Ret;
709720

710721
SPIRV::TranslatorOpts Opts(MaxSPIRVVersion, ExtensionsStatus);
722+
723+
if (ExtInst.getNumOccurrences() != 0) {
724+
if (ExtInst.getNumOccurrences() > 1) {
725+
errs() << "Error: --spirv-ext-inst cannot be used more than once\n";
726+
return -1;
727+
} else if (SPIRVReplaceLLVMFmulAddWithOpenCLMad.getNumOccurrences()) {
728+
errs()
729+
<< "Error: --spirv-ext-inst and --spirv-replace-fmuladd-with-ocl-mad "
730+
"cannot be used together. --spirv-replace-fmuladd-with-ocl-mad "
731+
"is deprecated and --spirv-ext-inst is preferred.\n";
732+
return -1;
733+
} else if (IsReverse) {
734+
errs() << "Note: --spirv-ext-inst option ignored as it only "
735+
"affects translation from LLVM IR to SPIR-V";
736+
}
737+
Opts.setExtInst(ExtInst);
738+
}
739+
711740
if (BIsRepresentation.getNumOccurrences() != 0) {
712741
if (!IsReverse) {
713742
errs() << "Note: --spirv-target-env option ignored as it only "

0 commit comments

Comments
 (0)