Fixes clang crash caused by a stale function pointer.
The bug has been present for a pretty long time, but we were lucky not to trigger it until D140663.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
150 ms | x64 debian > Flang.Driver::code-gen-rv64.f90 |
Event Timeline
Thank you Artem!
clang/lib/CodeGen/CGCUDANV.cpp | ||
---|---|---|
1201 | The different F is because sometimes at first we use an F with incomplete types as a key and later we use a different F (even if it's coming from the same function) with the instantiated types (usually after we encounter a statement where the size of the template parameter is necessary, like a function call). If you prefer this solution, the patch LGTM. |
clang/lib/CodeGen/CGCUDANV.cpp | ||
---|---|---|
1201 | Instantiating a complete function when we normally would not sounds a bit too invasive and may buy us unintended side effects. E.g. I can see it potentially causing code explosion in some cases, where we previously could get by with just a function decl. Fixing the cache locally maintains the global status quo which seems to be about the right balance between improving the situation, the effort involved, and the potential risk of the fix. The way we track kernels could potentially be improved (I think it would be better to track them explicitly vs relying on observing the functions flying by), but that should be a separate patch. Right now I just want to fix the regression w/o affecting anything else. |
Possibly, but I'm unable to reproduce the crash: https://godbolt.org/z/Gsx9sWG4v
The value cached by KernelHandles in HIP is the the manually created 'Var' and not the function itself. I don't think it ever changes outside of this function.
However, KernelStubs would still point to the original F, and that may potentially be left dangling. Perhaps I should always update both handles and stubs if F changes.
Yes, HIP is susceptibel to having the dangling pointer to F. What saves us is that KernelStubs happens to be used only *before* the cached functions are reinstantiated, so we never use those dangling pointers in case of HIP.
OK, looks like I'll need to fix HIP, too.
The different F is because sometimes at first we use an F with incomplete types as a key and later we use a different F (even if it's coming from the same function) with the instantiated types (usually after we encounter a statement where the size of the template parameter is necessary, like a function call).
Another option could be to always instantiate the complete type for F when we call GetOrCreateLLVMFunction (IIRC) if the function has a global attribute.
If you prefer this solution, the patch LGTM.