[llvm] [Inline] Propagate FMFs from calls to inlined instructions. (PR #145537)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 24 12:51:49 PDT 2025


fhahn wrote:

> I agree with @nikic on the limitations of applying fast-math flags to calls. In fact, I think it would be reasonable to state outright that fast-math flags can't be applied transitively to defined functions. Consider this situation:
> 
> ```
> float foo(float a, float b, float c) {
>   #pragma STDC FP_CONTRACT OFF
>   return a * b + c;
> }
> 
> float bar(float a, float b, float c) {
>   return foo(a, b, c);
> }
> ```
> 
> Here a pragma has been used to disallow `contract` on the definition of `foo`, but currently clang sets the `contract` flag on the call to `foo` in `bar`. This call is going to be inlined, but that should not re-enable `contract` on the inlined operations.
> 
> We should probably update clang to stop setting the fast-math flags on non-intrinsic calls, but I don't think we should try to apply them if they are present. The `nofpclass` attribute covers the effects of the poison-inducing flags, and those flags can be applied during inlining based on the `nofpclass` attribute settings, but the rewrite flags should not be applied.

Ah thanks for the example. I guess the problem is that we cannot distinguish why flags are not present, i.e. they could be explicitly disabled... 

Although I find it suprising that in the converse case, we can end up with contracted ops?
```
 float foo(float a, float b, float c) {
   return a * b + c;
 }
 
 float bar(float a, float b, float c) {
   #pragma STDC FP_CONTRACT OFF
   return foo(a, b, c);
 }
```

Any thoughts on how we could model things in Clang to get something like below working, as in propagating the flags through inlining? Maybe another pragma that instead adds `nofpclass`? Currently `  #pragma clang fp reassociate(on)` doesn't compose nicely with things like C++ templated libraries.

```
float do_add(float A, float B) { return A + B; }

float red1(float *A, float *B, unsigned N) {
float sum = 0;
  for (unsigned I = 0; I != N; ++I) {
    #pragma clang fp reassociate(on)
    sum = do_add(sum, A[I]);
  }
return sum;
}
```

https://github.com/llvm/llvm-project/pull/145537


More information about the llvm-commits mailing list