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

Crash in Inliner when using WebAssembly exception handling #55803

Closed
dschuff opened this issue Jun 1, 2022 · 3 comments
Closed

Crash in Inliner when using WebAssembly exception handling #55803

dschuff opened this issue Jun 1, 2022 · 3 comments

Comments

@dschuff
Copy link
Member

dschuff commented Jun 1, 2022

The attached program crashes in the inliner when wasm exception handling is enabled.
It was reduced with creduce, but I haven't attempted to reduce it manually yet.

class a;
class b {
public:
  a *operator->();
};
class c {
  void m_fn1();
  void e();
};
class f {
public:
  void g();
};
class a {
public:
  int h() { am.g(); return 0;}
  f am;
};
void c::e() {
  c *ao;
  bool ap = false;
  try {
    m_fn1();
    try {
      b d;
      int aq = d->h();
      if (aq)
        ap = true;
      m_fn1();
    } catch (int) {
    }
  } catch (...) {
    if (ap)
      ao = 0;
  }
}

command:

"/path/to/clang-15" "-cc1" "-triple" "wasm32-unknown-emscripten" "-emit-obj"  "-target-feature" "+exception-handling" "-mllvm" "-wasm-enable-eh"  "-O1"  "-std=gnu++17"  "-fcxx-exceptions" "-fexceptions" "-exception-model=wasm"  "-x" "c++" "repro.cpp"

It gives the following assertion failure:

clang-15: /s/llvm-upstream/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp:667: void HandleInlinedEHPad(llvm::InvokeInst *, llvm::BasicBlock *, llvm::ClonedCodeInfo &): Assertion `UnwindDest->getFirstNonPHI()->isEHPad() && "unexpected BasicBlock!"' 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: /s/emr/install/bin/clang-15 -cc1 -triple wasm32-unknown-emscripten -emit-obj -target-feature +exception-handling -mllvm -wasm-enable-eh -O1 -std=gnu++17 -fcxx-exceptions -fexceptions -exception-model=wasm -x c++ repro.cpp
1.	<eof> parser at end of file
2.	Optimizer
 #0 0x00007fe0fc8b75c3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMSupport.so.15git+0x23f5c3)
 #1 0x00007fe0fc8b527e llvm::sys::RunSignalHandlers() (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMSupport.so.15git+0x23d27e)
 #2 0x00007fe0fc8b7a8a SignalHandler(int) Signals.cpp:0:0
 #3 0x00007fe100878200 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12200)
 #4 0x00007fe0fc1568a1 raise ./signal/../sysdeps/unix/sysv/linux/raise.c:50:1
 #5 0x00007fe0fc140546 abort ./stdlib/abort.c:81:7
 #6 0x00007fe0fc14042f get_sysdep_segment_value ./intl/loadmsgcat.c:509:8
 #7 0x00007fe0fc14042f _nl_load_domain ./intl/loadmsgcat.c:970:34
 #8 0x00007fe0fc14f222 (/lib/x86_64-linux-gnu/libc.so.6+0x31222)
 #9 0x00007fe0fe0213b4 llvm::InlineFunction(llvm::CallBase&, llvm::InlineFunctionInfo&, llvm::AAResults*, bool, llvm::Function*) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMTransformUtils.so.15git+0x1e63b4)
#10 0x00007fe0ff626061 llvm::InlinerPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMipo.so.15git+0x2c6061)
#11 0x00007fe0ff62e4ad llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::InlinerPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) Inliner.cpp:0:0
#12 0x00007fe0fdb0c221 llvm::PassManager<llvm::LazyCallGraph::SCC, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMAnalysis.so.15git+0x36d221)
#13 0x00007fe0ff62e78d llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::PassManager<llvm::LazyCallGraph::SCC, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) Inliner.cpp:0:0
#14 0x00007fe0fdb0fe0b llvm::DevirtSCCRepeatedPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMAnalysis.so.15git+0x370e0b)
#15 0x00007fe0ff62ed4d llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::DevirtSCCRepeatedPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) Inliner.cpp:0:0
#16 0x00007fe0fdb0e57a llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMAnalysis.so.15git+0x36f57a)
#17 0x00007fe0ff62eb0d llvm::detail::PassModel<llvm::Module, llvm::ModuleToPostOrderCGSCCPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) Inliner.cpp:0:0
#18 0x00007fe0fd55ef04 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMCore.so.15git+0x463f04)
#19 0x00007fe0ff628ca6 llvm::ModuleInlinerWrapperPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMipo.so.15git+0x2c8ca6)
#20 0x00007fe0fb799f8d llvm::detail::PassModel<llvm::Module, llvm::ModuleInlinerWrapperPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) PassBuilder.cpp:0:0
#21 0x00007fe0fd55ef04 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libLLVMCore.so.15git+0x463f04)
#22 0x00007fe1002f8de2 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&) BackendUtil.cpp:0:0
#23 0x00007fe1002efee0 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libclangCodeGen.so.15git+0x285ee0)
#24 0x00007fe10069dc94 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) CodeGenAction.cpp:0:0
#25 0x00007fe0fa5f9cf3 clang::ParseAST(clang::Sema&, bool, bool) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/../lib/libclangParse.so.15git+0x66cf3)
#26 0x00007fe0fef180e0 clang::FrontendAction::Execute() (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libclangFrontend.so.15git+0x16b0e0)
#27 0x00007fe0fee888a8 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libclangFrontend.so.15git+0xdb8a8)
#28 0x00007fe1008629b3 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/usr/local/google/home/dschuff/s/emr/install/bin/../lib/libclangFrontendTool.so.15git+0x49b3)
#29 0x0000000000215150 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/s/emr/install/bin/clang-15+0x215150)
#30 0x0000000000213030 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#31 0x0000000000212dc5 main (/s/emr/install/bin/clang-15+0x212dc5)
#32 0x00007fe0fc1417fd __libc_start_main ./csu/../csu/libc-start.c:332:16
#33 0x000000000020ff3a _start (/s/emr/install/bin/clang-15+0x20ff3a)
@llvmbot
Copy link
Collaborator

llvmbot commented Jun 1, 2022

@llvm/issue-subscribers-backend-webassembly

@aheejin aheejin self-assigned this Jun 1, 2022
@aheejin
Copy link
Member

aheejin commented Jun 1, 2022

@dschuff Is it from one of our partners, i.e., how time critical is this?

@dschuff
Copy link
Member Author

dschuff commented Jun 2, 2022

As discussed offline: there's a workaround for the build that this test was derived from, which reduces the urgency. But it's not a great workaround (it's to disable opaque pointers), and it could stop working, so we shouldn't just let this drop for too long.

mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this issue Oct 7, 2022
If an integer PHI has an illegal type (according to the data layout) and
it is only used by `trunc` or `trunc(lshr)` operations, we split the PHI
into various instructions in its predecessors:
https://github.com/llvm/llvm-project/blob/6d1543a16797fa07eecea7e542df5b42422fc721/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp#L1536-L1543

So this can produce code like the following:
Before:
```
pred:
  ...

bb:
  %p = phi i8 [ %somevalue, %pred ], ...
  ...
  %tobool = trunc i8 %p to i1
  use %tobool
  ...
```
In this code, `%p` has an illegal integer type, `i8`, and its only used
in a `trunc` instruction later. In this case this pass puts extraction
code in its predecessors:

After:
```
pred:
  ...
  %t = and i8 %somevalue, 1
  %extract = icmp ne i8 %t, 0

bb:
  %p.new = phi i1 [ %extract, %pred ], ...
  use %p.new instead of %tobool
```

But this doesn't work if `pred` is a `catchswitch` BB because it cannot
have any non-PHI instructions. This CL ensures we bail out in that case.

Fixes llvm/llvm-project#55803.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D127699
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants