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.
Also Promotion optimization will run in CGSCC pipeline after coroutine function been splitted.
Test Plan: check-llvm, pr46990
It seems to me the problem is that the LICM generated code is mixing the loop exit basic block vs the return basic block. It just happens that both the suspend switch and loop exit condition jumps to the same block %bb2, but they mean different things.
I think we should still be able to do LICM when there is coroutine, but it's just that we need to make sure the instructions are moved to the loop exit block, while the suspend switch should remain jumping to the return block?