Skip to content
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

Deduced _BitInt type with certain values causes assert in EmitGlobalVarDefinition #85139

Closed
erichkeane opened this issue Mar 13, 2024 · 5 comments · Fixed by #91364
Closed

Deduced _BitInt type with certain values causes assert in EmitGlobalVarDefinition #85139

erichkeane opened this issue Mar 13, 2024 · 5 comments · Fixed by #91364
Labels
clang:codegen confirmed Verified by a second party

Comments

@erichkeane
Copy link
Collaborator

I found this messing around with _BitInt

https://godbolt.org/z/d6EYahK85

auto x = static_cast<_BitInt(257)>(0);

See stack trace below. It seems that the static_cast of SOMETHING (or the result of the expression on the RHS?) PLUS a deduced type is required. ALSO the value of the size of the _BitInt doesn't have an obvious pattern. All values sub-129 seem valid, but 255 and 256 are both valid (so its not a power-of-2 thing?). It seems any value 193-256 is valid as well (only spot checked).

I haven't mapped out ALL the values, but it seems a little odd where the holes are.

clang++: /root/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:5294: void clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(const clang::VarDecl*, bool): Assertion `VarSize == CstSize && "Emitted constant has unexpected size"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -Wall <source>
1.	<eof> parser at end of file
2.	<source>:3:6: LLVM IR generation of declaration 'x'
3.	<source>:3:6: Generating code for declaration 'x'
 #0 0x00000000038fc108 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x38fc108)
 #1 0x00000000038f9dec llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x38f9dec)
 #2 0x0000000003841908 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007ffaa8c42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007ffaa8c969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #5 0x00007ffaa8c42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #6 0x00007ffaa8c287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #7 0x00007ffaa8c2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #8 0x00007ffaa8c39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #9 0x0000000003cd4204 clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(clang::VarDecl const*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3cd4204)
#10 0x0000000003cf53a1 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3cf53a1)
#11 0x0000000003cf5a33 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3cf5a33)
#12 0x0000000003cff94b clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.part.0) CodeGenModule.cpp:0:0
#13 0x0000000004195ce6 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#14 0x00000000041866e8 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41866e8)
#15 0x00000000061758ec clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x61758ec)
#16 0x0000000004193908 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4193908)
#17 0x000000000440efc9 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x440efc9)
#18 0x000000000438c6fe clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x438c6fe)
#19 0x00000000044f199e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44f199e)
#20 0x0000000000c27226 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc27226)
#21 0x0000000000c1ef8a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#22 0x00000000041d5099 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#23 0x0000000003841db4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3841db4)
#24 0x00000000041d568f clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#25 0x000000000419d195 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x419d195)
#26 0x000000000419dbfd clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x419dbfd)
#27 0x00000000041a5b35 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41a5b35)
#28 0x0000000000c2470d clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc2470d)
#29 0x0000000000b198e4 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xb198e4)
#30 0x00007ffaa8c29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#31 0x00007ffaa8c29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#32 0x0000000000c1ea4e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc1ea4e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
@EugeneZelenko EugeneZelenko added clang:codegen crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Mar 13, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 13, 2024

@llvm/issue-subscribers-clang-codegen

Author: Erich Keane (erichkeane)

I found this messing around with _BitInt

https://godbolt.org/z/d6EYahK85

auto x = static_cast&lt;_BitInt(257)&gt;(0);

See stack trace below. It seems that the static_cast of SOMETHING (or the result of the expression on the RHS?) PLUS a deduced type is required. ALSO the value of the size of the _BitInt doesn't have an obvious pattern. All values sub-129 seem valid, but 255 and 256 are both valid (so its not a power-of-2 thing?). It seems any value 193-256 is valid as well (only spot checked).

I haven't mapped out ALL the values, but it seems a little odd where the holes are.

clang++: /root/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:5294: void clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(const clang::VarDecl*, bool): Assertion `VarSize == CstSize &amp;&amp; "Emitted constant has unexpected size"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -Wall &lt;source&gt;
1.	&lt;eof&gt; parser at end of file
2.	&lt;source&gt;:3:6: LLVM IR generation of declaration 'x'
3.	&lt;source&gt;:3:6: Generating code for declaration 'x'
 #<!-- -->0 0x00000000038fc108 llvm::sys::PrintStackTrace(llvm::raw_ostream&amp;, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x38fc108)
 #<!-- -->1 0x00000000038f9dec llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x38f9dec)
 #<!-- -->2 0x0000000003841908 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #<!-- -->3 0x00007ffaa8c42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #<!-- -->4 0x00007ffaa8c969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #<!-- -->5 0x00007ffaa8c42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #<!-- -->6 0x00007ffaa8c287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #<!-- -->7 0x00007ffaa8c2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #<!-- -->8 0x00007ffaa8c39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #<!-- -->9 0x0000000003cd4204 clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(clang::VarDecl const*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3cd4204)
#<!-- -->10 0x0000000003cf53a1 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3cf53a1)
#<!-- -->11 0x0000000003cf5a33 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3cf5a33)
#<!-- -->12 0x0000000003cff94b clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.part.0) CodeGenModule.cpp:0:0
#<!-- -->13 0x0000000004195ce6 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#<!-- -->14 0x00000000041866e8 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41866e8)
#<!-- -->15 0x00000000061758ec clang::ParseAST(clang::Sema&amp;, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x61758ec)
#<!-- -->16 0x0000000004193908 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4193908)
#<!-- -->17 0x000000000440efc9 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x440efc9)
#<!-- -->18 0x000000000438c6fe clang::CompilerInstance::ExecuteAction(clang::FrontendAction&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x438c6fe)
#<!-- -->19 0x00000000044f199e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44f199e)
#<!-- -->20 0x0000000000c27226 cc1_main(llvm::ArrayRef&lt;char const*&gt;, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc27226)
#<!-- -->21 0x0000000000c1ef8a ExecuteCC1Tool(llvm::SmallVectorImpl&lt;char const*&gt;&amp;, llvm::ToolContext const&amp;) driver.cpp:0:0
#<!-- -->22 0x00000000041d5099 void llvm::function_ref&lt;void ()&gt;::callback_fn&lt;clang::driver::CC1Command::Execute(llvm::ArrayRef&lt;std::optional&lt;llvm::StringRef&gt;&gt;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;&gt;*, bool*) const::'lambda'()&gt;(long) Job.cpp:0:0
#<!-- -->23 0x0000000003841db4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref&lt;void ()&gt;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3841db4)
#<!-- -->24 0x00000000041d568f clang::driver::CC1Command::Execute(llvm::ArrayRef&lt;std::optional&lt;llvm::StringRef&gt;&gt;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;&gt;*, bool*) const (.part.0) Job.cpp:0:0
#<!-- -->25 0x000000000419d195 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&amp;, clang::driver::Command const*&amp;, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x419d195)
#<!-- -->26 0x000000000419dbfd clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&amp;, llvm::SmallVectorImpl&lt;std::pair&lt;int, clang::driver::Command const*&gt;&gt;&amp;, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x419dbfd)
#<!-- -->27 0x00000000041a5b35 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&amp;, llvm::SmallVectorImpl&lt;std::pair&lt;int, clang::driver::Command const*&gt;&gt;&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41a5b35)
#<!-- -->28 0x0000000000c2470d clang_main(int, char**, llvm::ToolContext const&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc2470d)
#<!-- -->29 0x0000000000b198e4 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xb198e4)
#<!-- -->30 0x00007ffaa8c29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#<!-- -->31 0x00007ffaa8c29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#<!-- -->32 0x0000000000c1ea4e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc1ea4e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)

@erichkeane erichkeane added new issue and removed crash Prefer [crash-on-valid] or [crash-on-invalid] labels Mar 14, 2024
@AaronBallman AaronBallman added confirmed Verified by a second party and removed new issue labels Mar 20, 2024
@AaronBallman
Copy link
Collaborator

The failing code is:

#ifndef NDEBUG
      CharUnits VarSize = getContext().getTypeSizeInChars(ASTTy) +
                          InitDecl->getFlexibleArrayInitChars(getContext());
      CharUnits CstSize = CharUnits::fromQuantity(
          getDataLayout().getTypeAllocSize(Init->getType()));
      assert(VarSize == CstSize && "Emitted constant has unexpected size");
#endif

in

For this example, VarSize has a quantity of 40 while CstSize has a quantity of 48.

The AST type is AutoType whose deduced type is signed _BitInt(257). We think that should be aligned to 64 bits, and that sets the width of the type to 320 bits. Dividing by 8 bits is how we get VarSize to 40.

The IR type is IntegerTyId with 257 bits. We end up calling alignTo() with a size of 33 bytes and a 16-bit alignment, which is how we get to 48 bytes for CstSize.

CC @efriedma-quic @rjmccall -- this might be another _BitInt-alignment-ABI-related issue?

@rjmccall
Copy link
Contributor

Sounds like we can't use iN as the in-memory type for some _BitInt widths. That probably means generating astonishingly terrible code, but that's life.

@efriedma-quic
Copy link
Collaborator

The store size for a 257-bit integer should be 264 bits, regardless of the ABI alignment. The ABI alignment only matters for stuff like struct layout and the size of global variables. So we just need to use a different type to represent the value in memory; we can continue to use the obvious operations for load/store/etc. This isn't completely new territory; booleans also have different "memory" and "register" types.

This shouldn't significantly impact code quality; LLVM already basically ignores the declared types of variables.

@rjmccall
Copy link
Contributor

You're right that we can still emit simple loads and stores. What I'm worried about is the fact that a constant initializer is probably going to have to be broken up into individual bytes. I suppose there's no reason LLVM couldn't be taught to fold a load of that back into an iN.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen confirmed Verified by a second party
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants