[flang-commits] [flang] [flang] Generate valid IR on GOTO DO body (PR #66084)

Leandro Lupori via flang-commits flang-commits at lists.llvm.org
Wed Sep 13 05:19:16 PDT 2023


luporl wrote:

> The problem isn't restricted to stride computations. Other loop control expressions are also problematic.
> 
> ```
> subroutine sub(j)
>   integer :: i, j
>   if (j .eq. 2) goto 70
>   do i = 1, 2
>     70 j = j + 1
>   end do
> end
> ```

Your test program works fine with this patch:

```
$ flang-new -c blah.f90
./blah.f90:3:3: warning: Label '70' is in a construct that should not be used as a branch target here
    if (j .eq. 2) goto 70
    ^^^^^^^^^^^^^^^^^^^^^
$
```

The generated IR for this program actually has a step = 1 constant. The problem is that this constant is defined in the beginning of the loop and reused at its end, that will be in a different block.

> 
> This is nonconformant code. f90 Clause 8.1.1.2 states: _Transfer of control to the interior of a block from outside the block is prohibited._ f18 Clause 11.1.2.1 has the same program restriction with a minor qualification.
> 
> Some compilers flag this as a hard error, which is one possibility. A question there is whether to generate errors for all branches into blocks, or allow some that are more likely to be benign.
> 
> Otherwise, the primary goal is to avoid a compiler crash and generate an executable that will likely crash at runtime. It might be possible to generalize this PR to do that, but at a cost of generating somewhat more complex code that isn't needed most of the time.

Right, this is non-conformant code that is currently accepted as an extension by flang's semantics. I agree that if we need to come up with a complex solution to support this use case then it may not be worth it. But if what is done by this patch is enough to fix invalid IR generation when GOTO DO loop bodies are used, I think it is valid, as it adds little complexity and overhead.

Although jumping to the body of a loop may cause crashes at runtime, with care it can be avoided, if, for instance:
- The end of the loop is skipped (e.g., by a GOTO).
- The beginning of the loop is executed at least once (as with a GOTO out followed by a GOTO back inside the loop).

The test case in #65036 uses some constructions similar to the ones above and behaves correctly at runtime.


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


More information about the flang-commits mailing list