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

    <tr>
        <th>Summary</th>
        <td>
            [flang] 1.5x performance regression on gas_dyn2
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            flang
      </td>
    </tr>

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

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

<pre>
    This reproduces on zen4 after https://github.com/llvm/llvm-project/pull/121544

After `InlineHLFIRAssign` we now have this in `chozdt_` routine:
```
  %23 = hlfir.minloc %19#0 {fastmath = #arith.fastmath<fast>} : (!fir.box<!fir.array<?xf32>>) -> !hlfir.expr<1xi32>
  fir.do_loop %arg6 = %c1 to %c1 step %c1 unordered {
 %55 = hlfir.apply %23, %arg6 : (!hlfir.expr<1xi32>, index) -> i32
    %56 = hlfir.designate %7#0 (%arg6)  : (!fir.ref<!fir.array<1xi32>>, index) -> !fir.ref<i32>
    hlfir.assign %55 to %56 : i32, !fir.ref<i32>
 }
```

The do-loop is the result of inlining of:
```
  hlfir.assign %23 to %7#0 : !hlfir.expr<1xi32>, !fir.ref<!fir.array<1xi32>>
```

After LLVM inlining, and other optimizations we have the following minloc loop:
```
.lr.ph.i:                                         ; preds = %.lr.ph.i.preheader, %.lr.ph.i
  %42 = phi i32 [ %51, %.lr.ph.i ], [ 1, %.lr.ph.i.preheader ]
  %43 = phi float [ %52, %.lr.ph.i ], [ %41, %.lr.ph.i.preheader ]
  %44 = phi i64 [ %53, %.lr.ph.i ], [ 1, %.lr.ph.i.preheader ]
  %45 = shl nsw i64 %44, 2
  %46 = getelementptr i8, ptr %10, i64 %45
  %47 = load float, ptr %46, align 4, !tbaa !60
  %48 = fcmp fast uge float %47, %43
  %49 = trunc i64 %44 to i32
  %50 = add nuw i32 %49, 1
  %51 = select i1 %48, i32 %42, i32 %50
  %52 = select i1 %48, float %43, float %47
  %53 = add nuw nsw i64 %44, 1
  %exitcond.not.i = icmp eq i64 %53, %9
  br i1 %exitcond.not.i, label %_FortranAMinlocReal4x1_i32_fast_simplified.exit, label %.lr.ph.i, !llvm.loop !64
```

The select operations form the cyclic dependency, and they are later transformed to cmov/minss instructions. Before my change, the SimplifyCFG pass could not produce selects, presumably, because the result of the integer select was stored into the temporary `<1 x i32>` array.

The cyclic dependency introduces by the integer cmov seems to limit performance of the loop. The loop would be better off with compare and jump.

Performance restores with `-disable-select-optimize=false`, unfortunately, it is disabled by default on X86.

