<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/56483>56483</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Reassociation is needlessly suppressed when unrelated FastMathFlags are off
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          wjristow
      </td>
    </tr>
</table>

<pre>
    Reassociation enabled with `-ffast-math` only remains enabled when _all_ the FastMathFlags (FMF) remain on.  Here is a simple C++ program that dmonstrates it:

```
bool foo(float a, float b, float c) {
  float d = a + b + c;
  float e = c + a + b;
  return d == e;
}
```

Compiling the above with `-O2 -ffast-math` results in code that overtly returns `true`, as expected/desired:

```
$ clang++ -S -o - -emit-llvm -O2 -ffast-math test.cpp
    ...
entry:
  ret i1 true
    ...
$
```

Compiling with simply `-O2` results in code containing 4 additions and a comparison, which will sometimes return `true` and sometimes `false` (again, as expected/desired).

The problem is that when an unrelated FMF is turned off, then the reassociation is suppressed, and the additions and comparison are again generated.  For example, disabling the reciprocal transformation suppresses the reassociation and resulting optimization:

```
$ clang++ -S -o - -emit-llvm -O2 -ffast-math -fno-reciprocal-math test.cpp
    ...
entry:
  %add = fadd reassoc nnan ninf nsz contract afn float %a, %b
  %add1 = fadd reassoc nnan ninf nsz contract afn float %add, %c
  %add2 = fadd reassoc nnan ninf nsz contract afn float %a, %c
  %add3 = fadd reassoc nnan ninf nsz contract afn float %add2, %b
  %cmp = fcmp reassoc nnan ninf nsz contract afn oeq float %add1, %add3
  ret i1 %cmp
    ...
$
```

There aren't any divisions in the test-case, so suppressing the reciprocal transformation shouldn't impact the generated code.  (Reassoication requires the `reassoc` and `nsz` FastMathFlags to be on, so the reassociation/optimization should be done in the above example.)

To be explicit, it isn't a problem with `-fno-reciprocal-math` -- setting other FMF to values other than their "plain `fast` versions" also suppresses the optimization.  As an example, the 'fast' setting of FMA is `-ffp-contract=fast`, and changing it to `-ffp-contract=on`, has the equivalent problem of needlessly suppressing the optimization:

```
$ clang++ -S -o - -emit-llvm -O2 -ffast-math -ffp-contract=on test.cpp
    ...
entry:
  %add = fadd reassoc nnan ninf nsz arcp afn float %a, %b
  %add1 = fadd reassoc nnan ninf nsz arcp afn float %add, %c
  %add2 = fadd reassoc nnan ninf nsz arcp afn float %a, %c
  %add3 = fadd reassoc nnan ninf nsz arcp afn float %add2, %b
  %cmp = fcmp reassoc nnan ninf nsz arcp afn oeq float %add1, %add3
  ret i1 %cmp
    ...
$
```

I have a patch that I'll post shortly, to fix this.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy1V11v4ygU_TXOy5WtlDhJ85CHTqto52G00u6-jzDGCSMMHsDtdH79HrDz2cyq7XakKIEA9x4O9xzjytbP678k994KxYOyhqThlZY1Pamwo2wxzZuG-5C3POzQI2v0MznZcmX8ce5OGvrKtf5KYSdpgwVfMH-j-dZTxm43XzYZW43LEKIg-kM6ScoTJ6_aTku6z9gnfKhzdut4i0A8UN1a44PjQXpSIZvdZdOHbLr_XkzHT-pW1mpqrEW-Rlss5hm7p6FZHZsiIsmWn4ZFNP5bUzZ7AJiIoErfIptdzJFpjkij48yTOU6G3pkhUJwnD2PZ8uEq4OH73rad0spsE3W8so_yyP2fjC74d9L3OoANQ8LWcqAJa1xI5xIx-Lg0uF7GTNg3x0H96KQIss7YppZeObT-k8uMlSQ0N9vxUPK_KbeUUy5bFXKtH1u6wEY4olCIrtvzQVQUxdCRJrjnQ8JEFakbShBfzkbuV9GVSErF8zxydY0fYU1A0cUFJfG6VrHIUXamxhkKBONOeWsiT087JXYIqzV528qgWlTdeKxHRtPS4zj-abj2aQSVx7dI9mvS2ao43cw_OHHUOzTURi2ks0xa4oZ646RG4dcE9aRR4EDPNk2MH-K0WDHuTL2Y5_uuAws-prtPaFNhnW39uHHi0GFCTVtpZJRaDXlurAN-HpUZo9TKQ-n7InVSKMAWXOMMufGNde2Q_pDbX8EWEw_HEwPZDgSqn2now4sxb4zNjzDfXKEZm4OwpPcmNsaNkDE4GRRTQ8b_TLXluIDTNGb0iLgwEobf6jzYzTuj1fUYT5zHY_8P3UW02bvRsSvbFW03xIuNV8Sz8vtZzJsxZgR2YRpD9DfbBpQW69xJiHOJpOYZNf2ofFKEGpQU6yMX3KeK9_ZQzK8o-53tdT2EhiHFbcUFB0ElKyoiNbfDw1aJYaGT33sYw6AWQB652tsMfsFV7J0_UoOlStLgWgD6QmpwnFN5jfjimtoaud_v8KwZVV7Am84ISylgYVoJPHmRSGFvfqTv4FrHW8JLwUXceU5ehkHwyOmSmQH-I9c9tj38B99LiJQDQ6zT0YySr_oQY-Dhls4JYwSrtZcuc7pVkHwXLe7UvBK3bJnCseURTwMwd9Exh1tOl-9rEqU75t47qADCbVwEEoD-ygKQPkzf8QFVPFnsEs5yIAsZjZS1BnQ8sy7L6zcb4iXcj7dD7kT3MVZ4JdK7bfDXqN5qgVdRvdP-DrF-v_V9RklC59AsD7jfpEvGZwgB15zO-hDNIV4ek1IsNeoHpihfTOr1rF7NVnwSVNDy4i0BqrlSyvtXgZO7y5lvxbsG7i-T3un1LoTOxxpjeDfYbOEjfVXgXoJOrODxJ4d2vuEWha7yHpaBxnxR3s4mu3U5Y3VTL0rR8LKacTYv2Wq6nE5ZyWUlFsuJ5pXUfp3NoRJm5BOlEGhn84eJWrMpY9PlzQ1jrCxXRclXnMllJcu5mC3n86ycxvcVXUQchXXbiVsnSFW_9RjUygd_HAQ7agtOUjrE530Aseunb7hmBfs0SbnXCfu_P0s_IQ">