@@ -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,
@@ -1142,6 +1163,57 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
1142
1163
case AMDGPU::BI__builtin_amdgcn_s_prefetch_data:
1143
1164
return emitBuiltinWithOneOverloadedType<2 >(
1144
1165
*this , E, Intrinsic::amdgcn_s_prefetch_data);
1166
+ case Builtin::BIlogbf:
1167
+ case Builtin::BI__builtin_logbf: {
1168
+ Value *Src0 = EmitScalarExpr (E->getArg (0 ));
1169
+ Function *FrExpFunc = CGM.getIntrinsic (
1170
+ Intrinsic::frexp , {Src0->getType (), Builder.getInt32Ty ()});
1171
+ CallInst *FrExp = Builder.CreateCall (FrExpFunc, Src0);
1172
+ Value *Exp = Builder.CreateExtractValue (FrExp, 1 );
1173
+ Value *Add = Builder.CreateAdd (
1174
+ Exp, ConstantInt::getSigned (Exp->getType (), -1 ), " " , false , true );
1175
+ Value *SIToFP = Builder.CreateSIToFP (Add, Builder.getFloatTy ());
1176
+ Value *Fabs =
1177
+ emitBuiltinWithOneOverloadedType<1 >(*this , E, Intrinsic::fabs );
1178
+ Value *FCmpONE = Builder.CreateFCmpONE (
1179
+ Fabs, ConstantFP::getInfinity (Builder.getFloatTy ()));
1180
+ Value *Sel1 = Builder.CreateSelect (FCmpONE, SIToFP, Fabs);
1181
+ Value *FCmpOEQ =
1182
+ Builder.CreateFCmpOEQ (Src0, ConstantFP::getZero (Builder.getFloatTy ()));
1183
+ Value *Sel2 = Builder.CreateSelect (
1184
+ FCmpOEQ,
1185
+ ConstantFP::getInfinity (Builder.getFloatTy (), /* Negative=*/ true ), Sel1);
1186
+ return Sel2;
1187
+ }
1188
+ case Builtin::BIlogb:
1189
+ case Builtin::BI__builtin_logb: {
1190
+ Value *Src0 = EmitScalarExpr (E->getArg (0 ));
1191
+ Function *FrExpFunc = CGM.getIntrinsic (
1192
+ Intrinsic::frexp , {Src0->getType (), Builder.getInt32Ty ()});
1193
+ CallInst *FrExp = Builder.CreateCall (FrExpFunc, Src0);
1194
+ Value *Exp = Builder.CreateExtractValue (FrExp, 1 );
1195
+ Value *Add = Builder.CreateAdd (
1196
+ Exp, ConstantInt::getSigned (Exp->getType (), -1 ), " " , false , true );
1197
+ Value *SIToFP = Builder.CreateSIToFP (Add, Builder.getDoubleTy ());
1198
+ Value *Fabs =
1199
+ emitBuiltinWithOneOverloadedType<1 >(*this , E, Intrinsic::fabs );
1200
+ Value *FCmpONE = Builder.CreateFCmpONE (
1201
+ Fabs, ConstantFP::getInfinity (Builder.getDoubleTy ()));
1202
+ Value *Sel1 = Builder.CreateSelect (FCmpONE, SIToFP, Fabs);
1203
+ Value *FCmpOEQ =
1204
+ Builder.CreateFCmpOEQ (Src0, ConstantFP::getZero (Builder.getDoubleTy ()));
1205
+ Value *Sel2 = Builder.CreateSelect (
1206
+ FCmpOEQ,
1207
+ ConstantFP::getInfinity (Builder.getDoubleTy (), /* Negative=*/ true ),
1208
+ Sel1);
1209
+ return Sel2;
1210
+ }
1211
+ case Builtin::BIscalbnf:
1212
+ case Builtin::BI__builtin_scalbnf:
1213
+ case Builtin::BIscalbn:
1214
+ case Builtin::BI__builtin_scalbn:
1215
+ return emitBinaryExpMaybeConstrainedFPBuiltin (
1216
+ *this , E, Intrinsic::ldexp , Intrinsic::experimental_constrained_ldexp);
1145
1217
default :
1146
1218
return nullptr ;
1147
1219
}
0 commit comments