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

    <tr>
        <th>Summary</th>
        <td>
            -Ofast partially overrides -ffp-model
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:driver
      </td>
    </tr>

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

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

<pre>
    When the -Ofast option is specified along with the -ffp-model=<> option, the -Ofast option partially overrides the -ffp-model option, regardless of the order of the options. I'm not sure what the original intention was, but the current state is obviously not what was intended.

For example:
```
float foo(float x, float y, float z) {
  return x * y + z;
}
```
Compiled with "-Ofast -ffp-model=strict" produces
```
define float @foo(float %x, float %y, float %z) {
entry:
  %0 = tail call float @llvm.fmuladd.f32(float %x, float %y, float %z)
  ret float %0
}
```
This is unexpected because -ffp-model=strict shouldn't allow contraction at all, and -Ofast would result in separate fmul and fadd instructions with the `fast` flag set.

Compiled with "-O3 -ffp-model=strict" the code above produces
```
define float @foo(float %x, float %y, float %z) {
entry:  %mul = tail call float @llvm.experimental.constrained.fmul.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.strict")
  %add = tail call float @llvm.experimental.constrained.fadd.f32(float %mul, float %z, metadata !"round.dynamic", metadata !"fpexcept.strict")
  ret float %add
}
```
This is what you'd expect with -ffp-model=strict being honored.

Compiled with "-ffp-model=strict -Ofast" it produces
```
define float @foo(float %x, float %y, float %z) {
entry:
  %mul = fmul fast float %y, %x
  %add = fadd fast float %mul, %z
  ret float %add
}
```
This is what you'd expect with -Ofast taking precedence.

https://godbolt.org/z/739W871cT

It seems to have been like this since the introduction of the -ffp-model option, but I couldn't find comments in the review where -ffp-model was introduced that would explain why it was done this way. The driver code in RenderFloatingPointOptions() sets a bunch of local variables for any -ffp-model option to more or less initialize things to the -ffp-model=precise state, then it checks for -Ofast and breaks out of the handler for anything other than "fast" with a warning saying that "-Ofast" overrides the -ffp-model option, but it has already changed a lot of things to the -ffp-model=precise state.

I'm not sure why we would have wanted -Ofast to override -ffp-model regardless of position, but we didn't achieve it.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEVk1v4zYQ_TX0ZRBBpiI7Pviwu6mBPW1RLLDnETmS2FCkQFJWlF9fkJJjO3EXadEPIIglezicee_NB3qvGkO0Z-VnVj6ucAitdXs0cnrCSVu3qqyc9j9aMhBagrtvNfoAtg_KGlAefE9C1YokoLamgVGFdras6_6us5I0Kx5Z8YUVvyzHGP9yw1ePLijUegJ7JOeUJP_Gz8VxRw06qcl7sHUys06Se31Jhj6Dr4xvOzA2gB8cwdhiWKxVowxqUCaQSfeP6KPnapgtxOAcmQA-YKCYqK2Oyg5eT8ld8jSinx1IkhnLH1n-af5_sA7oGbteEyuW79gmX_7Sa60tBqitZfxhfn6O18-P0_nxhfEdsO3n-RSAozA4A8_A-CeYgPHP8MKK5We2fbx52Rfb9UqTnNlhnC_QX3Hkg1MiMM6hd1YOgvxNX5JqZWiJjt3nlykwXl5kwXg5Xb1d50ImuOkVHogGObDiEQIqDQK1Pl-i9bHL6m7QKGVWF_yv3HiB3PmH_OeAfW-Vj6QPhp57EoEkVCRw8HQLM_CtHbQ0jG8DoNZ2BGFNcCiSsjB9GeNCI0-qH-MJcOQHHUAZ8NSji1KLWSbDGqUEZXxwQ_Ljz7XFNnl0wjY51Bob8BSu9HeD7-LPyE5it5IAK3uk_5j7xHpM-Ge8Rwqc6sgE1JmwERFUhmQSxAfU0FFAiQGB8TXj3NnByExOBjslGOc3TOqengX1IXuF6UJHjJeRmb8X8Q39doN-i9Q_HvOV9lHKj6k_NbnJDoxvJcyFMCvqVg1UpEwDrTXWvemG79V44_hcFlGQKvx_DegkxVSEqU6vPSX_73WQSvXafGE1XfovkTA3koBPEfjekSBJRtAV9m0IvY858gPjh8bKyuqQWdcwfnhh_LAtdj8etmvx_fLQ1wCeqPMQLLR4JKiIDGj1RBBiVF4ZQalxKBMSVanPLcP35sCOY_UriHObrJWRIGwXiyRO0XTU0VHRCGNL7srPMmhnVUgIafimBkrPvUZlYGynKJxoKK1Z4hxxyuB7SyCdOpKb25wy8Fuc2O4QqVCm-dUqE77NGwPjD1EinoIHhGowoo1paStQwxGdwkqTh9o6QDO9TzUi1lkXFwxI24kyKm416iWFZJqE6bv1KJKnPM3LxrIemZiPaEk8zfctdMfJUDnCJw92CCfMWzRSkzsFlq4CG1pyESwTi-5UXkk7CCM6E408TvEjQfq6GES7D2xhkVQVoEUPqB2hnEC0aJq4DIK2S3Qfy_pKte_WtglGWhhPghzRxJl8KgH7Gu1loNdLYm-9ugx8JJDqNLNFq-hIoEK2kvtC7oodrmi_3q7LvODFtly1e1E9CLmraMPz4l7KIq8eqg3RWj7cr3dIu5Xa85zf52W-4euSl2VW1TWiFEW9W-dE_J7d59Sh0lmaEdY1K-X9QPvdmm83K40VaZ_2cM6FRtOw4tMs3NjLy8eV28eDd9XQ-DholA_-7CqooGm_AHJrlz4Dsxqc3r9pDCq0Q5UJ2zF-iD6Xj7ve2d8pTpNDitUzfkjh_hEAAP__ivPv2Q">