Skip to content

Commit eee5bc8

Browse files
committed
[clang] Lower modf builtin using llvm.modf intrinsic
This updates the existing `modf[f|l]` builtin to be lowered via the `llvm.modf.*` intrinsic when `-fno-math-errno` is set (rather than directly to a library call).
1 parent 2a5050a commit eee5bc8

File tree

5 files changed

+56
-12
lines changed

5 files changed

+56
-12
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,24 @@ static void emitSincosBuiltin(CodeGenFunction &CGF, const CallExpr *E,
859859
StoreCos->setMetadata(LLVMContext::MD_noalias, AliasScopeList);
860860
}
861861

862+
static llvm::Value *emitModfBuiltin(CodeGenFunction &CGF, const CallExpr *E,
863+
llvm::Intrinsic::ID IntrinsicID) {
864+
llvm::Value *Val = CGF.EmitScalarExpr(E->getArg(0));
865+
llvm::Value *IntPartDest = CGF.EmitScalarExpr(E->getArg(1));
866+
867+
llvm::Function *F = CGF.CGM.getIntrinsic(IntrinsicID, {Val->getType()});
868+
llvm::Value *Call = CGF.Builder.CreateCall(F, Val);
869+
870+
llvm::Value *FractionalResult = CGF.Builder.CreateExtractValue(Call, 0);
871+
llvm::Value *IntegralResult = CGF.Builder.CreateExtractValue(Call, 1);
872+
873+
QualType DestPtrType = E->getArg(1)->getType()->getPointeeType();
874+
LValue IntegralLV = CGF.MakeNaturalAlignAddrLValue(IntPartDest, DestPtrType);
875+
CGF.Builder.CreateStore(IntegralResult, IntegralLV.getAddress());
876+
877+
return FractionalResult;
878+
}
879+
862880
/// EmitFAbs - Emit a call to @llvm.fabs().
863881
static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
864882
Function *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
@@ -3259,6 +3277,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
32593277
return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod"));
32603278
}
32613279

3280+
case Builtin::BImodf:
3281+
case Builtin::BImodff:
3282+
case Builtin::BImodfl:
3283+
case Builtin::BI__builtin_modf:
3284+
case Builtin::BI__builtin_modff:
3285+
case Builtin::BI__builtin_modfl:
3286+
return RValue::get(emitModfBuiltin(*this, E, Intrinsic::modf));
3287+
32623288
case Builtin::BIlog:
32633289
case Builtin::BIlogf:
32643290
case Builtin::BIlogl:

clang/test/CodeGen/X86/math-builtins.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
3838
// NO__ERRNO-NEXT: [[FREXP_F128_0:%.+]] = extractvalue { fp128, i32 } [[FREXP_F128]], 0
3939

4040

41+
// NO__ERRNO: [[MODF_F64:%.+]] = call { double, double } @llvm.modf.f64(double %{{.+}})
42+
// NO__ERRNO-NEXT: [[MODF_F64_FP:%.+]] = extractvalue { double, double } [[MODF_F64]], 0
43+
// NO__ERRNO-NEXT: [[MODF_F64_IP:%.+]] = extractvalue { double, double } [[MODF_F64]], 1
44+
// NO__ERRNO-NEXT: store double [[MODF_F64_IP]], ptr %{{.+}}, align 8
45+
46+
// NO__ERRNO: [[MODF_F32:%.+]] = call { float, float } @llvm.modf.f32(float %{{.+}})
47+
// NO__ERRNO-NEXT: [[MODF_F32_FP:%.+]] = extractvalue { float, float } [[MODF_F32]], 0
48+
// NO__ERRNO-NEXT: [[MODF_F32_IP:%.+]] = extractvalue { float, float } [[MODF_F32]], 1
49+
// NO__ERRNO-NEXT: store float [[MODF_F32_IP]], ptr %{{.+}}, align 4
50+
51+
// NO__ERRNO: [[MODF_F80:%.+]] = call { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80 %{{.+}})
52+
// NO__ERRNO-NEXT: [[MODF_F80_FP:%.+]] = extractvalue { x86_fp80, x86_fp80 } [[MODF_F80]], 0
53+
// NO__ERRNO-NEXT: [[MODF_F80_IP:%.+]] = extractvalue { x86_fp80, x86_fp80 } [[MODF_F80]], 1
54+
// NO__ERRNO-NEXT: store x86_fp80 [[MODF_F80_IP]], ptr %{{.+}}, align 16
55+
56+
// NO__ERRNO: call fp128 @modff128(fp128 noundef %{{.+}}, ptr noundef %{{.+}})
57+
58+
4159
// NO__ERRNO: [[SINCOS_F64:%.+]] = call { double, double } @llvm.sincos.f64(double %{{.+}})
4260
// NO__ERRNO-NEXT: [[SINCOS_F64_0:%.+]] = extractvalue { double, double } [[SINCOS_F64]], 0
4361
// NO__ERRNO-NEXT: [[SINCOS_F64_1:%.+]] = extractvalue { double, double } [[SINCOS_F64]], 1
@@ -139,10 +157,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
139157

140158
__builtin_modf(f,d); __builtin_modff(f,fp); __builtin_modfl(f,l); __builtin_modff128(f,l);
141159

142-
// NO__ERRNO: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE:#[0-9]+]]
143-
// NO__ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
144-
// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
145-
// NO__ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) [[NOT_READNONE]]
160+
// NO__ERRNO: declare { double, double } @llvm.modf.f64(double) [[READNONE_INTRINSIC]]
161+
// NO__ERRNO: declare { float, float } @llvm.modf.f32(float) [[READNONE_INTRINSIC]]
162+
// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) [[READNONE_INTRINSIC]]
163+
// NO__ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) [[NOT_READNONE:#[0-9]+]]
146164
// HAS_ERRNO: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE]]
147165
// HAS_ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
148166
// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]

clang/test/CodeGen/aix-builtin-mapping.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ int main()
1717
returnValue = __builtin_ldexpl(1.0L, 1);
1818
}
1919

20-
// CHECK: %call = call double @modf(double noundef 1.000000e+00, ptr noundef %DummyLongDouble) #3
20+
// CHECK: %{{.+}} = call { double, double } @llvm.modf.f64(double 1.000000e+00)
2121
// CHECK: %{{.+}} = call { double, i32 } @llvm.frexp.f64.i32(double 0.000000e+00)
2222
// CHECK: %{{.+}} = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 1)

clang/test/CodeGen/builtin-attributes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// REQUIRES: arm-registered-target
2-
// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -emit-llvm -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -fmath-errno -emit-llvm -o - %s | FileCheck %s
33

44
int printf(const char *, ...);
55
void exit(int);

clang/test/CodeGen/math-libcalls.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
8383

8484
modf(f,d); modff(f,fp); modfl(f,l);
8585

86-
// NO__ERRNO: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE]]
87-
// NO__ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
88-
// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
86+
// NO__ERRNO: declare { double, double } @llvm.modf.f64(double) [[READNONE_INTRINSIC]]
87+
// NO__ERRNO: declare { float, float } @llvm.modf.f32(float) [[READNONE_INTRINSIC]]
88+
// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) [[READNONE_INTRINSIC]]
8989
// HAS_ERRNO: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE]]
9090
// HAS_ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
9191
// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
92-
// HAS_MAYTRAP: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE]]
93-
// HAS_MAYTRAP: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
94-
// HAS_MAYTRAP: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
92+
// HAS_MAYTRAP: declare { double, double } @llvm.modf.f64(double) [[READNONE_INTRINSIC]]
93+
// HAS_MAYTRAP: declare { float, float } @llvm.modf.f32(float) [[READNONE_INTRINSIC]]
94+
// HAS_MAYTRAP: declare { x86_fp80, x86_fp80 } @llvm.modf.f80(x86_fp80) [[READNONE_INTRINSIC]]
9595

9696
nan(c); nanf(c); nanl(c);
9797

0 commit comments

Comments
 (0)