@@ -23,6 +23,27 @@ using namespace CodeGen;
2323using namespace llvm ;
2424
2525namespace {
26+
27+ // Has second type mangled argument.
28+ static Value *
29+ emitBinaryExpMaybeConstrainedFPBuiltin (CodeGenFunction &CGF, const CallExpr *E,
30+ Intrinsic::ID IntrinsicID,
31+ Intrinsic::ID ConstrainedIntrinsicID) {
32+ llvm::Value *Src0 = CGF.EmitScalarExpr (E->getArg (0 ));
33+ llvm::Value *Src1 = CGF.EmitScalarExpr (E->getArg (1 ));
34+
35+ CodeGenFunction::CGFPOptionsRAII FPOptsRAII (CGF, E);
36+ if (CGF.Builder .getIsFPConstrained ()) {
37+ Function *F = CGF.CGM .getIntrinsic (ConstrainedIntrinsicID,
38+ {Src0->getType (), Src1->getType ()});
39+ return CGF.Builder .CreateConstrainedFPCall (F, {Src0, Src1});
40+ }
41+
42+ Function *F =
43+ CGF.CGM .getIntrinsic (IntrinsicID, {Src0->getType (), Src1->getType ()});
44+ return CGF.Builder .CreateCall (F, {Src0, Src1});
45+ }
46+
2647// If \p E is not null pointer, insert address space cast to match return
2748// type of \p E if necessary.
2849Value *EmitAMDGPUDispatchPtr (CodeGenFunction &CGF,
@@ -1184,6 +1205,57 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
11841205 case AMDGPU::BI__builtin_amdgcn_s_prefetch_data:
11851206 return emitBuiltinWithOneOverloadedType<2 >(
11861207 *this , E, Intrinsic::amdgcn_s_prefetch_data);
1208+ case Builtin::BIlogbf:
1209+ case Builtin::BI__builtin_logbf: {
1210+ Value *Src0 = EmitScalarExpr (E->getArg (0 ));
1211+ Function *FrExpFunc = CGM.getIntrinsic (
1212+ Intrinsic::frexp, {Src0->getType (), Builder.getInt32Ty ()});
1213+ CallInst *FrExp = Builder.CreateCall (FrExpFunc, Src0);
1214+ Value *Exp = Builder.CreateExtractValue (FrExp, 1 );
1215+ Value *Add = Builder.CreateAdd (
1216+ Exp, ConstantInt::getSigned (Exp->getType (), -1 ), " " , false , true );
1217+ Value *SIToFP = Builder.CreateSIToFP (Add, Builder.getFloatTy ());
1218+ Value *Fabs =
1219+ emitBuiltinWithOneOverloadedType<1 >(*this , E, Intrinsic::fabs);
1220+ Value *FCmpONE = Builder.CreateFCmpONE (
1221+ Fabs, ConstantFP::getInfinity (Builder.getFloatTy ()));
1222+ Value *Sel1 = Builder.CreateSelect (FCmpONE, SIToFP, Fabs);
1223+ Value *FCmpOEQ =
1224+ Builder.CreateFCmpOEQ (Src0, ConstantFP::getZero (Builder.getFloatTy ()));
1225+ Value *Sel2 = Builder.CreateSelect (
1226+ FCmpOEQ,
1227+ ConstantFP::getInfinity (Builder.getFloatTy (), /* Negative=*/ true ), Sel1);
1228+ return Sel2;
1229+ }
1230+ case Builtin::BIlogb:
1231+ case Builtin::BI__builtin_logb: {
1232+ Value *Src0 = EmitScalarExpr (E->getArg (0 ));
1233+ Function *FrExpFunc = CGM.getIntrinsic (
1234+ Intrinsic::frexp, {Src0->getType (), Builder.getInt32Ty ()});
1235+ CallInst *FrExp = Builder.CreateCall (FrExpFunc, Src0);
1236+ Value *Exp = Builder.CreateExtractValue (FrExp, 1 );
1237+ Value *Add = Builder.CreateAdd (
1238+ Exp, ConstantInt::getSigned (Exp->getType (), -1 ), " " , false , true );
1239+ Value *SIToFP = Builder.CreateSIToFP (Add, Builder.getDoubleTy ());
1240+ Value *Fabs =
1241+ emitBuiltinWithOneOverloadedType<1 >(*this , E, Intrinsic::fabs);
1242+ Value *FCmpONE = Builder.CreateFCmpONE (
1243+ Fabs, ConstantFP::getInfinity (Builder.getDoubleTy ()));
1244+ Value *Sel1 = Builder.CreateSelect (FCmpONE, SIToFP, Fabs);
1245+ Value *FCmpOEQ =
1246+ Builder.CreateFCmpOEQ (Src0, ConstantFP::getZero (Builder.getDoubleTy ()));
1247+ Value *Sel2 = Builder.CreateSelect (
1248+ FCmpOEQ,
1249+ ConstantFP::getInfinity (Builder.getDoubleTy (), /* Negative=*/ true ),
1250+ Sel1);
1251+ return Sel2;
1252+ }
1253+ case Builtin::BIscalbnf:
1254+ case Builtin::BI__builtin_scalbnf:
1255+ case Builtin::BIscalbn:
1256+ case Builtin::BI__builtin_scalbn:
1257+ return emitBinaryExpMaybeConstrainedFPBuiltin (
1258+ *this , E, Intrinsic::ldexp, Intrinsic::experimental_constrained_ldexp);
11871259 default :
11881260 return nullptr ;
11891261 }
0 commit comments