Skip to content

Commit 4917540

Browse files
authored
[AMDGPU][clang] provide device implementation for __builtin_logb and __builtin_scalebn (llvm#129347) (llvm#2462)
2 parents 1c23824 + 74010fc commit 4917540

File tree

4 files changed

+1133
-3
lines changed

4 files changed

+1133
-3
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,33 @@ using namespace clang;
7676
using namespace CodeGen;
7777
using namespace llvm;
7878

79+
/// Some builtins do not have library implementation on some targets and
80+
/// are instead emitted as LLVM IRs by some target builtin emitters.
81+
/// FIXME: Remove this when library support is added
82+
static bool shouldEmitBuiltinAsIR(unsigned BuiltinID,
83+
const Builtin::Context &BI,
84+
const CodeGenFunction &CGF) {
85+
if (!CGF.CGM.getLangOpts().MathErrno &&
86+
CGF.CurFPFeatures.getExceptionMode() ==
87+
LangOptions::FPExceptionModeKind::FPE_Ignore &&
88+
!CGF.CGM.getTargetCodeGenInfo().supportsLibCall()) {
89+
switch (BuiltinID) {
90+
default:
91+
return false;
92+
case Builtin::BIlogbf:
93+
case Builtin::BI__builtin_logbf:
94+
case Builtin::BIlogb:
95+
case Builtin::BI__builtin_logb:
96+
case Builtin::BIscalbnf:
97+
case Builtin::BI__builtin_scalbnf:
98+
case Builtin::BIscalbn:
99+
case Builtin::BI__builtin_scalbn:
100+
return true;
101+
}
102+
}
103+
return false;
104+
}
105+
79106
static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size,
80107
Align AlignmentInBytes) {
81108
ConstantInt *Byte;
@@ -2882,7 +2909,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
28822909
// disabled.
28832910
// Math intrinsics are generated only when math-errno is disabled. Any pragmas
28842911
// or attributes that affect math-errno should prevent or allow math
2885-
// intrincs to be generated. Intrinsics are generated:
2912+
// intrinsics to be generated. Intrinsics are generated:
28862913
// 1- In fast math mode, unless math-errno is overriden
28872914
// via '#pragma float_control(precise, on)', or via an
28882915
// 'attribute__((optnone))'.
@@ -6429,13 +6456,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
64296456
// If this is an alias for a lib function (e.g. __builtin_sin), emit
64306457
// the call using the normal call path, but using the unmangled
64316458
// version of the function name.
6432-
if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
6459+
const auto &BI = getContext().BuiltinInfo;
6460+
if (!shouldEmitBuiltinAsIR(BuiltinID, BI, *this) &&
6461+
BI.isLibFunction(BuiltinID))
64336462
return emitLibraryCall(*this, FD, E,
64346463
CGM.getBuiltinLibFunction(FD, BuiltinID));
64356464

64366465
// If this is a predefined lib function (e.g. malloc), emit the call
64376466
// using exactly the normal call path.
6438-
if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
6467+
if (BI.isPredefinedLibFunction(BuiltinID))
64396468
return emitLibraryCall(*this, FD, E, CGM.getRawFunctionPointer(FD));
64406469

64416470
// Check that a call to a target specific builtin has the correct target
@@ -20662,6 +20691,57 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
2066220691
case AMDGPU::BI__builtin_amdgcn_s_prefetch_data:
2066320692
return emitBuiltinWithOneOverloadedType<2>(
2066420693
*this, E, Intrinsic::amdgcn_s_prefetch_data);
20694+
case Builtin::BIlogbf:
20695+
case Builtin::BI__builtin_logbf: {
20696+
Value *Src0 = EmitScalarExpr(E->getArg(0));
20697+
Function *FrExpFunc = CGM.getIntrinsic(
20698+
Intrinsic::frexp, {Src0->getType(), Builder.getInt32Ty()});
20699+
CallInst *FrExp = Builder.CreateCall(FrExpFunc, Src0);
20700+
Value *Exp = Builder.CreateExtractValue(FrExp, 1);
20701+
Value *Add = Builder.CreateAdd(
20702+
Exp, ConstantInt::getSigned(Exp->getType(), -1), "", false, true);
20703+
Value *SIToFP = Builder.CreateSIToFP(Add, Builder.getFloatTy());
20704+
Value *Fabs =
20705+
emitBuiltinWithOneOverloadedType<1>(*this, E, Intrinsic::fabs);
20706+
Value *FCmpONE = Builder.CreateFCmpONE(
20707+
Fabs, ConstantFP::getInfinity(Builder.getFloatTy()));
20708+
Value *Sel1 = Builder.CreateSelect(FCmpONE, SIToFP, Fabs);
20709+
Value *FCmpOEQ =
20710+
Builder.CreateFCmpOEQ(Src0, ConstantFP::getZero(Builder.getFloatTy()));
20711+
Value *Sel2 = Builder.CreateSelect(
20712+
FCmpOEQ,
20713+
ConstantFP::getInfinity(Builder.getFloatTy(), /*Negative=*/true), Sel1);
20714+
return Sel2;
20715+
}
20716+
case Builtin::BIlogb:
20717+
case Builtin::BI__builtin_logb: {
20718+
Value *Src0 = EmitScalarExpr(E->getArg(0));
20719+
Function *FrExpFunc = CGM.getIntrinsic(
20720+
Intrinsic::frexp, {Src0->getType(), Builder.getInt32Ty()});
20721+
CallInst *FrExp = Builder.CreateCall(FrExpFunc, Src0);
20722+
Value *Exp = Builder.CreateExtractValue(FrExp, 1);
20723+
Value *Add = Builder.CreateAdd(
20724+
Exp, ConstantInt::getSigned(Exp->getType(), -1), "", false, true);
20725+
Value *SIToFP = Builder.CreateSIToFP(Add, Builder.getDoubleTy());
20726+
Value *Fabs =
20727+
emitBuiltinWithOneOverloadedType<1>(*this, E, Intrinsic::fabs);
20728+
Value *FCmpONE = Builder.CreateFCmpONE(
20729+
Fabs, ConstantFP::getInfinity(Builder.getDoubleTy()));
20730+
Value *Sel1 = Builder.CreateSelect(FCmpONE, SIToFP, Fabs);
20731+
Value *FCmpOEQ =
20732+
Builder.CreateFCmpOEQ(Src0, ConstantFP::getZero(Builder.getDoubleTy()));
20733+
Value *Sel2 = Builder.CreateSelect(
20734+
FCmpOEQ,
20735+
ConstantFP::getInfinity(Builder.getDoubleTy(), /*Negative=*/true),
20736+
Sel1);
20737+
return Sel2;
20738+
}
20739+
case Builtin::BIscalbnf:
20740+
case Builtin::BI__builtin_scalbnf:
20741+
case Builtin::BIscalbn:
20742+
case Builtin::BI__builtin_scalbn:
20743+
return emitBinaryExpMaybeConstrainedFPBuiltin(
20744+
*this, E, Intrinsic::ldexp, Intrinsic::experimental_constrained_ldexp);
2066520745
default:
2066620746
return nullptr;
2066720747
}

clang/lib/CodeGen/TargetInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class TargetCodeGenInfo {
7171
return *SwiftInfo;
7272
}
7373

74+
/// supportsLibCall - Query to whether or not target supports all
75+
/// lib calls.
76+
virtual bool supportsLibCall() const { return true; }
77+
7478
/// setTargetAttributes - Provides a convenient hook to handle extra
7579
/// target-specific attributes for the given global.
7680
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,

clang/lib/CodeGen/Targets/AMDGPU.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo {
301301
AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT)
302302
: TargetCodeGenInfo(std::make_unique<AMDGPUABIInfo>(CGT)) {}
303303

304+
bool supportsLibCall() const override { return false; }
304305
void setFunctionDeclAttributes(const FunctionDecl *FD, llvm::Function *F,
305306
CodeGenModule &CGM) const;
306307

0 commit comments

Comments
 (0)