Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang] Set correct FPOptions if attribute 'optnone' presents #85605

Merged
merged 4 commits into from Apr 23, 2024

Conversation

spavloff
Copy link
Collaborator

Attribute optnone must turn off all optimizations including fast-math ones. Actually AST nodes in the 'optnone' function still had fast-math flags. This change implements fixing FP options before function body is parsed.

@spavloff spavloff self-assigned this Mar 18, 2024
@spavloff spavloff requested a review from Endilll as a code owner March 18, 2024 06:57
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Mar 18, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 18, 2024

@llvm/pr-subscribers-clang

Author: Serge Pavlov (spavloff)

Changes

Attribute optnone must turn off all optimizations including fast-math ones. Actually AST nodes in the 'optnone' function still had fast-math flags. This change implements fixing FP options before function body is parsed.


Full diff: https://github.com/llvm/llvm-project/pull/85605.diff

5 Files Affected:

  • (modified) clang/include/clang/Basic/LangOptions.h (+11)
  • (modified) clang/include/clang/Sema/Sema.h (+1)
  • (modified) clang/lib/Parse/ParseStmt.cpp (+4)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+10)
  • (modified) clang/test/AST/ast-dump-fpfeatures.cpp (+11)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 08fc706e3cbf74..19c60a8cb5e946 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -842,6 +842,8 @@ class FPOptions {
   /// Return difference with the given option set.
   FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
 
+  void applyChanges(FPOptionsOverride FPO);
+
   // We can define most of the accessors automatically:
 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
   TYPE get##NAME() const {                                                     \
@@ -923,6 +925,11 @@ class FPOptionsOverride {
       setAllowFPContractAcrossStatement();
   }
 
+  void setDisallowOptimizations() {
+    setFPPreciseEnabled(true);
+    setDisallowFPContract();
+  }
+
   storage_type getAsOpaqueInt() const {
     return (static_cast<storage_type>(Options.getAsOpaqueInt())
             << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const
   return getChangesSlow(Base);
 }
 
+inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
+  *this = FPO.applyOverrides(*this);
+}
+
 /// Describes the kind of translation unit being processed.
 enum TranslationUnitKind {
   /// The translation unit is a complete translation unit.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 95ea5ebc7f1ac1..ccc2ded67589ec 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3222,6 +3222,7 @@ class Sema final {
   Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
                                 SkipBodyInfo *SkipBody = nullptr,
                                 FnBodyKind BodyKind = FnBodyKind::Other);
+  void applyFunctionAttributesBeforeParsingBody(Decl *FD);
 
   /// Determine whether we can delay parsing the body of a function or
   /// function template until it is used, assuming we don't care about emitting
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 76a3fa8f2627de..489ae9f167b95d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
   Sema::PragmaStackSentinelRAII
     PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);
 
+  // Some function attributes (like OptimizeNoneAttr) affect FP options.
+  Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
+  Actions.applyFunctionAttributesBeforeParsingBody(Decl);
+
   // Do not enter a scope for the brace, as the arguments are in the same scope
   // (the function body) as the body itself.  Instead, just read the statement
   // list and put it into a CompoundStmt for safe keeping.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9aa..59c327515dba70 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
   return D;
 }
 
+void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
+  if (FD->hasAttr<OptimizeNoneAttr>()) {
+    FPOptionsOverride FPO;
+    FPO.setDisallowOptimizations();
+    CurFPFeatures.applyChanges(FPO);
+    FpPragmaStack.CurrentValue =
+        CurFPFeatures.getChangesFrom(FPOptions(LangOpts));
+  }
+}
+
 /// Given the set of return statements within a function body,
 /// compute the variables that are subject to the named return value
 /// optimization.
diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp
index da0011602a728e..f6e9d3637417e6 100644
--- a/clang/test/AST/ast-dump-fpfeatures.cpp
+++ b/clang/test/AST/ast-dump-fpfeatures.cpp
@@ -187,3 +187,14 @@ float func_18(float x, float y) {
 // CHECK:         CompoundStmt {{.*}} ConstRoundingMode=downward
 // CHECK:           ReturnStmt
 // CHECK:             BinaryOperator {{.*}} ConstRoundingMode=downward
+
+#pragma float_control(precise, off)
+__attribute__((optnone))
+float func_19(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_19 'float (float, float)'
+// CHECK:         CompoundStmt {{.*}} MathErrno=1
+// CHECK:           ReturnStmt
+// CHECK:             BinaryOperator {{.*}} 'float' '+' MathErrno=1

@rjmccall
Copy link
Contributor

Hmm. Is there some sort of optimization in IRGen that we need to suppress here, or is it something in LLVM code gen? Presumably normal LLVM optimization passes all just skip optnone functions.

Mostly I'm wondering how far we're expected to go with optnone.

@spavloff
Copy link
Collaborator Author

Hmm. Is there some sort of optimization in IRGen that we need to suppress here, or is it something in LLVM code gen? Presumably normal LLVM optimization passes all just skip optnone functions.

The issue #62098 demonstrates such case. Anyway, It is not good to have bogus attributes in AST.

Mostly I'm wondering how far we're expected to go with optnone.

It impedes implementation of pragma FENV_ROUND. The pragma requires setting FP options inside CompoundStmt and it interacts with the fictious attributes. This is the reason of this patch.

@rjmccall
Copy link
Contributor

Hmm. Is there some sort of optimization in IRGen that we need to suppress here, or is it something in LLVM code gen? Presumably normal LLVM optimization passes all just skip optnone functions.

The issue #62098 demonstrates such case.

Okay. So if I understand correctly, this substitution of libcalls is a frontend optimization, and the bug is arguing that it ought to be suppressed by optnone.

Anyway, It is not good to have bogus attributes in AST.

I think it's a fair question whether this is a bogus attribute. optnone is a very strange attribute; it's a directive to the compiler with no clear semantics. There are "optimizations" that I don't think we expect optnone to suppress — we wouldn't want optnone to turn off NRVO in C++, for example. optnone seems to be about getting a straightforward, literal translation of the code. If the frontend can do a transformation during IR emission, though, it's generally a highly reliable transformation and can basically be thought of as part of the semantics.

From the bug, it sounds more like the user wants some way to disable fast-math for a specific function, and apparently we don't have one. That seems like a reasonable feature request. Because we don't have that feature, they're flailing around trying essentially every pragma and attribute that we do have and arguing that at least one of them ought to have that impact, but it's not at all clear to me that they should. And presumably they don't actually want to disable all optimization of their function anyway; they just want to turn off fast math.

Mostly I'm wondering how far we're expected to go with optnone.

It impedes implementation of pragma FENV_ROUND. The pragma requires setting FP options inside CompoundStmt and it interacts with the fictious attributes. This is the reason of this patch.

That doesn't make sense as a reason for this patch; #pragma FENV_ROUND can obviously occur in non-optnone functions.

@zahiraam
Copy link
Contributor

I have uploaded your patch and compared the attributes generated from your patch and the little test case from #62098. The attributes generated are different. Therefore, the expected optimizations from this patch are going to be different than what we currently have. I think that's a problem.

Attributes with this patch (only the ones that differ):

attributes #0 = { "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "unsafe-fp-math"="false" }

and without the patch:
attributes #0 = { "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "unsafe-fp-math"="true" }

@spavloff
Copy link
Collaborator Author

optnone is a very strange attribute; it's a directive to the compiler with no clear semantics.

fast-math also does not have clear semantics. It is however used to express user's expectations that some assumptions are valid. optnone could also be treated from similar viewpoint. It is very convenient for a user to have a "big switch" that would turn off "all" things that can complicate code generation. Which transformations are optimizations that should be turned off by optnone - it depends on user expectations. Fast-math options are definitely in this list, - they are unsafe transformations aimed at performance.

And presumably they don't actually want to disable all optimization of their function anyway; they just want to turn off fast math.

They can use #pragma float_control(precise, on). However optnone, according to the documentation, is also a legitimate way to turn off fast math.

I have uploaded your patch and compared the attributes generated from your patch and the little test case from #62098. The attributes generated are different. Therefore, the expected optimizations from this patch are going to be different than what we currently have. I think that's a problem.

Exactly. User specifies attribute optnone but the functions has attribute "no-infs-fp-math"="true", which is unsafe optimization. Even if this function is not transformed in IR pipeline, the attribute can cause CodeGen to emit code as if fast-math is in effect. Such behavior contradicts the meaning of optnone described in documenttion.

@spavloff spavloff marked this pull request as ready for review March 19, 2024 15:34
Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. I don't really have a problem with doing this, and this seems like basically the right approach. You're applying the attributes in the wrong place, though.

@@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
Sema::PragmaStackSentinelRAII
PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);

// Some function attributes (like OptimizeNoneAttr) affect FP options.
Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
Actions.applyFunctionAttributesBeforeParsingBody(Decl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attributes should cover the entire function body, so you're also going to need to do this before parsing function-try-blocks and constructor initializers. That probably just means pushing it a level up across the board.

@@ -1495,6 +1495,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
return Actions.ActOnFinishFunctionBody(Res, nullptr, false);
}

// Some function attributes (like OptimizeNoneAttr) affect FP options.
Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
Actions.applyFunctionAttributesBeforeParsingBody(Res);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. There are actually a lot of paths that call into ParseFunctionStatementBody like this. Rather than changing all of them, can we just do this in ActOnStartOfFunctionDef / ActOnFinishFunctionBody? We do a lot of similar context push/pop operations there already.

Please test an inline C++ method (which are delayed and use a different path) and ObjC method parsing (which also use a different path).

Copy link
Contributor

@Endilll Endilll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sema.h changes look good to me.

Copy link

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link

✅ With the latest revision this PR passed the Python code formatter.

Attribute `optnone` must turn off all optimizations including fast-math
ones. Actually AST nodes in the 'optnone' function still had fast-math
flags. This change implements fixing FP options before function body is
parsed.
@spavloff
Copy link
Collaborator Author

Ping.

@spavloff
Copy link
Collaborator Author

A little about the significance of this fix. To implement pragma FENV_ROUND, we need to apply the FP options stored in the instance of CompoundStmt to the builder object, so that it uses the specified rounding mode. It can be done using the class CGFPOptionsRAII. However in this case a couple of issues rise, both related to fast-math. This patch is intended to fix one of them an is a prerequisite for pragma FENV_ROUND implementation.

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine. Is there any existing bookkeeping we no longer need to do if we're going to have this RAII object in scope during function parsing?

@spavloff spavloff merged commit a046242 into llvm:main Apr 23, 2024
4 checks passed
@spavloff spavloff deleted the noopt branch April 23, 2024 07:14
@spavloff
Copy link
Collaborator Author

Thanks!

Is there any existing bookkeeping we no longer need to do if we're going to have this RAII object in scope during function parsing?

It seems handling fast-math is the only case that prevented using this RAII object.

@dyung
Copy link
Collaborator

dyung commented Apr 25, 2024

Hi, we have an internal test that checks that compiling with and without optnone at O0 does not change the code generated by the compiler, and one of the tests we have did change which I bisected back to your change.

The test consists of the following code:

#include <math.h>

extern int printf(const char *format, ...);

template <typename T> OPTNONE T &pi(int num_terms) {
  static T approx = 0;

  for (int i = 0; i <= num_terms; ++i) {
    approx += 4 * (pow(-1, i) / ((2 * i) + 1));
  }

  return approx;
}

OPTNONE
int main() {
  int const num_terms = 5;

  float f1000 = pi<float>(num_terms);

  printf("%f\n", f1000);

  return 0;
}

When compiled with -S -O0 -mavx -DOPTNONE= part of the function pi(int) looks like this:

        vcvtsi2sd       xmm1, xmm1, eax
        vdivsd  xmm0, xmm0, xmm1
        vmovss  xmm2, dword ptr [rip + pi<float>(int)::approx] # xmm2 = mem[0],zero,zero,zero
        vcvtss2sd       xmm1, xmm1, xmm2
        vmovsd  xmm2, qword ptr [rip + .LCPI1_0] # xmm2 = [4.0E+0,0.0E+0]
        vmulsd  xmm0, xmm0, xmm2
        vaddsd  xmm1, xmm0, xmm1
        vcvtsd2ss       xmm0, xmm0, xmm1
        vmovss  dword ptr [rip + pi<float>(int)::approx], xmm0

When compiled with -S -O0 -mavx -DOPTNONE=__attribute__((optnone)), the same code for pi(int) is slightly different:

        vcvtsi2sd       xmm1, xmm1, eax
        vdivsd  xmm1, xmm0, xmm1
        vmovsd  xmm0, qword ptr [rip + .LCPI1_0] # xmm0 = [4.0E+0,0.0E+0]
        vmulsd  xmm1, xmm0, xmm1
        vmovss  xmm2, dword ptr [rip + pi<float>(int)::approx] # xmm2 = mem[0],zero,zero,zero
        vcvtss2sd       xmm0, xmm0, xmm2
        vaddsd  xmm1, xmm0, xmm1
        vcvtsd2ss       xmm0, xmm0, xmm1
        vmovss  dword ptr [rip + pi<float>(int)::approx], xmm0

You can see this change on godbolt here: https://godbolt.org/z/WTWPoqY51

Is this change intended?

@spavloff
Copy link
Collaborator Author

Hi @dyung.

The observed difference is due to the FP contraction turned off if optnone is specified. In O0 this optimization is still applied. As a result, the function with optnone contains separate fadd and fmul, while without this attribute the function contains combined operatin fmuladd.

This optimization is turned off in FPOption.setDisallowOptimizations (introduced by this patch) by the call setDisallowFPContract(). If it is removed, I think, the output would be identical.

@dyung
Copy link
Collaborator

dyung commented Apr 25, 2024

Hi @dyung.

The observed difference is due to the FP contraction turned off if optnone is specified. In O0 this optimization is still applied. As a result, the function with optnone contains separate fadd and fmul, while without this attribute the function contains combined operatin fmuladd.

This optimization is turned off in FPOption.setDisallowOptimizations (introduced by this patch) by the call setDisallowFPContract(). If it is removed, I think, the output would be identical.

Thanks @spavloff. I can confirm that if I remove the call you mentioned the assembly generated is identical.

I am slightly confused why we are running FP contraction at O0. I would have thought no optimization at all be done at O0?

@pogo59
Copy link
Collaborator

pogo59 commented Apr 26, 2024

optnone is a very strange attribute; it's a directive to the compiler with no clear semantics.

In an ideal world, an optnone function would be compiled as-if the entire compilation unit had -O0. At -O0, Clang attaches optnone to every function, implying that this equivalence is the exact intent. Clang does this so that -O0 -flto will not lose the -O0 semantic during LTO.

When we devised optnone, there was an argument that this goal was not practical, and so the description could not imply that it was in fact equivalent to -O0. Thus, the description is fuzzy. Perhaps that was a mistake, and we should revise the description to include the goal, even if the goal is not 100% attainable.

With that goal in mind, having optnone and -O0 be deliberately different here makes no sense.

@wjristow
Copy link
Collaborator

wjristow commented May 2, 2024

Hi @spavloff.

Regarding:

With that goal in mind, having optnone and -O0 be deliberately different here makes no sense.

There's no need for them to behave differently here. And in fact, we want them to behave the same. There's a subtle point about FP contraction, in that doing an FP contraction (within a statement in C/C++) isn't considered an "optimization". It's a bit counterintuitive, but there's a good reason.

A Fused Multiply Add (FMA) will, in general, produce a slightly different bit-wise floating point result than a multiply/add sequence. For architectures that have FMA instructions, if we enabled FMA at (for example) -O2 but not at lower optimizations, then our -O0 and -O2 FP results would generally not be bit-wise identical. And we don't want that. Essentially, we have a requirement that "safe" optimizations like -O2 (as opposed to "unsafe" optimizations like -ffast-math) should not change the results of correct programs. So if FMA is to be enabled at -O2, we must also enable it at -O0.

The legal values and semantics in C/C++ for -ffp-contract=<value> are:

-ffp-contract=off       Never use FMA
-ffp-contract=on        Use FMA within a statement (default)
-ffp-contract=fast      Use FMA across multiple statements

See: https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffp-contract

(There is also one other legal setting: -ffp-contract=fast-honor-pragmas, but it's not relevant to the issue here.)

So setting -ffp-contract=off isn't setting it to the -O0 value, and setting it to the -O0 value is what we want.

To put it another way, for a target that has FMA instructions, a valid program will produce identical results for -O0, -O1 and -O2 (as desired), but with the change of this commit, applying the attribute optnone can now produce slightly different floating point results.

As you said earlier:

The observed difference is due to the FP contraction turned off if optnone is specified. In O0 this optimization is still applied. As a result, the function with optnone contains separate fadd and fmul, while without this attribute the function contains combined operatin fmuladd.

In short, optnone shouldn't set -ffp-contract=off, it should set -ffp-contract=on. Which, as I'm sure you realize, can be done via:

diff --git clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/LangOptions.h
index e2a2aa71b880..a5a7b3895d58 100644
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -970,7 +970,7 @@ public:

   void setDisallowOptimizations() {
     setFPPreciseEnabled(true);
-    setDisallowFPContract();
+    setAllowFPContractWithinStatement();
   }

   storage_type getAsOpaqueInt() const {

@wjristow
Copy link
Collaborator

wjristow commented May 3, 2024

Hi @spavloff.

Given my post above was fairly long, I want to make a short, clarifying comment. There was a sense in the earlier discussion that there is a problem in that the spec of optnone is imprecise (and that's causing the behavior difference). A lack of precision of the spec isn't the problem here. The problem is that the commit a046242 creates a situation where applying the optnone attribute can result in a change in the computation of floating point values. Here is a simple test-case:

#if defined(USE_OPTNONE)
__attribute__((optnone))
#endif
float foo(float a, float b, float c) {
  return (a * b) + c;
}

For -march=haswell (which has FMA hardware), when compiling this at -O0, the generated code will include:

vfmadd213ss     xmm0, xmm1, xmm2 

but if optnone is applied (compiling with -DUSE_OPTNONE), then the generated code will instead include:

vmulss  xmm0, xmm0, dword ptr [rbp - 8]
vaddss  xmm0, xmm0, dword ptr [rbp - 12]

That will, in general, produce a slightly different result. Both results are correct/legal according to the IEEE Standard. But regardless, we don't want applying optnone to change the values of floating-point computations. So that should be fixed.

Here is a godbolt link illustrating: https://godbolt.org/z/abfz41f9W

spavloff added a commit to spavloff/llvm-project that referenced this pull request May 4, 2024
Previously treatment of the attribute `optnone` was modified in
llvm#85605 ([clang] Set correct
FPOptions if attribute 'optnone' presents). As a side effect FPContract
was disabled for optnone. It created unneeded divergence with the
behavior of -O0, which enables this optimization.

In the discussion
llvm#85605 (comment)
it was pointed out that FP contraction should be enabled even if all
optimizations are turned off, otherwise results of calculations would be
different. This change enables FPContract at optnone.
@spavloff
Copy link
Collaborator Author

spavloff commented May 4, 2024

Hi @wjristow,

Thank you for your detailed analysis. Indeed, FPContract looks more like mandatory option rather than optional optimization. I prepared PR: #91061, which fixes this issue.

spavloff added a commit that referenced this pull request May 6, 2024
Previously treatment of the attribute `optnone` was modified in
#85605 ([clang] Set correct
FPOptions if attribute 'optnone' presents). As a side effect FPContract
was disabled for optnone. It created unneeded divergence with the
behavior of -O0, which enables this optimization.

In the discussion
#85605 (comment)
it was pointed out that FP contraction should be enabled even if all
optimizations are turned off, otherwise results of calculations would be
different. This change enables FPContract at optnone.
@SLTozer
Copy link
Contributor

SLTozer commented May 10, 2024

It looks like this is causing crashes when including precompiled headers that contain optnone functions; this can be reproduced with a very short header file and any source file, even a completely empty one. Reproducer follows:

$ cat header.h
__attribute__((optnone)) void foo() {}
$ cat src.cpp
// Empty file
$ ./build/bin/clang -x c++-header header.h -o header.pch
$ ./build/bin/clang -c -include-pch header.pch src.cpp
clang: /home/gbtozers/dev/upstream-llvm/clang/lib/Serialization/ASTReader.cpp:8316: void clang::ASTReader::UpdateSema(): Assertion `*FpPragmaCurrentValue == SemaObj->FpPragmaStack.DefaultValue && "Expected a default pragma float_control value"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: ./build/bin/clang -c -include-pch header.pch src.cpp
1.      <eof> parser at end of file
 #0 0x000055db95a49978 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (./build/bin/clang+0x7aa2978)
 #1 0x000055db95a474ce llvm::sys::RunSignalHandlers() (./build/bin/clang+0x7aa04ce)
 #2 0x000055db959ae1a6 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f1c0f348520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007f1c0f39c9fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007f1c0f39c9fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007f1c0f39c9fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007f1c0f348476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007f1c0f32e7f3 abort ./stdlib/abort.c:81:7
 #9 0x00007f1c0f32e71b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007f1c0f33fe96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x000055db967f68db clang::ASTReader::UpdateSema() (./build/bin/clang+0x884f8db)
#12 0x000055db980be50c clang::Sema::Initialize() (./build/bin/clang+0xa11750c)
#13 0x000055db97f7a4e3 clang::Parser::Initialize() (./build/bin/clang+0x9fd34e3)
#14 0x000055db97f75373 clang::ParseAST(clang::Sema&, bool, bool) (./build/bin/clang+0x9fce373)
#15 0x000055db966b20cf clang::FrontendAction::Execute() (./build/bin/clang+0x870b0cf)
#16 0x000055db966212cd clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (./build/bin/clang+0x867a2cd)
#17 0x000055db9679971e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (./build/bin/clang+0x87f271e)
#18 0x000055db933468bc cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (./build/bin/clang+0x539f8bc)
#19 0x000055db9334325d ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#20 0x000055db96467159 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
#21 0x000055db959adee6 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (./build/bin/clang+0x7a06ee6)
#22 0x000055db96466892 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (./build/bin/clang+0x84bf892)
#23 0x000055db9641e954 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (./build/bin/clang+0x8477954)
#24 0x000055db9641ee87 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (./build/bin/clang+0x8477e87)
#25 0x000055db9643fcb8 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (./build/bin/clang+0x8498cb8)
#26 0x000055db93342790 clang_main(int, char**, llvm::ToolContext const&) (./build/bin/clang+0x539b790)
#27 0x000055db93353047 main (./build/bin/clang+0x53ac047)
#28 0x00007f1c0f32fd90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#29 0x00007f1c0f32fe40 call_init ./csu/../csu/libc-start.c:128:20
#30 0x00007f1c0f32fe40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#31 0x000055db93340c25 _start (./build/bin/clang+0x5399c25)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 19.0.0git (https://github.com/llvm/llvm-project.git a04624206ddf03dc54d5c372e7eac13575b4124b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/gbtozers/dev/upstream-llvm/build/bin
Build config: +assertions
clang: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/src-520bcb.cpp
clang: note: diagnostic msg: /tmp/src-520bcb.sh
clang: note: diagnostic msg:

********************

@spavloff
Copy link
Collaborator Author

Hi @SLTozer,

Thank you for the report. There is an issue somewhere around the code that reads/wtites records FP_PRAGMA_OPTIONS and/or FLOAT_CONTROL_PRAGMA_OPTIONS, which sometimes manifest itseld in broken synchronization of FP options. I will prepare fix soon.

spavloff added a commit to spavloff/llvm-project that referenced this pull request May 14, 2024
After llvm#85605 ([clang] Set
correct FPOptions if attribute 'optnone' presents) the current FP options
in Sema are saved during parsing function because Sema can modify them if
optnone is present. However they were saved too late, it caused fails in
some cases when precompiled headers are used. This patch moves the
storing earlier.
@spavloff
Copy link
Collaborator Author

PR #92146 does not solve the problem of serialization mentioned above, but it is simple and quick solution for the reported crash.

spavloff added a commit that referenced this pull request May 15, 2024
After #85605 ([clang] Set
correct FPOptions if attribute 'optnone' presents) the current FP
options in Sema are saved during parsing function because Sema can
modify them if optnone is present. However they were saved too late, it
caused fails in some cases when precompiled headers are used. This patch
moves the storing earlier.
mub-at-arm pushed a commit to mub-at-arm/llvm-project that referenced this pull request May 16, 2024
After llvm#85605 ([clang] Set
correct FPOptions if attribute 'optnone' presents) the current FP
options in Sema are saved during parsing function because Sema can
modify them if optnone is present. However they were saved too late, it
caused fails in some cases when precompiled headers are used. This patch
moves the storing earlier.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants