[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
echesakov wrote: Ping https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
https://github.com/echesakov created https://github.com/llvm/llvm-project/pull/105912 ...control `FastMathFlags` during code-generation of `ConditionalOperator`. This involves storing `FPOptionsOverride` in trailing storage of `ConditionalOperator` and storing `CurFPOptionsOverride` when creating an AST node. Fixes #84648 >From 124a1c4c7c102421b74eaaa1133ea58a9017e07b Mon Sep 17 00:00:00 2001 From: Egor Chesakov <5292656+echesa...@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:44:14 -0700 Subject: [PATCH] [clang] Allow `pragma float_control(precise, *)` to... ...control `FastMathFlags` during code-generation of `ConditionalOperator`. This involves storing `FPOptionsOverride` in trailing storage of `ConditionalOperator` and storing `CurFPOptionsOverride` when creating an AST node. Fixes #84648 --- clang/include/clang/AST/Expr.h| 67 +-- clang/include/clang/AST/Stmt.h| 11 +++ clang/include/clang/AST/TextNodeDumper.h | 1 + clang/lib/AST/ASTImporter.cpp | 6 +- clang/lib/AST/Expr.cpp| 22 ++ clang/lib/AST/TextNodeDumper.cpp | 5 ++ clang/lib/CodeGen/CGExprScalar.cpp| 2 + .../Frontend/Rewrite/RewriteModernObjC.cpp| 7 +- clang/lib/Frontend/Rewrite/RewriteObjC.cpp| 13 ++-- clang/lib/Sema/SemaExpr.cpp | 6 +- clang/lib/Sema/SemaOpenMP.cpp | 12 ++-- clang/lib/Serialization/ASTReaderStmt.cpp | 8 ++- clang/lib/Serialization/ASTWriterStmt.cpp | 3 + clang/test/AST/conditional-operator.c | 21 ++ clang/test/CodeGen/conditional-operator.c | 36 ++ 15 files changed, 193 insertions(+), 27 deletions(-) create mode 100644 clang/test/AST/conditional-operator.c create mode 100644 clang/test/CodeGen/conditional-operator.c diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7bacf028192c65..cc79496e809829 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4210,26 +4210,45 @@ class AbstractConditionalOperator : public Expr { /// ConditionalOperator - The ?: ternary operator. The GNU "missing /// middle" extension is a BinaryConditionalOperator. -class ConditionalOperator : public AbstractConditionalOperator { +class ConditionalOperator final +: public AbstractConditionalOperator, + llvm::TrailingObjects { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. friend class ASTStmtReader; -public: + ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, SourceLocation CLoc, Expr *rhs, QualType t, - ExprValueKind VK, ExprObjectKind OK) + ExprValueKind VK, ExprObjectKind OK, + FPOptionsOverride FPFeatures) : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc, CLoc) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; +ConditionalOperatorBits.HasFPFeatures = +FPFeatures.requiresTrailingStorage(); +if (hasStoredFPFeatures()) + setStoredFPFeatures(FPFeatures); setDependence(computeDependence(this)); } /// Build an empty conditional operator. - explicit ConditionalOperator(EmptyShell Empty) -: AbstractConditionalOperator(ConditionalOperatorClass, Empty) { } + ConditionalOperator(EmptyShell Empty, bool HasFPFeatures) + : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { +ConditionalOperatorBits.HasFPFeatures = HasFPFeatures; + } + +public: + static ConditionalOperator *CreateEmpty(const ASTContext &C, EmptyShell Empty, + bool HasFPFeatures); + + static ConditionalOperator *Create(const ASTContext &C, Expr *cond, + SourceLocation QLoc, Expr *lhs, + SourceLocation CLoc, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, + FPOptionsOverride FPFeatures); /// getCond - Return the expression representing the condition for /// the ?: operator. @@ -4265,6 +4284,44 @@ class ConditionalOperator : public AbstractConditionalOperator { const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } + + /// Is FPFeatures in trailing storage? + bool hasStoredFPFeatures() const { +return ConditionalOperatorBits.HasFPFeatures; + } + /// Get FPFeatures from trailing storage. + FPOptionsOverride getStoredFPFeatures() const { +return *getTrailingFPFeatures(); + } + + // Get the FP features status of this operator. Only meaningful for + // operations on floating point types. + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { +if (hasStoredFPFeatures()) + return
[clang] [clang] Allow `ConditionalOperator` fast-math flags to be overridden by `pragma float_control` (PR #105912)
echesakov wrote: > I made an alternative PR, which does not need changes in ConditionalOperator: > https://github.com/llvm/llvm-project/pull/111654. Thank you @spavloff , closing in favor of #111654 https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `ConditionalOperator` fast-math flags to be overridden by `pragma float_control` (PR #105912)
https://github.com/echesakov closed https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
https://github.com/echesakov updated https://github.com/llvm/llvm-project/pull/105912 >From 1231a5658bf7dde633e2d84967c6e540b3259e4b Mon Sep 17 00:00:00 2001 From: Egor Chesakov <5292656+echesa...@users.noreply.github.com> Date: Sat, 5 Oct 2024 12:22:27 -0700 Subject: [PATCH] [clang] Allow `ConditionalOperator` fast-math flags to be overridden by `pragma float_control` Currently, the fast-math flags set on `select` or `phi` instruction emitted by CodeGen when visiting `ConditionalOperator` take into account only global `FPOptions` and ignore `pragma float_control`. This involves storing `FPOptionsOverride` in trailing storage of `ConditionalOperator` and storing `CurFPOptionsOverride` when creating an AST node. Fixes #84648 --- clang/include/clang/AST/Expr.h| 67 +-- clang/include/clang/AST/Stmt.h| 11 +++ clang/include/clang/AST/TextNodeDumper.h | 1 + clang/lib/AST/ASTImporter.cpp | 6 +- clang/lib/AST/Expr.cpp| 22 ++ clang/lib/AST/TextNodeDumper.cpp | 5 ++ clang/lib/CodeGen/CGExprScalar.cpp| 2 + .../Frontend/Rewrite/RewriteModernObjC.cpp| 7 +- clang/lib/Frontend/Rewrite/RewriteObjC.cpp| 13 ++-- clang/lib/Sema/SemaExpr.cpp | 6 +- clang/lib/Sema/SemaOpenMP.cpp | 12 ++-- clang/lib/Serialization/ASTReaderStmt.cpp | 8 ++- clang/lib/Serialization/ASTWriterStmt.cpp | 3 + clang/test/AST/conditional-operator.c | 21 ++ clang/test/CodeGen/conditional-operator.c | 36 ++ 15 files changed, 193 insertions(+), 27 deletions(-) create mode 100644 clang/test/AST/conditional-operator.c create mode 100644 clang/test/CodeGen/conditional-operator.c diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7bacf028192c65..848c9676d5f11e 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4210,26 +4210,45 @@ class AbstractConditionalOperator : public Expr { /// ConditionalOperator - The ?: ternary operator. The GNU "missing /// middle" extension is a BinaryConditionalOperator. -class ConditionalOperator : public AbstractConditionalOperator { +class ConditionalOperator final +: public AbstractConditionalOperator, + private llvm::TrailingObjects { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. friend class ASTStmtReader; -public: + ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, SourceLocation CLoc, Expr *rhs, QualType t, - ExprValueKind VK, ExprObjectKind OK) + ExprValueKind VK, ExprObjectKind OK, + FPOptionsOverride FPFeatures) : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc, CLoc) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; +ConditionalOperatorBits.HasFPFeatures = +FPFeatures.requiresTrailingStorage(); +if (hasStoredFPFeatures()) + setStoredFPFeatures(FPFeatures); setDependence(computeDependence(this)); } /// Build an empty conditional operator. - explicit ConditionalOperator(EmptyShell Empty) -: AbstractConditionalOperator(ConditionalOperatorClass, Empty) { } + ConditionalOperator(EmptyShell Empty, bool HasFPFeatures) + : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { +ConditionalOperatorBits.HasFPFeatures = HasFPFeatures; + } + +public: + static ConditionalOperator *CreateEmpty(const ASTContext &C, EmptyShell Empty, + bool HasFPFeatures); + + static ConditionalOperator *Create(const ASTContext &C, Expr *cond, + SourceLocation QLoc, Expr *lhs, + SourceLocation CLoc, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, + FPOptionsOverride FPFeatures); /// getCond - Return the expression representing the condition for /// the ?: operator. @@ -4265,6 +4284,44 @@ class ConditionalOperator : public AbstractConditionalOperator { const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } + + /// Is FPFeatures in trailing storage? + bool hasStoredFPFeatures() const { +return ConditionalOperatorBits.HasFPFeatures; + } + /// Get FPFeatures from trailing storage. + FPOptionsOverride getStoredFPFeatures() const { +return *getTrailingFPFeatures(); + } + + // Get the FP features status of this operator. Only meaningful for + // operations on floating point types. + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { +if (hasStoredFPFeatures()) + return getStoredFPFeatures().applyOverrides(LO); +return FPOptions::defaul
[clang] [clang] Allow `ConditionalOperator` fast-math flags to be overridden by `pragma float_control` (PR #105912)
echesakov wrote: > Can you reword the description to have less wrapping @arsenm @zahiraam Updated the commit/PR and added more details on the issue. https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `ConditionalOperator` fast-math flags to be overridden by `pragma float_control` (PR #105912)
https://github.com/echesakov edited https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `ConditionalOperator` fast-math flags to be overridden by `pragma float_control` (PR #105912)
https://github.com/echesakov edited https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
@@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm -menable-no-infs -fapprox-func\ +// RUN: -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math\ +// RUN: -ffp-contract=fast -ffast-math %s -o - | FileCheck %s + +float test_precise_off_select(int c) { +#pragma float_control(precise, off) + return c ? 0.0f : 1.0f; +} + +// CHECK-LABEL: test_precise_off_select +// CHECK: select fast i1 {{%.+}}, float 0.00e+00, float 1.00e+00 + +float test_precise_off_phi(int c, float t, float f) { +#pragma float_control(precise, off) +return c ? t : f; +} + +// CHECK-LABEL: test_precise_off_phi +// CHECK: phi fast float [ {{%.+}}, {{%.+}} ], [ {{%.+}}, {{%.+}} ] + +float test_precise_on_select(int c) { +#pragma float_control(precise, on) +return c ? 0.0f : 1.0f; +} + +// CHECK-LABEL: test_precise_on_select +// CHECK: select i1 {{%.+}}, float 0.00e+00, float 1.00e+00 + +float test_precise_on_phi(int c, float t, float f) { +#pragma float_control(precise, on) + return c ? t : f; +} + echesakov wrote: For "vector case" do you mean something along the lines of ```c typedef float float2 __attribute__((ext_vector_type(2))); typedef int int2 __attribute__((ext_vector_type(2))); float2 foo(int2 c, float2 t, float2 f) { #pragma float_control(precise, off) return c ? t : f; } ``` In this case, the expression would be codegen-d to a sequence of bitwise operations and these are not affected by fast-math flags ```llvm ; Function Attrs: noinline nounwind optnone define <2 x float> @foo(<2 x i32> noundef %c, <2 x float> noundef %t, <2 x float> noundef %f) #0 { entry: %c.addr = alloca <2 x i32>, align 8 %t.addr = alloca <2 x float>, align 8 %f.addr = alloca <2 x float>, align 8 store <2 x i32> %c, ptr %c.addr, align 8 store <2 x float> %t, ptr %t.addr, align 8 store <2 x float> %f, ptr %f.addr, align 8 %0 = load <2 x i32>, ptr %c.addr, align 8 %1 = load <2 x float>, ptr %t.addr, align 8 %2 = load <2 x float>, ptr %f.addr, align 8 %3 = icmp slt <2 x i32> %0, zeroinitializer %sext = sext <2 x i1> %3 to <2 x i32> %4 = xor <2 x i32> %sext, %5 = bitcast <2 x float> %2 to <2 x i32> %6 = bitcast <2 x float> %1 to <2 x i32> %7 = and <2 x i32> %5, %4 %8 = and <2 x i32> %6, %sext %cond = or <2 x i32> %7, %8 %9 = bitcast <2 x i32> %cond to <2 x float> ret <2 x float> %9 } ``` Not really sure what I will be testing here? https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
@@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm -menable-no-infs -fapprox-func\ +// RUN: -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math\ +// RUN: -ffp-contract=fast -ffast-math %s -o - | FileCheck %s echesakov wrote: These flags correspond to how the clang driver `-ffast-math` are expanded to the individual flags passed to `-cc1`. Several tests (e.g. `clang/test/Parser/fp-floatcontrol-syntax.cpp` and `clang/test/CodeGen/math-errno.c`) use similar command lines for testing fast-path behavior and I was trying to be consistent with them. https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
https://github.com/echesakov updated https://github.com/llvm/llvm-project/pull/105912 >From 124a1c4c7c102421b74eaaa1133ea58a9017e07b Mon Sep 17 00:00:00 2001 From: Egor Chesakov <5292656+echesa...@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:44:14 -0700 Subject: [PATCH 1/2] [clang] Allow `pragma float_control(precise, *)` to... ...control `FastMathFlags` during code-generation of `ConditionalOperator`. This involves storing `FPOptionsOverride` in trailing storage of `ConditionalOperator` and storing `CurFPOptionsOverride` when creating an AST node. Fixes #84648 --- clang/include/clang/AST/Expr.h| 67 +-- clang/include/clang/AST/Stmt.h| 11 +++ clang/include/clang/AST/TextNodeDumper.h | 1 + clang/lib/AST/ASTImporter.cpp | 6 +- clang/lib/AST/Expr.cpp| 22 ++ clang/lib/AST/TextNodeDumper.cpp | 5 ++ clang/lib/CodeGen/CGExprScalar.cpp| 2 + .../Frontend/Rewrite/RewriteModernObjC.cpp| 7 +- clang/lib/Frontend/Rewrite/RewriteObjC.cpp| 13 ++-- clang/lib/Sema/SemaExpr.cpp | 6 +- clang/lib/Sema/SemaOpenMP.cpp | 12 ++-- clang/lib/Serialization/ASTReaderStmt.cpp | 8 ++- clang/lib/Serialization/ASTWriterStmt.cpp | 3 + clang/test/AST/conditional-operator.c | 21 ++ clang/test/CodeGen/conditional-operator.c | 36 ++ 15 files changed, 193 insertions(+), 27 deletions(-) create mode 100644 clang/test/AST/conditional-operator.c create mode 100644 clang/test/CodeGen/conditional-operator.c diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7bacf028192c65..cc79496e809829 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4210,26 +4210,45 @@ class AbstractConditionalOperator : public Expr { /// ConditionalOperator - The ?: ternary operator. The GNU "missing /// middle" extension is a BinaryConditionalOperator. -class ConditionalOperator : public AbstractConditionalOperator { +class ConditionalOperator final +: public AbstractConditionalOperator, + llvm::TrailingObjects { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. friend class ASTStmtReader; -public: + ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, SourceLocation CLoc, Expr *rhs, QualType t, - ExprValueKind VK, ExprObjectKind OK) + ExprValueKind VK, ExprObjectKind OK, + FPOptionsOverride FPFeatures) : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc, CLoc) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; +ConditionalOperatorBits.HasFPFeatures = +FPFeatures.requiresTrailingStorage(); +if (hasStoredFPFeatures()) + setStoredFPFeatures(FPFeatures); setDependence(computeDependence(this)); } /// Build an empty conditional operator. - explicit ConditionalOperator(EmptyShell Empty) -: AbstractConditionalOperator(ConditionalOperatorClass, Empty) { } + ConditionalOperator(EmptyShell Empty, bool HasFPFeatures) + : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { +ConditionalOperatorBits.HasFPFeatures = HasFPFeatures; + } + +public: + static ConditionalOperator *CreateEmpty(const ASTContext &C, EmptyShell Empty, + bool HasFPFeatures); + + static ConditionalOperator *Create(const ASTContext &C, Expr *cond, + SourceLocation QLoc, Expr *lhs, + SourceLocation CLoc, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, + FPOptionsOverride FPFeatures); /// getCond - Return the expression representing the condition for /// the ?: operator. @@ -4265,6 +4284,44 @@ class ConditionalOperator : public AbstractConditionalOperator { const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } + + /// Is FPFeatures in trailing storage? + bool hasStoredFPFeatures() const { +return ConditionalOperatorBits.HasFPFeatures; + } + /// Get FPFeatures from trailing storage. + FPOptionsOverride getStoredFPFeatures() const { +return *getTrailingFPFeatures(); + } + + // Get the FP features status of this operator. Only meaningful for + // operations on floating point types. + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { +if (hasStoredFPFeatures()) + return getStoredFPFeatures().applyOverrides(LO); +return FPOptions::defaultWithoutTrailingStorage(LO); + } + FPOptionsOverride getFPFeatures() const { +return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride(); + } + +
[clang] [clang] Allow `pragma float_control(precise, *)` to... (PR #105912)
echesakov wrote: > Not very clear to me what the issue is. Can you please explain this in the > description. I think here the `#pragma float_control(precise, on)` should be > taking precedence over the `-ffast-math` flag and it's not. Right? @zahiraam Correct, this is not happening right now and flags on codegen-d `select`/`phi` are not taking into account the pragma. https://github.com/llvm/llvm-project/pull/105912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits