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

[AsmPrinter] Global Constant with Big Endian crashes backend with assertion ShiftAmt <= BitWidth && "Invalid shift amount" failed #59055

Closed
HazyFish opened this issue Nov 17, 2022 · 4 comments
Labels
crash Prefer [crash-on-valid] or [crash-on-invalid] llvm:codegen

Comments

@HazyFish
Copy link
Contributor

Description

When targeting aarch64_be, the following code crashes the backend with error ShiftAmt <= BitWidth && "Invalid shift amount".

This does not occur when targeting aarch64.

Minimal Reproduction

https://godbolt.org/z/sf17n5Me6

Code

@G = global <4 x i1> <i1 true, i1 false, i1 true, i1 true>

Stack Trace

llc: /home/henry/aflplusplus-isel/llvm-project/llvm/include/llvm/ADT/APInt.h:840: void llvm::APInt::lshrInPlace(unsigned int): Assertion `ShiftAmt <= BitWidth && "Invalid shift amount"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /home/henry/aflplusplus-isel/llvm-project/build-debug/bin/llc -mtriple=aarch64_be ./crash-reports/dagisel-aarch64_be/1.ll
 #0 0x00000000047c438a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Unix/Signals.inc:569:11
 #1 0x00000000047c453b PrintStackTraceSignalHandler(void*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Unix/Signals.inc:636:1
 #2 0x00000000047c2b76 llvm::sys::RunSignalHandlers() /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Signals.cpp:104:5
 #3 0x00000000047c4c65 SignalHandler(int) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/Support/Unix/Signals.inc:407:1
 #4 0x00007f37d8ff5980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
 #5 0x00007f37d7ee5e87 raise /build/glibc-CVJwZb/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
 #6 0x00007f37d7ee77f1 abort /build/glibc-CVJwZb/glibc-2.27/stdlib/abort.c:81:0
 #7 0x00007f37d7ed73fa __assert_fail_base /build/glibc-CVJwZb/glibc-2.27/assert/assert.c:89:0
 #8 0x00007f37d7ed7472 (/lib/x86_64-linux-gnu/libc.so.6+0x30472)
 #9 0x0000000000db84e6 llvm::APInt::lshrInPlace(unsigned int) /home/henry/aflplusplus-isel/llvm-project/llvm/include/llvm/ADT/APInt.h:0:5
#10 0x00000000031b908a emitGlobalConstantLargeInt(llvm::ConstantInt const*, llvm::AsmPrinter&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:3272:5
#11 0x00000000031b9bba emitGlobalConstantVector(llvm::DataLayout const&, llvm::ConstantVector const*, llvm::AsmPrinter&, llvm::DenseMap<unsigned long, llvm::SmallVector<llvm::GlobalAlias const*, 1u>, llvm::DenseMapInfo<unsigned long, void>, llvm::detail::DenseMapPair<unsigned long, llvm::SmallVector<llvm::GlobalAlias const*, 1u>>>*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:3147:19
#12 0x00000000031b6993 emitGlobalConstantImpl(llvm::DataLayout const&, llvm::Constant const*, llvm::AsmPrinter&, llvm::Constant const*, unsigned long, llvm::DenseMap<unsigned long, llvm::SmallVector<llvm::GlobalAlias const*, 1u>, llvm::DenseMapInfo<unsigned long, void>, llvm::detail::DenseMapPair<unsigned long, llvm::SmallVector<llvm::GlobalAlias const*, 1u>>>*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:3458:5
#13 0x00000000031aaba8 llvm::AsmPrinter::emitGlobalConstant(llvm::DataLayout const&, llvm::Constant const*, llvm::DenseMap<unsigned long, llvm::SmallVector<llvm::GlobalAlias const*, 1u>, llvm::DenseMapInfo<unsigned long, void>, llvm::detail::DenseMapPair<unsigned long, llvm::SmallVector<llvm::GlobalAlias const*, 1u>>>*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:3478:5
#14 0x00000000031aa539 llvm::AsmPrinter::emitGlobalVariable(llvm::GlobalVariable const*) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:861:3
#15 0x00000000031b1c80 llvm::AsmPrinter::doFinalization(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2069:22
#16 0x0000000003c71d3e llvm::FPPassManager::doFinalization(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1494:16
#17 0x0000000003c6d93c (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1581:16
#18 0x0000000003c6d22d llvm::legacy::PassManagerImpl::run(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:535:16
#19 0x0000000003c71ef1 llvm::legacy::PassManager::run(llvm::Module&) /home/henry/aflplusplus-isel/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1672:3
#20 0x0000000000d1edec compileModule(char**, llvm::LLVMContext&) /home/henry/aflplusplus-isel/llvm-project/llvm/tools/llc/llc.cpp:737:41
#21 0x0000000000d1d192 main /home/henry/aflplusplus-isel/llvm-project/llvm/tools/llc/llc.cpp:418:13
#22 0x00007f37d7ec8c87 __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:344:0
#23 0x0000000000d1c99a _start (/home/henry/aflplusplus-isel/llvm-project/build-debug/bin/llc+0xd1c99a)

Cause

The following code from function emitGlobalConstantLargeInt in AsmPrinter.cpp tries to right shift Realigned by an amount ExtraBitSize in place. However, if the constant to emit has a bit width less than 64 and the bit width is not a multiple of 8, the shift amount will be greater than the bit width of Realigned, which causes the crash.

unsigned BitWidth = CI->getBitWidth();
// Copy the value as we may massage the layout for constants whose bit width
// is not a multiple of 64-bits.
APInt Realigned(CI->getValue());
uint64_t ExtraBits = 0;
unsigned ExtraBitsSize = BitWidth & 63;
if (ExtraBitsSize) {
// The bit width of the data is not a multiple of 64-bits.
// The extra bits are expected to be at the end of the chunk of the memory.
// Little endian:
// * Nothing to be done, just record the extra bits to emit.
// Big endian:
// * Record the extra bits to emit.
// * Realign the raw data to emit the chunks of 64-bits.
if (DL.isBigEndian()) {
// Basically the structure of the raw data is a chunk of 64-bits cells:
// 0 1 BitWidth / 64
// [chunk1][chunk2] ... [chunkN].
// The most significant chunk is chunkN and it should be emitted first.
// However, due to the alignment issue chunkN contains useless bits.
// Realign the chunks so that they contain only useful information:
// ExtraBits 0 1 (BitWidth / 64) - 1
// chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN]
ExtraBitsSize = alignTo(ExtraBitsSize, 8);
ExtraBits = Realigned.getRawData()[0] &
(((uint64_t)-1) >> (64 - ExtraBitsSize));
Realigned.lshrInPlace(ExtraBitsSize);
} else
ExtraBits = Realigned.getRawData()[BitWidth / 64];
}

@HazyFish
Copy link
Contributor Author

cc @DataCorrupted

@DataCorrupted DataCorrupted added backend:AArch64 crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Nov 17, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 17, 2022

@llvm/issue-subscribers-backend-aarch64

@HazyFish
Copy link
Contributor Author

Candidate patch https://reviews.llvm.org/D138246

DataCorrupted pushed a commit that referenced this issue Mar 29, 2023
…th when targeting Big Endian arch

For Big Endian, the function `emitGlobalConstantLargeInt` tries to right shift `Realigned` by an amount `ExtraBitSize` in place. However, if the constant to emit has a bit width less than 64 and the bit width is not a multiple of 8, the shift amount will be greater than the bit width of `Realigned`, which causes assertion error described in issue [[ #59055 | issue #59055 ]].

This patch fixes the issue by avoiding right shift when bit width is under 64 to avoid the assertion error.

Reviewed By: Peter

Differential Revision: https://reviews.llvm.org/D138246
@HazyFish
Copy link
Contributor Author

Fixed in fc1ffb4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash Prefer [crash-on-valid] or [crash-on-invalid] llvm:codegen
Projects
None yet
Development

No branches or pull requests

4 participants