<div dir="ltr">Hello all!<div>(+cc Vedant Kumar, who I've been told knows a lot about UBSan!)<br></div><div><br></div><div>I am trying to fix an assert that occurs when the transforms in llvm/lib/Transforms/Coroutines are applied to LLVM IR that has been generated with UBSan enabled -- specifically, '-fsanitize=null'.</div><div><br></div><div>You can see an example of the assert in this 26-line C++ file here: <a href="https://godbolt.org/g/Gw9UZq">https://godbolt.org/g/Gw9UZq</a></div><div><br></div><div>Note that without the '-fsanitize=null' option this compiles fine, but when that option is used, Clang/LLVM crashes due to "error in backend: cannot move instruction since its users are not dominated by CoroBegin".</div><div><br></div><div>The coroutine pass coro-split is responsible for transforming instructions within a coroutine function. Because a coroutine function can be suspended and then resumed much later in a program's execution, accesses to stack variables much be rewritten so that they access variables stored on the "coroutine frame," a heap-allocated piece of state that represents the execution frame of the coroutine. As part of this process, load instructions, such as the one generated for the '*this' expression in the source file above, are moved down past a call to the '@llvm.coro.begin' intrinsic.</div><div><br></div><div>However, when UBSan is enabled, the load of '*this' is then immediately followed by a null check and, in the null case, a conditional branch to a call to '@ __ubsan_handle_type_mismatch_v1'. The coro-split pass is not written to move these compare and branch instructions, and instead asserts.</div><div><br></div><div>You can see an example of the IR generated with and without '-fsanitize=null' here: <a href="https://gist.github.com/modocache/54a036c3bf9c06882fe85122e105d153">https://gist.github.com/modocache/54a036c3bf9c06882fe85122e105d153</a> -- PR36578.ll lines 82 to 104 show the problematic UBSan branches. Note that PR36578.nosan.ll, which was compiled without '-fsanitize=null', does not include these branches.</div><div><br></div><div>I have several questions:</div><div><br></div><div>* What's the best way for the LLVM coroutines transform passes to play nicely with the code generated with UBSan's '-fsanitize=null'?</div><div>* Are there other LLVM passes I could look at, to see examples of how they were modified to handle UBSan?</div><div>* I've seen code in Clang's codebase that adds 'SanitizerKind::Null' to a set of skipped UBSan checks; should lib/CodeGen/CGCoroutine.cpp also do something like this, to avoid generating UBSan checks altogether? Would that be sufficient to avoid the error? Are there downsides to doing this?</div><div><br></div><div>Any and all advice is appreciated -- thanks!</div><div><br></div><div>- Brian Gesiak</div><div><br></div></div>