Skip to content

Commit cb015b9

Browse files
authored
[clang][CodeGen] Propagate pragma set fast-math flags to floating point builtins (#90377)
This is a fix for the issue #87758 where fast-math flags are not propagated all builtins. It seems like pragmas with fast math flags was only propagated to calls of unary floating point builtins. This patch propagate them also for binary and ternary floating point builtins.
1 parent 7ee6288 commit cb015b9

File tree

3 files changed

+84
-7
lines changed

3 files changed

+84
-7
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ static Value *emitBinaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
513513
llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
514514
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
515515

516+
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
516517
if (CGF.Builder.getIsFPConstrained()) {
517-
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
518518
Function *F = CGF.CGM.getIntrinsic(ConstrainedIntrinsicID, Src0->getType());
519519
return CGF.Builder.CreateConstrainedFPCall(F, { Src0, Src1 });
520520
} else {
@@ -530,8 +530,8 @@ static Value *emitBinaryExpMaybeConstrainedFPBuiltin(
530530
llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
531531
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
532532

533+
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
533534
if (CGF.Builder.getIsFPConstrained()) {
534-
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
535535
Function *F = CGF.CGM.getIntrinsic(ConstrainedIntrinsicID,
536536
{Src0->getType(), Src1->getType()});
537537
return CGF.Builder.CreateConstrainedFPCall(F, {Src0, Src1});
@@ -551,8 +551,8 @@ static Value *emitTernaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
551551
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
552552
llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2));
553553

554+
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
554555
if (CGF.Builder.getIsFPConstrained()) {
555-
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
556556
Function *F = CGF.CGM.getIntrinsic(ConstrainedIntrinsicID, Src0->getType());
557557
return CGF.Builder.CreateConstrainedFPCall(F, { Src0, Src1, Src2 });
558558
} else {
@@ -704,6 +704,7 @@ static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
704704

705705
static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
706706
const CallExpr *E, llvm::Constant *calleeValue) {
707+
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
707708
CGCallee callee = CGCallee::forDirect(calleeValue, GlobalDecl(FD));
708709
return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
709710
}
@@ -2660,7 +2661,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
26602661
if (OP.hasMathErrnoOverride())
26612662
ErrnoOverriden = OP.getMathErrnoOverride();
26622663
}
2663-
// True if 'atttibute__((optnone)) is used. This attibute overrides
2664+
// True if 'attribute__((optnone))' is used. This attribute overrides
26642665
// fast-math which implies math-errno.
26652666
bool OptNone = CurFuncDecl && CurFuncDecl->hasAttr<OptimizeNoneAttr>();
26662667

clang/test/CodeGen/math-errno.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ float f1(float x) {
2727
// CHECK: tail call float @sqrtf(float noundef {{.*}}) #[[ATTR4_O2:[0-9]+]]
2828

2929
// FAST-LABEL: define {{.*}} nofpclass(nan inf) float @f1
30-
// FAST: call fast nofpclass(nan inf) float @sqrtf(float noundef nofpclass(nan inf) {{.*}}) #[[ATTR3_FAST:[0-9]+]]
30+
// FAST: call nofpclass(nan inf) float @sqrtf(float noundef nofpclass(nan inf) {{.*}}) #[[ATTR3_FAST:[0-9]+]]
3131

3232
// NOOPT-LABEL: define {{.*}} float @f1
3333
// NOOPT: call float @sqrtf(float noundef {{.*}}) #[[ATTR4_NOOPT:[0-9]+]]
@@ -44,7 +44,7 @@ float f2(float x) {
4444
// FAST: call fast float @llvm.sqrt.f32(float {{.*}})
4545

4646
// NOOPT-LABEL: define {{.*}} float @f2
47-
// NOOPT: call float @sqrtf(float {{.*}}) #[[ATTR4_NOOPT:[0-9]+]]
47+
// NOOPT: call fast float @sqrtf(float {{.*}}) #[[ATTR4_NOOPT:[0-9]+]]
4848

4949
__attribute__((optnone))
5050
float f3(float x) {
@@ -56,7 +56,7 @@ float f3(float x) {
5656
// CHECK: call float @sqrtf(float noundef {{.*}})
5757

5858
// FAST-LABEL: define {{.*}} nofpclass(nan inf) float @f3
59-
// FAST: call fast nofpclass(nan inf) float @sqrtf(float noundef nofpclass(nan inf) {{.*}}) #[[ATTR4_FAST:[0-9]+]]
59+
// FAST: call nofpclass(nan inf) float @sqrtf(float noundef nofpclass(nan inf) {{.*}}) #[[ATTR4_FAST:[0-9]+]]
6060

6161
// NOOPT-LABEL: define {{.*}} float @f3
6262
// NOOPT: call float @sqrtf(float noundef %0) #[[ATTR4_NOOPT:[0-9]+]]

clang/test/CodeGen/pr87758.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
2+
3+
// precise mode
4+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fmath-errno -ffp-contract=on \
5+
// RUN: -fno-rounding-math -emit-llvm -o - %s | FileCheck \
6+
// RUN: --check-prefix=CHECK-PRECISE %s
7+
8+
// fast mode
9+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffast-math -ffp-contract=fast \
10+
// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s
11+
12+
// Reproducer for issue #87758
13+
// The testcase below verifies that the "fast" flag are set on the calls.
14+
15+
float sqrtf(float x); // unary fp builtin
16+
float powf(float x, float y); // binary fp builtin
17+
float fmaf(float x, float y, float z); // ternary fp builtin
18+
char *rindex(const char *s, int c); // not a fp builtin
19+
20+
#pragma float_control(push)
21+
#pragma float_control(precise, off)
22+
// CHECK: define dso_local float @fp_precise_off_libm_calls(
23+
// CHECK: call fast float @llvm.sqrt.f32(
24+
// CHECK: call fast float @llvm.pow.f32(
25+
// CHECK: call fast float @llvm.fma.f32(
26+
// CHECK: call ptr @rindex(
27+
28+
// CHECK-PRECISE: define dso_local float @fp_precise_off_libm_calls(
29+
// CHECK-PRECISE: call fast float @sqrtf(
30+
// CHECK-PRECISE: call fast float @powf(
31+
// CHECK-PRECISE: call fast float @llvm.fma.f32(
32+
// CHECK-PRECISE: call ptr @rindex(
33+
34+
// CHECK-FAST: define dso_local nofpclass(nan inf) float @fp_precise_off_libm_calls(
35+
// CHECK-FAST: call fast float @llvm.sqrt.f32(
36+
// CHECK-FAST: call fast float @llvm.pow.f32(
37+
// CHECK-FAST: call fast float @llvm.fma.f32(
38+
// CHECK-FAST: call ptr @rindex(
39+
40+
float fp_precise_off_libm_calls(float a, float b, float c, const char *d, char *e, unsigned char f) {
41+
a = sqrtf(a);
42+
a = powf(a,b);
43+
a = fmaf(a,b,c);
44+
e = rindex(d, 75);
45+
return a;
46+
}
47+
#pragma float_control(pop)
48+
49+
#pragma float_control(push)
50+
#pragma float_control(precise, on)
51+
// CHECK: define dso_local float @fp_precise_on_libm_calls(
52+
// CHECK: call float @sqrtf(
53+
// CHECK: call float @powf(
54+
// CHECK: call float @llvm.fma.f32(
55+
// CHECK: call ptr @rindex(
56+
57+
// CHECK-PRECISE: define dso_local float @fp_precise_on_libm_calls(
58+
// CHECK-PRECISE: call float @sqrtf(
59+
// CHECK-PRECISE: call float @powf(
60+
// CHECK-PRECISE: call float @llvm.fma.f32(
61+
// CHECK-PRECISE: call ptr @rindex(
62+
63+
// CHECK-FAST: define dso_local nofpclass(nan inf) float @fp_precise_on_libm_calls(
64+
// CHECK-FAST: call nofpclass(nan inf) float @sqrtf(
65+
// CHECK-FAST: call nofpclass(nan inf) float @powf(
66+
// CHECK-FAST: call float @llvm.fma.f32(
67+
// CHECK-FAST: call ptr @rindex(
68+
69+
float fp_precise_on_libm_calls(float a, float b, float c, const char *d, char *e, unsigned char f) {
70+
a = sqrtf(a);
71+
a = powf(a,b);
72+
a = fmaf(a,b,c);
73+
e = rindex(d, 75);
74+
return a;
75+
}
76+
#pragma float_control(pop)

0 commit comments

Comments
 (0)