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

    <tr>
        <th>Summary</th>
        <td>
            [flang][hlfir] The elemental ops can be incorrectly optimized by CSE
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            bug,
            flang:ir,
            crash-on-valid
      </td>
    </tr>

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

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

<pre>
    After the recent changes to support recursive memory effects in CSE, the hlfir.elemental operations can be incorrectly optimized.

For example:
```
subroutine test(a)
  interface
     subroutine foo(e, a)
       character :: e(10), a(10)
     end subroutine foo
 end interface
  character :: a(10)
  call foo([(a(i),i=1,10)], a)
 call foo([(a(i),i=1,10)], a)
end subroutine test
```

Before CSE we have:
```
    %5 = hlfir.elemental %4 typeparams %c1 unordered : (!fir.shape<1>, index) -> !hlfir.expr<10x!fir.char<1>> {
    ^bb0(%arg1: index):
      %18 = fir.convert %arg1 : (index) -> i32
      %19 = fir.convert %18 : (i32) -> i64
      %20 = hlfir.designate %3#0 (%19) typeparams %c1 : (!fir.ref<!fir.array<10x!fir.char<1>>>, i64, index) -> !fir.ref<!fir.char<1>>
      hlfir.yield_element %20 : !fir.ref<!fir.char<1>>
    }
...
    %9 = fir.convert %3#1 : (!fir.ref<!fir.array<10x!fir.char<1>>>) -> !fir.ref<!fir.char<1>>
    %10 = fir.emboxchar %9, %c1 : (!fir.ref<!fir.char<1>>, index) -> !fir.boxchar<1>
    fir.call @_QPfoo(%8, %10) fastmath<contract> : (!fir.boxchar<1>, !fir.boxchar<1>) -> ()
...
    %12 = hlfir.elemental %11 typeparams %c1 unordered : (!fir.shape<1>, index) -> !hlfir.expr<10x!fir.char<1>> {
    ^bb0(%arg1: index):
      %18 = fir.convert %arg1 : (index) -> i32
      %19 = fir.convert %18 : (i32) -> i64
      %20 = hlfir.designate %3#0 (%19)  typeparams %c1 : (!fir.ref<!fir.array<10x!fir.char<1>>>, i64, index) -> !fir.ref<!fir.char<1>>
      hlfir.yield_element %20 : !fir.ref<!fir.char<1>>
    }
...
    %16 = fir.convert %3#1 : (!fir.ref<!fir.array<10x!fir.char<1>>>) -> !fir.ref<!fir.char<1>>
    %17 = fir.emboxchar %16, %c1 : (!fir.ref<!fir.char<1>>, index) -> !fir.boxchar<1>
    fir.call @_QPfoo(%15, %17) fastmath<contract> : (!fir.boxchar<1>, !fir.boxchar<1>) -> ()
```

Since there are no memory effects inside the hlfir.elemental operations, CSE reuses substitutes %12 with %5.  I believe this is incorrect, in general (i.e. if `foo` modifies `a`).

I think we should have some indication of the actual reads implied by the elemental operations, but I am not sure yet what the best representation should be.  I cannot think of any existing operation(s) that would allow us to represent the dereference for non-trivial/character types, unless we implement memory effects interface for hlfir.yield_element that will report `read` for its `!fir.ref` operand.

@jeanPerier, @tblah, I will appreciate your feedback.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV91u2zgTfRr6ZhCDon5iXfgisRMgd_3Q776gpJHFliIFknLiPv1iKNlJbKfFdrE_wG5gOJGoc2bmDHUylN6rnUFcs_ye5duFHENn3Xr_XX7rpFOLyjaH9V0b0EHoEBzWaALUnTQ79BAs-HEYrAu0Mjqv9gg99tYdANsW6-BBGdh8fmBiEwk63Sq3RI09miA12AGdDMoaD7U0UCEoU1vnsA76AHYIqlffsVkyvmX8bvp-tA7wRfaDRpbO91jB50-89GPl7BiUQQjoAxMryUQ5rQEoE9C1ssbjDQB4g2itZWKFlPJbVPypO-lkTXJQ6PQOkIlVwumx6fH54hWDpjknnxZp4SKTC_4LylpqPadIPYuVrdSUgGLpNmFiMwHy7VkJvw49KyJqek336fseW-uQ2g7PCJ3cf9gnEoiJPAeWbi_2BhN5BuEw4CCd7D1d1wmMxroGHTakEFApIiGc7-SALN0kLI27TZkGX5go4YalD8BEMtO_DI6e4i8zjhQ_wujB2_s3qeUPVcVjjFy6XUIRj7ynkqaNwUSerGIZkdSaPboAM-6Y6vucVCrOGcprDJF3wqfiFV1kZ2jB38jYIL3YMiCtpEykfNIqT0qiuJD1vZgOW5Zu5gvpnDz8QLOj4EV2VfcLvjP0myKm1A8KdfNl3genwu5-Fxe73U4Xy-Xy3Va7qjDp88cl-IWSqR_8lBH2lX2hR2OiJOZPe3NG_JH-M-_xyVP8SEGuwDL-5X-fZm8Q-WoOHt0AWulDL0PH0k1tTSCDitzv0joLEfFXF06ZrU72ct6kRHxkCEnynyP8OY7w77WEpPjHecLtdU9Iir_TFJL86Aq3f4krXJ0tPitTI42SDkE6BGMvB06vGvzJtEmZ0HzicPToabbxQYUxoJ_951mFLo4mS4AnqFAr3BOp8kCf45A6iQs7NOiiQ63UEpegWmAFJ-UKDr1tVKuIueCSyhHlu3n2iWjNN5qVfGdH3cSRCbztaRpuVB1TBtvGmmQdRqnBoWw8qH7QChuoDnHto0qrMcATyB6MDeBHh3DAAM-dDBFWoacBfnDoCR2jzZlUGOuvpSHolKdtQZoD4IvyQZndaywmVj4OF0T8HPFSa_sMYzwqnCLEoOTYLTqkdrbWgbHmJji1V1Iz8fg6B5MtxSJGo9F7UomqnpzgovXzOB0Zr1nHlJrSJGA8t7CCk5TUJ8KoENv05q0q-FSgeX8IYRn_itJ8QqfQxX2d8VBp2dHfT1MIOQwOa0WWe7CjgxaxqWT9bblo1mlTpqVc4DopSlGkaVrwRbfmBZZNg6IUdZZUsuJNvirTvMISM9lktwu1FlykfCWSJM8LzpepzHAl8iprZXmLScEyjr1Ueqn1vl9at1so70dcF9mqKBZaVqh9POwJUY07JgQTGyZEq6XZsfROudOt2knf3Vhzs5daNXQ73y7cmnhvqnHnWca18sG_Rgoq6HiSnNjyLcvvYxNYvoX_n-3PHx_4aEdvPj8sRqfXXQiDp3-u4pGJx50K3Vgta9sz8Uih5183g7Nf4xv5GCv2TDzGon8LAAD__yu8R7I">