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

    <tr>
        <th>Summary</th>
        <td>
            OpenMP untied tasks + stack management
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          rpereira-dev
      </td>
    </tr>
</table>

<pre>
    Tested on LLVM release 15.x
Using C99 Variable Length Array (VLA) within OpenMP untied tasks crashes.
Using `alloca` within OpenMP untied tasks can lead to unexpected behaviour at run-time.

I believe these issues are tightly linked to the `untied` implementation, which as far as I understand it:
    - A single task descriptor `kmp_task_t` is built by the compiler/runtime  (`__kmpc_omp_task_alloc`)
    - Clang creates continuations on each explicit scheduling point of the task scope, privatizing tasks local variables that would be pushed on the thread's
    - Each continuations are sent to the runtime and scheduled as 'normal tasks'

Here are a few code examples illustrating what's going on:

Snippet 1: crashed at compile-time
```C
void toto(int n) {
    # pragma omp task untied
    {
        int x[n];
        x[0] = 42;
        # pragma omp taskyield
        assert(x[0] == 42);
    }
}

int main(void) {
    # pragma omp parallel
    {
        # pragma omp single
        {
            toto(1);
        }
    }
    return 0;
}
```

Snippet 2: no crashes, no continuations are generated (but task cannot change thread on the yield)
```C
void toto(int n) {
        int x[n];
        x[0] = 42;
        # pragma omp taskyield
        assert(x[0] == 42);
}

int main(void) {
    # pragma omp parallel
    {
        # pragma omp single
        {
            # pragma omp task untied
            toto(1);
        }
    }
    return 0;
}
```

Snippet 3: may crash at run-time (the pointer 'x' is privatized, not the 'n' pointed bytes)
```C
void toto(int n) {
    # pragma omp task untied
    {
            int * x = alloca(n);
            x[0] = 42;
            # pragma omp taskyield
            assert(x[0] == 42);
    }
}

int main(void) {
    # pragma omp parallel
    {
        # pragma omp single
        {
            toto(1);
        }
    }
    return 0;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsVs9v6zYM_muUC9HClpM4PuSQtiv2gD5swLZ3LWiZsbXKkiHJ-bG_fqDttGkaPHS77B0WFE4Vi-RHfh8lYgi6tkRrsbgTi4cZ9rFxfu078qQ93lS0m5WuOq5_pxCpAmfh6enbV_BkCANBurg9iORBJJs_grY13BcFfEOvsTQET2Tr2MDGezyCkKtvTxshC9jr2GgLv3Rkv_4KvY2aKogYXgIoj6GhcHvuUiwTNMYpFMvku7ZowRBWEB30lg4dKUZcUoM77XoPGMH39ibqlqYA4_MLlGQ07QhiQ4FAh9BTAPQEUddNNEcw2r7Q4Dk2xIjGyIxIt52hlmzEqJ0V8h72jVYNYIAtev76Ar2tyIeItgIdRTbFBQC4gQ1wloaGLKCioLzuovMc5aXtnvnn5zhEClD22kQojwMM5dpOG_JCPnrG0xJwlcUyeX5-aTv17E7mQ_3EMhGyOA99b9DWoDxhpADK2ahtP6QRmGhC1QAdOqOVjhBUQ1VvmJHOaRvBbQcUA-ygXEece-f1DqP-i7eNtDBzBnaTJgLEBiPsXW-YGuj60IyyGnw1nrASMg_nMH9iHO_RMTeBbDwxcsqfKzwBpYprL2RunW_RjGiEzM-Z_5k8Db4QtrQH5SoCOiAzGkAb04foMXIu-wYj44La8dLZVxbH529Wdx1FSEW2mVRcseAmjgbRTfuXyfh3P653TrOwohNyxWW13CIiv3urgJCZuJdik3Qe6xbBtd1Y9UmEbxvPrfjD_g5icWfF4kFkFy_5RSIWDyCyB5jLD--FzOAi4lGTqd7vwhDIRyFX5-4mj7J451TkD1MJXv8ZnoyyRW2FXHExruV_DqRDj8aQ-U7eFxZjg11subThz0RDeon8HfoPC0-x9xaSV5O3_E5cX5OKZKlYdzrzuHt49UHnNVnyyEeZkKuyjyP3Cq11EVSDtj41zqmNRppOvf7PBfdjSeeHVcuVLD-05H-irIyV1eJxlNb5vccSYoUMJzh5Ph4PQuZ8tZxObqpGJcbxqpO55Q2jQQXlMbJU_7W0PlOzq8Vmd0Ju4DBobhoI5MpeK-hnJPp5mf5_yn1Wi7NqnVVFVuCM1ukyL9JlsVjks2YtF2mSzBWtUJVVliVFvlxsl2m1nat8uyqrmV7LRGZJlq7SYlGk-a3KcJvjXOWoZErpXMwTalGbW2N27a3z9WyY0tbLdF4UM4MlmTDMsFJa2o8jnJCSR1q_Zpubsq-DmCdGhxjevEQdDa2vjZNC3kGIqF6gRYv1MOLNem_WTYxd4OtfPgr5WOvY9OWtcq2Qj-x2-rrpvPuTVBTycZwnhXwcwP4dAAD__xFARgE">