Skip to content

Commit eb33c58

Browse files
AlexeySachkovvmaksimo
authored andcommitted
Add possibility to lower llvm.fmuladd into mad from OpenCL extinst
1 parent 5ffafc6 commit eb33c58

File tree

5 files changed

+66
-12
lines changed

5 files changed

+66
-12
lines changed

llvm-spirv/include/LLVMSPIRVOpts.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,14 @@ class TranslatorOpts {
160160

161161
void setDebugInfoEIS(DebugInfoEIS EIS) { DebugInfoVersion = EIS; }
162162

163+
bool shouldReplaceLLVMFmulAddWithOpenCLMad() const noexcept {
164+
return ReplaceLLVMFmulAddWithOpenCLMad;
165+
}
166+
167+
void setReplaceLLVMFmulAddWithOpenCLMad(bool Value) noexcept {
168+
ReplaceLLVMFmulAddWithOpenCLMad = Value;
169+
}
170+
163171
private:
164172
// Common translation options
165173
VersionNumber MaxVersion = VersionNumber::MaximumVersion;
@@ -192,6 +200,10 @@ class TranslatorOpts {
192200
bool AllowExtraDIExpressions = false;
193201

194202
DebugInfoEIS DebugInfoVersion = DebugInfoEIS::OpenCL_DebugInfo_100;
203+
204+
// Controls whether llvm.fmuladd.* should be replaced with mad from OpenCL
205+
// extended instruction set or with a simple fmul + fadd
206+
bool ReplaceLLVMFmulAddWithOpenCLMad = true;
195207
};
196208

197209
} // namespace SPIRV

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,6 +2337,19 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
23372337
// For llvm.fmuladd.* fusion is not guaranteed. If a fused multiply-add
23382338
// is required the corresponding llvm.fma.* intrinsic function should be
23392339
// used instead.
2340+
// If allowed, let's replace llvm.fmuladd.* with mad from OpenCL extended
2341+
// instruction set, as it has the same semantic for FULL_PROFILE OpenCL
2342+
// devices (implementation-defined for EMBEDDED_PROFILE).
2343+
if (BM->shouldReplaceLLVMFmulAddWithOpenCLMad()) {
2344+
std::vector<SPIRVValue *> Ops{transValue(II->getArgOperand(0), BB),
2345+
transValue(II->getArgOperand(1), BB),
2346+
transValue(II->getArgOperand(2), BB)};
2347+
return BM->addExtInst(transType(II->getType()),
2348+
BM->getExtInstSetId(SPIRVEIS_OpenCL),
2349+
OpenCLLIB::Mad, Ops, BB);
2350+
}
2351+
2352+
// Otherwise, just break llvm.fmuladd.* into a pair of fmul + fadd
23402353
SPIRVType *Ty = transType(II->getType());
23412354
SPIRVValue *Mul =
23422355
BM->addBinaryInst(OpFMul, Ty, transValue(II->getArgOperand(0), BB),

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ class SPIRVModule {
489489
return TranslationOpts.allowExtraDIExpressions();
490490
}
491491

492+
bool shouldReplaceLLVMFmulAddWithOpenCLMad() const noexcept {
493+
return TranslationOpts.shouldReplaceLLVMFmulAddWithOpenCLMad();
494+
}
495+
492496
SPIRVExtInstSetKind getDebugInfoEIS() const {
493497
switch (TranslationOpts.getDebugInfoEIS()) {
494498
case DebugInfoEIS::SPIRV_Debug:

llvm-spirv/test/llvm-intrinsics/fmuladd.ll

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
; RUN: llvm-as %s -o %t.bc
2-
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s
3-
; RUN: llvm-spirv %t.bc -o %t.spv
4-
; RUN: spirv-val %t.spv
5-
6-
; CHECK-NOT: llvm.fmuladd
7-
8-
; CHECK: TypeFloat [[f32:[0-9]+]] 32
9-
; CHECK: TypeFloat [[f64:[0-9]+]] 64
2+
; RUN: llvm-spirv %t.bc -o %default.spv
3+
; RUN: llvm-spirv %t.bc --spirv-replace-fmuladd-with-ocl-mad=true -o %replace.spv
4+
; RUN: llvm-spirv %t.bc --spirv-replace-fmuladd-with-ocl-mad=false -o %break.spv
5+
; RUN: spirv-val %replace.spv
6+
; RUN: spirv-val %break.spv
7+
; RUN: llvm-spirv %default.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,REPLACE
8+
; RUN: llvm-spirv %replace.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,REPLACE
9+
; RUN: llvm-spirv %break.spv -to-text -o - | FileCheck %s --check-prefixes=COMMON,BREAK
10+
11+
; COMMON-NOT: llvm.fmuladd
12+
13+
; COMMON: TypeFloat [[f32:[0-9]+]] 32
14+
; COMMON: TypeFloat [[f64:[0-9]+]] 64
15+
;
16+
; REPLACE: ExtInst [[f32]] {{[0-9]+}} {{[0-9]+}} mad
17+
; REPLACE: ExtInst [[f64]] {{[0-9]+}} {{[0-9]+}} mad
18+
;
19+
; BREAK: FMul [[f32]] [[mul32:[0-9]+]] {{[0-9]+}} {{[0-9]+}}
20+
; BREAK-NEXT: FAdd [[f32]] {{[0-9]+}} [[mul32]] {{[0-9]+}}
21+
; BREAK: FMul [[f64]] [[mul64:[0-9]+]] {{[0-9]+}} {{[0-9]+}}
22+
; BREAK-NEXT: FAdd [[f64]] {{[0-9]+}} [[mul64]] {{[0-9]+}}
1023

1124
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
1225
target triple = "spir64"
@@ -15,11 +28,7 @@ target triple = "spir64"
1528
define spir_func void @foo(float %a, float %b, float %c, double %x, double %y, double %z) #0 {
1629
entry:
1730
%0 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
18-
; CHECK: FMul [[f32]] [[mul32:[0-9]+]] {{[0-9]+}} {{[0-9]+}}
19-
; CHECK-NEXT: FAdd [[f32]] {{[0-9]+}} [[mul32]] {{[0-9]+}}
2031
%1 = call double @llvm.fmuladd.f64(double %x, double %y, double %z)
21-
; CHECK: FMul [[f64]] [[mul64:[0-9]+]] {{[0-9]+}} {{[0-9]+}}
22-
; CHECK-NEXT: FAdd [[f64]] {{[0-9]+}} [[mul64]] {{[0-9]+}}
2332
ret void
2433
}
2534

llvm-spirv/tools/llvm-spirv/llvm-spirv.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ static cl::opt<SPIRV::DebugInfoEIS> DebugEIS(
202202
"extended instruction set. This version of SPIR-V debug "
203203
"info format is compatible with the SPIRV-Tools")));
204204

205+
static cl::opt<bool> SPIRVReplaceLLVMFmulAddWithOpenCLMad(
206+
"spirv-replace-fmuladd-with-ocl-mad",
207+
cl::desc("Allow replacement of llvm.fmuladd.* intrinsic with OpenCL mad "
208+
"instruction from OpenCL extended instruction set"),
209+
cl::init(true));
210+
205211
static std::string removeExt(const std::string &FileName) {
206212
size_t Pos = FileName.find_last_of(".");
207213
if (Pos != std::string::npos)
@@ -587,6 +593,16 @@ int main(int Ac, char **Av) {
587593
}
588594
}
589595

596+
if (SPIRVReplaceLLVMFmulAddWithOpenCLMad.getNumOccurrences() != 0) {
597+
if (IsReverse) {
598+
errs() << "Note: --spirv-replace-fmuladd-with-ocl-mad option ignored as "
599+
"it only affects translation from LLVM IR to SPIR-V";
600+
} else {
601+
Opts.setReplaceLLVMFmulAddWithOpenCLMad(
602+
SPIRVReplaceLLVMFmulAddWithOpenCLMad);
603+
}
604+
}
605+
590606
if (SPIRVAllowExtraDIExpressions.getNumOccurrences() != 0) {
591607
Opts.setAllowExtraDIExpressionsEnabled(SPIRVAllowExtraDIExpressions);
592608
}

0 commit comments

Comments
 (0)