Possible solutions:
* Try to enable the select optimization for X86, but I guess it is disabled for a reason.
* We can try to trick SimplifyCFG to not optimize the compare-jump into selects by setting the following probability to the jump instruction:
```
  %35 = load float, ptr %34, align 4, !tbaa !1609
  %36 = fcmp fast olt float %35, %23
  %37 = fcmp fast une float %23, %23
  %38 = fcmp fast oeq float %35, %35
  %39 = and i1 %37, %38
  %40 = or i1 %36, %39
  %41 = trunc i32 %27 to i1
  %42 = xor i1 %41, true
  %43 = or i1 %40, %42
  br i1 %43, label %44, label %47, !prof !2000

44: ; preds = %26
  store i32 1, ptr %5, align 4, !tbaa !1609
  %45 = trunc i64 %22 to i32
  %46 = add i32 %45, 1
  store i32 %46, ptr %14, align 4, !tbaa !1609
  br label %47

47: ; preds = %44, %26
...

!2000 = !{!"branch_weights", !"expected",  i32 1, i32 99}
```
This is just a trick though, and the right solution should be allowing the select optimization to use its heuristics.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykV11v47oR_TXMyyCCREpy_OAHJ1m3C-wFittF27eAkkYW99KiLklt7P31xVCU_JGkSHEXC0SSZ87MHA7PkNI5te8RN6x4ZJz__CX_6KRVjHNWPN_J0XfGbuavd5VpTpvvnXJgcbCmGWt0YHr4hX0OsvVoofN-cExsGd8xvtsr341VUpsD4zutf85_7gdrfmDtGd8No9aM7zKeFXnO0i1Lt9uAxMr0a69Vj3__tvv6-zYkysoUXhF68wqd_IngKRfVk23dmV-NfyELa0aveqQs0i0r0_g_3QIwXnABTDxDp1tlk4Pqtanpc7ZmXKTAVo-tdP4gfRfMGBfSKt8l81cmnuiRiS9s9QxMbIHxB8YzQqvMkYmn-CKtlSd6FbtjKzg5iC-Mr-GeiS_AeDZlgMfBMvGUHdVkQ1nS98a8aGMGSk3afRmTKeoMvIkPzuMQH8fe2AYtNlQAYTBeFMVFoXIY9Gkqn_GnC9Q5__ez4U-g-gaPS970nVIMVBblRYQGaYWkR_plNZFJyCEQ-d-QZbF9S9YS-L3YV44XdMFcY-iRWPrEUjGVSMah6ncB2Or5plFYuv3eITTmPqyBcuA7BItu1B5MC4oaU_V7MO17XXabDhcxnUhL4OFjxj9L0Jucp43z7du_flsyJDzZN2B8hxbM4NVB_ZJemd7RToq7CKE1WptXKiluCSr8bW2JtsnQJYpK-Ow_Jh5hsNi4uYdnkGSw2KFs0MaWXNDjVs15cBk6RSsIrHgMa5rdmAMrnsOn4hFufzvHCFYzsFiAW22kX6D5_4Amv0_C5-e8y3wBF38972lLu05D714ncApHznwxmnblHj1qPGDvB29BPZANPZHWpWFzRe9icVwFR21kM9Fy4ZKXoZM0dXQem9RXUtLfs7bmDwGhrQ8DkErCuMeZYcKPReZicVgHB2_Hvj6XQ7tlFhoiLg1GsmmgH1-nViBXQssWo2yiBjXWHlQ2pRPqjPb84qVYUi74R37nvMX162rxFVeJvVmSJTk8Kl-bvkl642ndxTMo4gj_nB2W5lgHn8rGVK49yUbLCjX99LIz1lvZb38LO_Z3lDo_Zi9K8Bfi_sWpw6BVq7BJCOXKd9lp00rSTE7iuMnK_H01jBSZAW0UkNbYQ1CP-lRrVUODA_YN9vVplh3f4QmkRdCSpInSdeSFDa1xfTA_Gd8dVO9ojDtvxzogJ_CIrbEIhxPUnez3SIAU6Z9TUaen3d9gkM5BbUbdQG88xBNJzNOF5iXJPshKh4QqrOXo8EbL6U31Hvdo5xJfpQPnDY1T1XsTTDweBmOlPdFhg4QYjhCluEwhyHNy5uoNIQQ0n5iq01VQYgEc4sERJ1odlIcBLdEk-xrnHGl5Evgen-A11F0hVOiJWtO28Kp8B7U5DMQ40f9jPAwxq39cIFoM1bnJgZXpfaOcrDTeTwTcxzmBTDy3UjukkvkTjH1rrB9pyE-MKk-zMTo3VFiDrQzE9vCfh3KObZxTlUZwRo9hgeNk4Vv4bk9UNvYEEQpd-uw8q6jTCC-s4ujhK-xHpJ65jk9WEixKZ_ok4v8boZY9-CmMt6r-46qJvAnNM1c8tfNE4T3RN3VA7Cmq0KH3NCevp-ZgTSUrpZWf4nQI0Xvp6g_Oo6L4WHVF_rHqZmW6XjDKG9012p8FSxRRW_iiu2J1K9T9hVAvZ8QLh1tlN_jnOxHEMkzEpOzUhZOSiVn9xcOi_pOwm1nsRDmbLJXl2eWAmMSbr8KAyG6OCccFZxrT3o54M_DPFuk8ivi13k5av-jkpOPn11hDNljT0l-eplEh8zwc627POrwM-GG_hfyzi-UtPre6cepfDUnOb4ZknPo0i-aBV5xn0Dn-Msvns8BnWqyyVxxMBa_eLTjP596hypMkSkDkKlpldEvhGeO8srKvu5dXVPuONHs-pzPO8Thg7bGJH8_s0cN6_fbUHm6mysGP0XmQca_7zoz77mIegaVQixSB62YllfNm_kiFvAGaH8o76HC0ynlVu-Su2YhmLdbyDjfZShRrURQ8ves2D9kqb9tVnlVFuZblOi-LelUKWdVN1bR5fac2POVFmqWCp9lDnibrep3Jel1mskjzlGcsT_EglU7CgDZ2f6ecG3FDt-X1-i6siYt391ZLOu6Hi7vdhFt2Ne4dy1OtnHdnCK-8Dhf-yaN4hiwpjlcjx-LeonNUs-lhL91Lc-r53Wj15v--4IeMXbzir9d3Pzf8vwEAAP__NUXEcQ">