-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
coroutines + templates + "-fsanitize=undefined" = error in backend: Cannot represent a difference across sections (clang++ 10, 11, 12, trunk) #49689
Comments
This is due to
Before coro-splitting
After coro-splitting
So for .resume/.destroy/.cleanup, their prologue data are still referring About the fix, I think we could replace references to ramp function in coroutine functions prologue data with their own function symbol:
I'm not sure this covers all the use cases, but most likely a better default than the status quo. |
I've never seen this prologue attribute before. Why does it have a self-reference? That seems generically problematic for any sort of function duplication pass. If such passes are all supposed to be updated to handle it, then sure, I guess coroutine splitting should be, too. |
Okay, reading up on this attribute, I have no idea what we can reasonably do. This is intentionally opaque data. How can we know in general that it's safe to replace references to the ramp function with references to the current sub-function here? How do other function-cloning optimizations deal with this? |
That's indeed problematic. I was proposing to enforce self-referencing before and after coro-split just for this particular bug. Yeah, it is definitely not a complete solution. |
*** Bug llvm/llvm-bugzilla-archive#50863 has been marked as a duplicate of this bug. *** |
I recently found that you don't even need templates, a static member function coroutine is enough: |
We have this (form the last comment's output):
and later .type .L__unnamed_2,@object # @​1
.section .rodata,"a",@progbits
.p2align 3
.L__unnamed_2:
.quad _ZTIF4taskvE
.size .L__unnamed_2, 8 Clearly I'm guessing the sequence
Is really
so asan is hiding some magic numbers by adding a jump over them, but those magic numbers are not representible. |
This is llvm::Constant * but looking at the first comments I see you already new that. Anyway it was fun reverse-engineering it. |
We should probably just disable this sanitizer, because this does not seem like a well-designed implementation. Clang should emit some sort of abstract attribute, and then a very late pass can cause that to be lowered into this prologue attribute. |
How should we fix this in the release/13.x branch? |
CC @pcc in case he got insights about this. https://reviews.llvm.org/D37597 introduced the faulty minus op in this bug. For a temporary measure, I think we could use 846595819 (getUBSanFunctionSignature) to tell that
|
Hmmm, not quite. The type information comes from RTTI, the method I described may compile successfully but gives runtime false positives since resume/destroy function types are different from the ramp function. I think the only sensible thing left is to discard the |
mentioned in issue llvm/llvm-bugzilla-archive#50863 |
mentioned in issue #51489 |
Ugh, spent some time bisecting only to notice now that there's a patch ready. Anyway bisected to commit 5de2d18
|
I see the patch is rotting on the review board. Perhaps someone can review it? |
Hi, can someone with expertise in this area review the diff? Thanks. |
Could this issue please be added to the clang v14 milestone as a release blocker? |
@llvm/issue-subscribers-clang-codegen |
It's now been 7 weeks since the patch was posted, and no review activity. @tstellar perhaps you can enlist a reviewer? |
Review stalled again :( |
before this change, the design of generator (quoting Avi's comment): > This effectively forces a ping-pong between the generator and its user. > The generator will have to yield each time it produces a value. after this change, we have two variants of generator - one which always suspends itself so its caller can consume the produced value. - one which buffers the yielded values until the buffer is full, by then, it suspends itself, and wait for the consumer to grab a value from it. please note, due to llvm/llvm-project#49689, the new generator does not compile with clang-15 + {debug,sanitize} mode. but the old version compiles and runs fine with the same combinatino. Signed-off-by: Kefu Chai <tchaikov@gmail.com>
before this change, the design of generator (quoting Avi's comment): > This effectively forces a ping-pong between the generator and its user. > The generator will have to yield each time it produces a value. after this change, we have two variants of generator - one which always suspends itself so its caller can consume the produced value. - one which buffers the yielded values until the buffer is full, by then, it suspends itself, and wait for the consumer to grab a value from it. please note, due to llvm/llvm-project#49689, the new generator does not compile with clang-15 + {debug,sanitize} mode. but the old version compiles and runs fine with the same combinatino. Signed-off-by: Kefu Chai <tchaikov@gmail.com>
before this change, the design of generator (quoting Avi's comment): > This effectively forces a ping-pong between the generator and its user. > The generator will have to yield each time it produces a value. after this change, we have two variants of generator - one which always suspends itself so its caller can consume the produced value. - one which buffers the yielded values until the buffer is full, by then, it suspends itself, and wait for the consumer to grab a value from it. please note, due to llvm/llvm-project#49689, the new generator does not compile with clang-15 + {debug,sanitize} mode. but the old version compiles and runs fine with the same combinatino. Signed-off-by: Kefu Chai <tchaikov@gmail.com> Message-Id: <20220703170214.43823-1-tchaikov@gmail.com>
before this change, the design of generator (quoting Avi's comment): > This effectively forces a ping-pong between the generator and its user. > The generator will have to yield each time it produces a value. after this change, we have two variants of generator - one which always suspends itself so its caller can consume the produced value. - one which buffers the yielded values until the buffer is full, by then, it suspends itself, and wait for the consumer to grab a value from it. please note, due to llvm/llvm-project#49689, the new generator does not compile with clang-15 + {debug,sanitize} mode. but the old version compiles and runs fine with the same combinatino. Signed-off-by: Kefu Chai <tchaikov@gmail.com>
@nikic any chance of getting this backported to 14.0.x? and getting a release cut? |
@avikivity: 15 is only maintained release branch. |
I see. It is unfortunate, 14 is broken, and 15 is unreleased, so there is no way to deliver a fix to users. |
And to think that this issue was once a release blocker for 13.0.1. |
Failed to cherry-pick: 6678f8e https://github.com/llvm/llvm-project/actions/runs/2891032428 Please manually backport the fix and push it to your github fork. Once this is done, please add a comment like this:
|
@avikivity I recall you have a branch with this fix backported manually. |
I just checked the patch is already included in the 15.x release branch. |
Ah, I thought you were trying to backport it to 14. |
The problem is not with performing the backport. It is trivial and mechanical. The problem is that 14.x is not getting updates, while 15.x is not released. |
Information in the function `Prologue Data` is intentionally opaque. When a function with `Prologue Data` is duplicated. The self (global value) references inside `Prologue Data` is still pointing to the original function. This may cause errors like `fatal error: error in backend: Cannot represent a difference across sections`. This patch detaches the information from function `Prologue Data` and attaches it to a function metadata node. This and D116130 fix llvm/llvm-project#49689. Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D115844
There is no proper RTTI for these split functions. So just delete the metadata. Fixes llvm/llvm-project#49689. Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D116130
now that the minimum clang version we support is Clang 15, and the fix of llvm/llvm-project#49689 was included its 15.x branch. so we can enable these test for Clang now. Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>
now that the minimum clang version we support is Clang 15, and the fix of llvm/llvm-project#49689 was included its 15.x branch. so we can enable these tests for Clang now. Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>
Extended Description
The attached file causes clang++ to crash given certain compilation flags.
also godbolt: https://godbolt.org/z/j14YMxj5M
$ clang++ --version
clang version 10.0.1 (Fedora 10.0.1-3.fc32)
Target: x86_64-unknown-linux-gnu
Thread model: posix
$ clang++ coro-crash.cpp -std=c++20 -stdlib=libc++ -fsanitize=undefined
fatal error: error in backend: Cannot represent a difference across sections
Stack dump:
0. Program arguments: /usr/bin/clang++ -std=c++20 -fsanitize=undefined -fcolor-diagnostics -stdlib=libc++ -c -o coro-crash.o coro-crash.cpp
1. parser at end of file
2. Code generation
/lib64/libLLVM-10.so(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x2e)[0x7f60b555e10e]
/lib64/libLLVM-10.so(_ZN4llvm3sys17RunSignalHandlersEv+0x34)[0x7f60b555c3e4]
/lib64/libLLVM-10.so(_ZN4llvm20CrashRecoveryContext10HandleExitEi+0x78)[0x7f60b549b768]
/lib64/libLLVM-10.so(_ZN4llvm3sys7Process4ExitEi+0x1b)[0x7f60b5556ffb]
/usr/bin/clang++(+0x16372)[0x55988c5f0372]
/lib64/libLLVM-10.so(_ZN4llvm18report_fatal_errorERKNS_5TwineEb+0x8b)[0x7f60b54a702b]
/lib64/libLLVM-10.so(+0x1bc7623)[0x7f60b66db623]
/lib64/libLLVM-10.so(+0x1ba83c6)[0x7f60b66bc3c6]
/lib64/libLLVM-10.so(_ZN4llvm11MCAssembler11handleFixupERKNS_11MCAsmLayoutERNS_10MCFragmentERKNS_7MCFixupE+0xf2)[0x7f60b66d2ed2]
/lib64/libLLVM-10.so(_ZN4llvm11MCAssembler6layoutERNS_11MCAsmLayoutE+0x281)[0x7f60b66d40b1]
/lib64/libLLVM-10.so(_ZN4llvm11MCAssembler6FinishEv+0x3d)[0x7f60b66d42ad]
/lib64/libLLVM-10.so(_ZN4llvm10AsmPrinter14doFinalizationERNS_6ModuleE+0x731)[0x7f60b5c64b11]
/lib64/libLLVM-10.so(_ZN4llvm13FPPassManager14doFinalizationERNS_6ModuleE+0x65)[0x7f60b5658895]
/lib64/libLLVM-10.so(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x460)[0x7f60b5664220]
/lib64/libclang-cpp.so.10(+0x16123e1)[0x7f60baea73e1]
/lib64/libclang-cpp.so.10(_ZN5clang17EmitBackendOutputERNS_17DiagnosticsEngineERKNS_19HeaderSearchOptionsERKNS_14CodeGenOptionsERKNS_13TargetOptionsERKNS_11LangOptionsERKN4llvm10DataLayoutEPNSE_6ModuleENS_13BackendActionESt10unique_ptrINSE_17raw_pwrite_streamESt14default_deleteISM_EE+0x2fe)[0x7f60baea805e]
/lib64/libclang-cpp.so.10(+0x190fb39)[0x7f60bb1a4b39]
/lib64/libclang-cpp.so.10(_ZN5clang8ParseASTERNS_4SemaEbb+0x499)[0x7f60ba208c09]
/lib64/libclang-cpp.so.10(_ZN5clang14FrontendAction7ExecuteEv+0xb9)[0x7f60bb83c139]
/lib64/libclang-cpp.so.10(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x1cd)[0x7f60bb7f827d]
/lib64/libclang-cpp.so.10(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0x95c)[0x7f60bb8b212c]
/usr/bin/clang++(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x6c0)[0x55988c5f1440]
/usr/bin/clang++(+0x15a94)[0x55988c5efa94]
/lib64/libclang-cpp.so.10(+0x1c8cec9)[0x7f60bb521ec9]
/lib64/libLLVM-10.so(_ZN4llvm20CrashRecoveryContext9RunSafelyENS_12function_refIFvvEEE+0x27)[0x7f60b549b5e7]
/lib64/libclang-cpp.so.10(_ZNK5clang6driver10CC1Command7ExecuteEN4llvm8ArrayRefINS2_8OptionalINS2_9StringRefEEEEEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPb+0x157)[0x7f60bb524537]
/lib64/libclang-cpp.so.10(ZNK5clang6driver11Compilation14ExecuteCommandERKNS0_7CommandERPS3+0x9d)[0x7f60bb4f8bed]
/lib64/libclang-cpp.so.10(_ZNK5clang6driver11Compilation11ExecuteJobsERKNS0_7JobListERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x86)[0x7f60bb4f9156]
/lib64/libclang-cpp.so.10(_ZN5clang6driver6Driver18ExecuteCompilationERNS0_11CompilationERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x93)[0x7f60bb501693]
/usr/bin/clang++(main+0x14a6)[0x55988c5ebb86]
/lib64/libc.so.6(__libc_start_main+0xf2)[0x7f60b4766042]
/usr/bin/clang++(_start+0x2e)[0x55988c5ecc1e]
also checked through godbolt: crashes in clang 11 and clang trunk, clang 12 doesn't crash but prints errors.
None of these commands crash:
clang++ coro-crash.cpp -std=c++20 -stdlib=libc++ -fsanitize=undefined -emit-llvm -Xclang -disable-llvm-passes -c
clang++ coro-crash.cpp -std=c++20 -stdlib=libc++ -fsanitize=undefined -emit-llvm -Xclang -c
by https://llvm.org/docs/HowToSubmitABug.html#crashing-bugs I deduced that it's a backend bug (as if it wasn't obvious by the error message and the "Code generation" part in the dump).
However, after generating coro_crash.bc using:
clang++ coro-crash.cpp -std=c++20 -stdlib=libc++ -fsanitize=undefined -emit-llvm -c -o coro_crash.bc
none of these commands crash either:
llc coro_crash.bc
llc coro_crash.bc -relocation-model=pic
llc coro_crash.bc -relocation-model=static
Hence https://llvm.org/docs/HowToSubmitABug.html#backend-code-generator-bugs claims that I should follow instructions for front-end bugs, but every other evidence points to a backend bug, so dunno. Maybe it's a mix of bugs, frontent/middle passing incorrect input to backend or whatever.
Anyway, bugpoint doesn't want to cooperate with me either:
bugpoint -run-llc coro_crash.bc
Read input file : 'coro_crash.bc'
*** All input ok
Initializing execution environment: Found llc: /usr/bin/llc
Sorry, I can't automatically select a safe interpreter!
So I guess that's all what I can give in this bug report.
The text was updated successfully, but these errors were encountered: