@@ -23,6 +23,27 @@ using namespace CodeGen;
23
23
using namespace llvm ;
24
24
25
25
namespace {
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
+
26
47
// If \p E is not null pointer, insert address space cast to match return
27
48
// type of \p E if necessary.
28
49
Value *EmitAMDGPUDispatchPtr (CodeGenFunction &CGF,
@@ -1184,6 +1205,57 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
1184
1205
case AMDGPU::BI__builtin_amdgcn_s_prefetch_data:
1185
1206
return emitBuiltinWithOneOverloadedType<2 >(
1186
1207
*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);
1187
1259
default :
1188
1260
return nullptr ;
1189
1261
}
0 commit comments