Skip to content

Commit e800e7f

Browse files
authored
[ESIMD] Break @llvm.fmuladd back into mul/add to satisfy VC BE. (#5075)
Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent 596f693 commit e800e7f

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

llvm/lib/SYCLLowerIR/LowerESIMD.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,39 @@ static Instruction *generateGenXCall(ExtractElementInst *EEI,
978978
return Inst;
979979
}
980980

981+
// Translates the following intrinsics:
982+
// %res = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
983+
// %res = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
984+
// To
985+
// %mul = fmul <type> %a, <type> %b
986+
// %res = fadd <type> %mul, <type> %c
987+
void translateFmuladd(CallInst *CI) {
988+
assert(CI->getIntrinsicID() == Intrinsic::fmuladd);
989+
IRBuilder<> Bld(CI);
990+
auto *Mul = Bld.CreateFMul(CI->getOperand(0), CI->getOperand(1));
991+
auto *Res = Bld.CreateFAdd(Mul, CI->getOperand(2));
992+
CI->replaceAllUsesWith(Res);
993+
}
994+
995+
// Translates an LLVM intrinsic to a form, digestable by the BE.
996+
bool translateLLVMIntrinsic(CallInst *CI) {
997+
Function *F = CI->getCalledFunction() ? CI->getCalledFunction() : nullptr;
998+
assert(F && F->isIntrinsic());
999+
1000+
switch (F->getIntrinsicID()) {
1001+
case Intrinsic::assume:
1002+
// no translation - it will be simply removed.
1003+
// TODO: make use of 'assume' info in the BE
1004+
break;
1005+
case Intrinsic::fmuladd:
1006+
translateFmuladd(CI);
1007+
break;
1008+
default:
1009+
return false; // "intrinsic wasn't translated, keep the original call"
1010+
}
1011+
return true; // "intrinsic has been translated, erase the original call"
1012+
}
1013+
9811014
/// Replaces the load \p LI of SPIRV global with corresponding call(s) of GenX
9821015
/// intrinsic(s). The users of \p LI may also be transformed if needed for
9831016
/// def/use type correctness.
@@ -1469,8 +1502,10 @@ size_t SYCLLowerESIMDPass::runOnFunction(Function &F,
14691502
Function *Callee = nullptr;
14701503
if (CI && (Callee = CI->getCalledFunction())) {
14711504
// TODO workaround for ESIMD BE until it starts supporting @llvm.assume
1472-
if (match(&I, PatternMatch::m_Intrinsic<Intrinsic::assume>())) {
1473-
ToErase.push_back(CI);
1505+
if (Callee->isIntrinsic()) {
1506+
if (translateLLVMIntrinsic(CI)) {
1507+
ToErase.push_back(CI);
1508+
}
14741509
continue;
14751510
}
14761511
StringRef Name = Callee->getName();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: opt -LowerESIMD -S < %s | FileCheck %s
2+
3+
; This test checks that LowerESIMD pass correctly lowers some llvm intrinsics
4+
; which can't be handled by the VC BE.
5+
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"
6+
target triple = "spir64-unknown-unknown"
7+
8+
declare float @llvm.fmuladd.f32(float %x, float %y, float %z)
9+
declare double @llvm.fmuladd.f64(double %x, double %y, double %z)
10+
11+
define spir_func float @test_fmuladd_f32(float %x, float %y, float %z) {
12+
%1 = call float @llvm.fmuladd.f32(float %x, float %y, float %z)
13+
; CHECK: %[[A:[0-9a-zA-Z\._]+]] = fmul float %x, %y
14+
; CHECK: %[[B:[0-9a-zA-Z\._]+]] = fadd float %[[A]], %z
15+
ret float %1
16+
; CHECK: ret float %[[B]]
17+
}
18+
19+
define spir_func double @test_fmuladd_f64(double %x, double %y, double %z) {
20+
%1 = call double @llvm.fmuladd.f64(double %x, double %y, double %z)
21+
; CHECK: %[[A:[0-9a-zA-Z\._]+]] = fmul double %x, %y
22+
; CHECK: %[[B:[0-9a-zA-Z\._]+]] = fadd double %[[A]], %z
23+
ret double %1
24+
; CHECK: ret double %[[B]]
25+
}
26+

0 commit comments

Comments
 (0)