@@ -31,6 +31,27 @@ using namespace CodeGen;
31
31
using namespace llvm ;
32
32
33
33
namespace {
34
+
35
+ // Has second type mangled argument.
36
+ static Value *
37
+ emitBinaryExpMaybeConstrainedFPBuiltin (CodeGenFunction &CGF, const CallExpr *E,
38
+ Intrinsic::ID IntrinsicID,
39
+ Intrinsic::ID ConstrainedIntrinsicID) {
40
+ llvm::Value *Src0 = CGF.EmitScalarExpr (E->getArg (0 ));
41
+ llvm::Value *Src1 = CGF.EmitScalarExpr (E->getArg (1 ));
42
+
43
+ CodeGenFunction::CGFPOptionsRAII FPOptsRAII (CGF, E);
44
+ if (CGF.Builder .getIsFPConstrained ()) {
45
+ Function *F = CGF.CGM .getIntrinsic (ConstrainedIntrinsicID,
46
+ {Src0->getType (), Src1->getType ()});
47
+ return CGF.Builder .CreateConstrainedFPCall (F, {Src0, Src1});
48
+ }
49
+
50
+ Function *F =
51
+ CGF.CGM .getIntrinsic (IntrinsicID, {Src0->getType (), Src1->getType ()});
52
+ return CGF.Builder .CreateCall (F, {Src0, Src1});
53
+ }
54
+
34
55
// If \p E is not null pointer, insert address space cast to match return
35
56
// type of \p E if necessary.
36
57
Value *EmitAMDGPUDispatchPtr (CodeGenFunction &CGF,
@@ -1876,6 +1897,30 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
1876
1897
case AMDGPU::BI__builtin_amdgcn_s_prefetch_data:
1877
1898
return emitBuiltinWithOneOverloadedType<2 >(
1878
1899
*this , E, Intrinsic::amdgcn_s_prefetch_data);
1900
+ case Builtin::BIlogb:
1901
+ case Builtin::BI__builtin_logb: {
1902
+ auto *Src0 = EmitScalarExpr (E->getArg (0 ));
1903
+ auto *FrExpFunc = CGM.getIntrinsic (Intrinsic::amdgcn_frexp_exp,
1904
+ {Builder.getInt32Ty (), Src0->getType ()});
1905
+ auto *FrExp = Builder.CreateCall (FrExpFunc, Src0);
1906
+ auto *Add = Builder.CreateAdd (
1907
+ FrExp, ConstantInt::getSigned (FrExp->getType (), -1 ), " " , false , true );
1908
+ auto *SIToFP = Builder.CreateSIToFP (Add, Builder.getDoubleTy ());
1909
+ auto *Fabs = emitBuiltinWithOneOverloadedType<1 >(*this , E, Intrinsic::fabs );
1910
+ auto *FCmpONE = Builder.CreateFCmpONE (
1911
+ Fabs, ConstantFP::getInfinity (Builder.getDoubleTy ()));
1912
+ auto *Sel1 = Builder.CreateSelect (FCmpONE, SIToFP, Fabs);
1913
+ auto *FCmpOEQ =
1914
+ Builder.CreateFCmpOEQ (Src0, ConstantFP::getZero (Builder.getDoubleTy ()));
1915
+ auto *Sel2 = Builder.CreateSelect (
1916
+ FCmpOEQ, ConstantFP::getInfinity (Builder.getDoubleTy (), /* Neg*/ true ),
1917
+ Sel1);
1918
+ return Sel2;
1919
+ }
1920
+ case Builtin::BIscalbn:
1921
+ case Builtin::BI__builtin_scalbn:
1922
+ return emitBinaryExpMaybeConstrainedFPBuiltin (
1923
+ *this , E, Intrinsic::ldexp , Intrinsic::experimental_constrained_ldexp);
1879
1924
default :
1880
1925
return nullptr ;
1881
1926
}
0 commit comments