[LICM][Coroutine] Don't sink stores from loops with coro.suspend instructions
authorXun Li <lxfind@gmail.com>
Wed, 3 Mar 2021 23:21:57 +0000 (15:21 -0800)
committerXun Li <lxfind@gmail.com>
Wed, 3 Mar 2021 23:21:57 +0000 (15:21 -0800)
commit03f668613c44714fe859e60c5775b6d8d46ac65d
tree0fe2640785fe122e1a88208741c0fa9589049a97
parent30ad7b5dadcd90ce8df240f1fa74ee2e98a875dc
[LICM][Coroutine] Don't sink stores from loops with coro.suspend instructions

See pr46990(https://bugs.llvm.org/show_bug.cgi?id=46990). LICM should not sink store instructions to loop exit blocks which cross coro.suspend intrinsics. This breaks semantic of coro.suspend intrinsic which return to caller directly. Also this leads to use-after-free if the coroutine is freed before control returns to the caller in multithread environment.

This patch disable promotion by check whether loop contains coro.suspend intrinsics.
This is a resubmit of D86190.
Disabling LICM for loops with coroutine suspension is a better option not only for correctness purpose but also for performance purpose.
In most cases LICM sinks memory operations. In the case of coroutine, sinking memory operation out of the loop does not improve performance since coroutien needs to get data from the frame anyway. In fact LICM would hurt coroutine performance since it adds more entries to the frame.

Differential Revision: https://reviews.llvm.org/D96928
llvm/docs/Coroutines.rst
llvm/lib/Transforms/Scalar/LICM.cpp
llvm/test/Transforms/Coroutines/ArgAddr.ll
llvm/test/Transforms/LICM/sink-with-coroutine.ll [new file with mode: 0644]