An alternative to D129025.
For
define void @f(i32 %x) { entry: %cmp = icmp slt i32 %x, 0 br i1 %cmp, label %await.suspend, label %final.suspend await.suspend: %0 = call token @llvm.coro.save(ptr null) %1 = call i8 @llvm.coro.suspend(token %0, i1 false) br label %coro.ret final.suspend: %2 = call token @llvm.coro.save(ptr null) %3 = call i8 @llvm.coro.suspend(token %2, i1 true) br label %coro.ret coro.ret: ret void }
SimplifyCFG would hoist llvm.coro.save into the entry block. However,
since one is for the final suspend and the other is not, the transformation
is not desired.
I proposed D129025, which requires a update to the token type definition
in LangRef to make merging two token-returning instructions illegal
(which I didn't do yet and I think it may affect other users of the token
type like WinEH, GC intrinsics). D129025 also excludes some valid
transformation: for this test case, if both branches of the if statement
contains non-final suspend, it is ok to hoisting llvm.coro.save.
So this patch, I propose to directly change the IR equality between two
llvm.coro.save to disable the invalid hoisting. I don't like the
special casing of llvm.coro.save in the llvm/IR space however, the
only other choice would be to change llvm.coro.save in some way like:
- add new flag parameter to llvm.coro.save
- add llvm.coro.save.final
I'm not a fan of both.
Any thoughts?