@@ -76,6 +76,33 @@ using namespace clang;
7676using namespace CodeGen;
7777using 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+
79106static 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 }
0 commit comments