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

aarch64 middle-end optimizer bug: crash when use &&labels(1) #54238

Closed
ashimida123 opened this issue Mar 7, 2022 · 5 comments
Closed

aarch64 middle-end optimizer bug: crash when use &&labels(1) #54238

ashimida123 opened this issue Mar 7, 2022 · 5 comments
Labels
invalid Resolved as invalid, i.e. not a bug llvm:crash llvm:optimizations

Comments

@ashimida123
Copy link

ashimida123 commented Mar 7, 2022

Stack dump:
0. Program arguments: /mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang --target=aarch64-linux-gnu -O2 -S main.c -o main.s

  1.  <eof> parser at end of file
    
  2.  Per-module optimization passes
    
  3.  Running pass 'Function Pass Manager' on module 'main.c'.
    
  4.  Running pass 'Combine redundant instructions' on function '@set_return_addr'
    

#0 0x00000000024c18a3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x24c18a3)
#1 0x00000000024bf7ee llvm::sys::RunSignalHandlers() (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x24bf7ee)
#2 0x00000000024c0d5d llvm::sys::CleanupOnSignal(unsigned long) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x24c0d5d)
#3 0x000000000244d170 CrashRecoverySignalHandler(int) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x244d170)
#4 0x00007f8d11453980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
#5 0x0000000001dcd4f5 llvm::ConstantUniqueMapllvm::ConstantExpr::getOrCreate(llvm::Type*, llvm::ConstantExprKeyType) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bi
n/clang+0x1dcd4f5)
#6 0x0000000001dc2087 llvm::ConstantExpr::getBitCast(llvm::Constant*, llvm::Type*, bool) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x1dc2087)
#7 0x0000000001868655 (anonymous namespace)::ConstantFoldConstantImpl(llvm::Constant const*, llvm::DataLayout const&, llvm::TargetLibraryInfo const*, llvm::SmallDenseMap<llvm::Constant*, llvm::Constant*,
4u, llvm::DenseMapInfollvm::Constant*, llvm::detail::DenseMapPair<llvm::Constant*, llvm::Constant*> >&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x186
8655)
#8 0x00000000018689ac llvm::ConstantFoldConstant(llvm::Constant const*, llvm::DataLayout const&, llvm::TargetLibraryInfo const*) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubunt
u-16.04/bin/clang+0x18689ac)
#9 0x0000000002035414 combineInstructionsOverFunction(llvm::Function&, llvm::InstCombineWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::Do
minatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, unsigned int, llvm::LoopInfo*) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ub
untu-16.04/bin/clang+0x2035414)
#10 0x0000000002035ec1 llvm::InstructionCombiningPass::runOnFunction(llvm::Function&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2035ec1)
#11 0x0000000001e6ca1d llvm::FPPassManager::runOnFunction(llvm::Function&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x1e6ca1d)
#12 0x0000000001e726f3 llvm::FPPassManager::runOnModule(llvm::Module&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x1e726f3)
#13 0x0000000001e6d08f llvm::legacy::PassManagerImpl::run(llvm::Module&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x1e6d08f)
#14 0x000000000269d3b5 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::Da
taLayout const&, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_deletellvm::raw_pwrite_stream >) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-li
nux-gnu-ubuntu-16.04/bin/clang+0x269d3b5)
#15 0x000000000319415f clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x319415f)
#16 0x0000000003be7554 clang::ParseAST(clang::Sema&, bool, bool) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x3be7554)
#17 0x0000000002bea627 clang::FrontendAction::Execute() (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2bea627)
#18 0x0000000002b75151 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2b75151)
#19 0x0000000002c7f38c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2c7f38c)
#20 0x0000000000a06e72 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0xa06e72)
#21 0x0000000000a056b7 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0xa056b7)
#22 0x0000000002a39b12 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optionalllvm::StringRef >, std::__cxx11::basic_string<char, std::char_traits<
char>, std::allocator >, bool) const::$_1>(long) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2a39b12)
#23 0x000000000244cf5d llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x244cf5d)
#24 0x0000000002a394b9 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optionalllvm::StringRef >, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool) const (
/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2a394b9)
#25 0x0000000002a0941d clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-
ubuntu-16.04/bin/clang+0x2a0941d)
#26 0x0000000002a09667 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/mnt/disk0/disk0/toolchains/llv
m/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2a09667)
#27 0x0000000002a21208 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/mnt/disk0/disk0/toolchains/llvm/clan
g+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0x2a21208)
#28 0x0000000000a0506d main (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0xa0506d)
#29 0x00007f8d10326c87 __libc_start_main /build/glibc-uZu3wS/glibc-2.27/csu/../csu/libc-start.c:344:0
#30 0x0000000000a023d9 _start (/mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang+0xa023d9)
clang-12: error: clang frontend command failed with exit code 139 (use -v to see invocation)
clang version 12.0.1
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /mnt/disk0/disk0/toolchains/llvm/clang+llvm-12.0.1-x86_64-linux-gnu-ubuntu-16.04/bin
clang-12: note: diagnostic msg:


PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-12: note: diagnostic msg: /tmp/main-ebca80.c
clang-12: note: diagnostic msg: /tmp/main-ebca80.sh
clang-12: note: diagnostic msg:


Code in use:

#include <stdio.h>

static __attribute__((noinline))
void set_return_addr(unsigned long *expected, unsigned long *addr)
{
    unsigned long * volatile *ret_addr = (unsigned long **)__builtin_frame_address(0) + 1;
    *ret_addr = addr;
}

int __attribute__((optnone)) main(void)
{
    do {
        if ((volatile int)0)
            goto normal;
        if ((volatile int)0)
            goto redirected;
            
        set_return_addr(&&normal, &&redirected);
normal: 
        printf("foo \n");
        break;
        
redirected:
        printf("bar\n");
        
    } while (0);
    
    return 0;
}   

main-0a64b0.zip

@ashimida123 ashimida123 changed the title aarch64 frontend crash when use &&labels aarch64 middle-end optimizer bug: crash when use &&labels(1) Mar 7, 2022
@nikic
Copy link
Contributor

nikic commented Mar 7, 2022

define i32 @main() {
  call void @set_return_addr(i64* bitcast (i8* blockaddress(@main, %redirected) to i64*))
  ret i32 0

redirected:
  ret i32 0
}

define internal void @set_return_addr(i64* %addr) {
  %addr.addr = alloca i64*, i32 0, align 8
  store i64* %addr, i64** %addr.addr, align 8
  ret void
}

Crashes the verifier after opt -ipsccp.

cc @nickdesaulniers who tends to know stuff about blockaddress.

@nickdesaulniers
Copy link
Member

nickdesaulniers commented Mar 14, 2022

And @ashimida123 is implementing Shadow Call Stack (SCS) in GCC for use in the linux kernel. :) Hi @ashimida123 , thank you for filing the report (and #54251).

Given the test cases, I can definitely reproduce a crash w/ ToT.

IIUC, it looks like the blockaddress is being converted from:
i64* bitcast (i8* blockaddress(@main, %redirected) to i64*) to i64* inttoptr (i32 1 to i64*) which looks curious. I just saw something similar in D120781.

@efriedma-quic explains here that BasicBlocks that are not statically reachable have their blockaddresses converted to arbitrary i32 1 Constants.

I think we should not consider a BasicBlock unreachable if it has its address taken, and that address escapes the current Function.

@nickdesaulniers
Copy link
Member

Using address of labels for comparisons is unspecified behavior.
#54328 (comment)

@EugeneZelenko EugeneZelenko added the invalid Resolved as invalid, i.e. not a bug label Mar 14, 2022
@ashimida123
Copy link
Author

And @ashimida123 is implementing Shadow Call Stack (SCS) in GCC for use in the linux kernel. :) Hi @ashimida123 , thank you for filing the report (and #54251).

Hi, @nickdesaulniers , nice to see you here :)

Given the test cases, I can definitely reproduce a crash w/ ToT.

IIUC, it looks like the blockaddress is being converted from: i64* bitcast (i8* blockaddress(@main, %redirected) to i64*) to i64* inttoptr (i32 1 to i64*) which looks curious. I just saw something similar in D120781.

@efriedma-quic explains here that BasicBlocks that are not statically reachable have their blockaddresses converted to arbitrary i32 1 Constants.

I think we should not consider a BasicBlock unreachable if it has its address taken, and that address escapes the current Function.

Yeah, combined with your comment in #54328 , it makes sense to me.
(As said in #54251 ) maybe we could give users a hint. Crash during compilation might not look so friendly :)

@nickdesaulniers
Copy link
Member

nickdesaulniers added a commit that referenced this issue Mar 18, 2022
[SCCP] do not clean up dead blocks that have their address taken

Fixes a crash observed in IPSCCP.

Because the SCCPSolver has already internalized BlockAddresses as
Constants or ConstantExprs, we don't want to try to update their Values
in the ValueLatticeElement. Instead, continue to propagate these
BlockAddress Constants, continue converting BasicBlocks to unreachable,
but don't delete the "dead" BasicBlocks which happen to have their
address taken.  Leave replacing the BlockAddresses to another pass.

Fixes: #54238
Fixes: #54251

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D121744
mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this issue Oct 7, 2022
[SCCP] do not clean up dead blocks that have their address taken

Fixes a crash observed in IPSCCP.

Because the SCCPSolver has already internalized BlockAddresses as
Constants or ConstantExprs, we don't want to try to update their Values
in the ValueLatticeElement. Instead, continue to propagate these
BlockAddress Constants, continue converting BasicBlocks to unreachable,
but don't delete the "dead" BasicBlocks which happen to have their
address taken.  Leave replacing the BlockAddresses to another pass.

Fixes: llvm/llvm-project#54238
Fixes: llvm/llvm-project#54251

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D121744
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid Resolved as invalid, i.e. not a bug llvm:crash llvm:optimizations
Projects
None yet
Development

No branches or pull requests

4 participants