[llvm-bugs] [Bug 50973] New: [SimpleLoopUnswitch] Assertion `!NodePtr->isKnownSentinel()' failed when catchswitch BB is cloned
via llvm-bugs
llvm-bugs at lists.llvm.org
Sat Jul 3 17:34:43 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=50973
Bug ID: 50973
Summary: [SimpleLoopUnswitch] Assertion
`!NodePtr->isKnownSentinel()' failed when catchswitch
BB is cloned
Product: libraries
Version: trunk
Hardware: All
OS: All
Status: NEW
Severity: release blocker
Priority: P
Component: Scalar Optimizations
Assignee: unassignedbugs at nondot.org
Reporter: aheejin at gmail.com
CC: chandlerc at gmail.com, llvm-bugs at lists.llvm.org,
rnk at google.com
Running
$ opt -simple-loop-unswitch -enable-nontrivial-unswitch test.ll
When test.ll is
```
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-emscripten"
declare i32 @__gxx_wasm_personality_v0(...)
declare void @foo()
define void @test(i1 %arg) personality i8* bitcast (i32 (...)*
@__gxx_wasm_personality_v0 to i8*) {
entry:
br label %while.body
while.body: ; preds = %cleanup, %entry
br i1 %arg, label %if.end, label %if.then
if.then: ; preds = %while.body
br label %if.end
if.end: ; preds = %if.then,
%while.body
invoke void @foo()
to label %cleanup unwind label %catch.dispatch
catch.dispatch: ; preds = %invoke.cont,
%if.end
%0 = catchswitch within none [label %catch] unwind to caller
catch: ; preds = %catch.dispatch
%1 = catchpad within %0 [i8* null]
unreachable
cleanup: ; preds = %invoke.cont
br label %while.body
}
```
crashes with the error message
```
opt:
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/ADT/ilist_iterator.h:138:
llvm::ilist_iterator::reference
llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true,
false, void>, false, false>::operator*() const [OptionsT =
llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>,
IsReverse = false, IsConst = false]: Assertion `!NodePtr->isKnownSentinel()'
failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash
backtrace.
Stack dump:
0. Program arguments:
/usr/local/google/home/aheejin/llvm-git/install.debug/bin/opt
-simple-loop-unswitch -enable-nontrivial-unswitch reduced.ll
#0 0x00007f81093eecaa llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Support/Unix/Signals.inc:565:11
#1 0x00007f81093eee5b PrintStackTraceSignalHandler(void*)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Support/Unix/Signals.inc:632:1
#2 0x00007f81093ed673 llvm::sys::RunSignalHandlers()
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Support/Signals.cpp:76:5
#3 0x00007f81093ef495 SignalHandler(int)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Support/Unix/Signals.inc:407:1
#4 0x00007f810dea6140 __restore_rt
(/lib/x86_64-linux-gnu/libpthread.so.0+0x14140)
#5 0x00007f8108c3fce1 raise ./signal/../sysdeps/unix/sysv/linux/raise.c:51:1
#6 0x00007f8108c29537 abort ./stdlib/abort.c:81:7
#7 0x00007f8108c2940f get_sysdep_segment_value ./intl/loadmsgcat.c:509:8
#8 0x00007f8108c2940f _nl_load_domain ./intl/loadmsgcat.c:970:34
#9 0x00007f8108c38662 (/lib/x86_64-linux-gnu/libc.so.6+0x34662)
#10 0x00007f810ae1350f
llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true,
false, void>, false, false>::operator*() const
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/ADT/ilist_iterator.h:0:5
#11 0x00007f810ae630c5
llvm::simplify_type<llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction,
true, false, void>, false, false>
>::getSimplifiedValue(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction,
true, false, void>, false, false> const&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/ADT/ilist_iterator.h:189:64
#12 0x00007f810ae677e5 llvm::isa_impl_wrap<llvm::PHINode,
llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true,
false, void>, false, false> const,
llvm::Instruction*>::doit(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction,
true, false, void>, false, false> const&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/Support/Casting.h:123:27
#13 0x00007f810ae56405 bool llvm::isa<llvm::PHINode,
llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true,
false, void>, false, false>
>(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction,
true, false, void>, false, false> const&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/Support/Casting.h:142:3
#14 0x00007f810ae509d4 SplitBlockImpl(llvm::BasicBlock*, llvm::Instruction*,
llvm::DomTreeUpdater*, llvm::DominatorTree*, llvm::LoopInfo*,
llvm::MemorySSAUpdater*, llvm::Twine const&, bool)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:769:10
#15 0x00007f810ae501c7 llvm::SplitBlock(llvm::BasicBlock*, llvm::Instruction*,
llvm::DominatorTree*, llvm::LoopInfo*, llvm::MemorySSAUpdater*, llvm::Twine
const&, bool)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:816:3
#16 0x00007f810c0146ca buildClonedLoopBlocks(llvm::Loop&, llvm::BasicBlock*,
llvm::BasicBlock*, llvm::ArrayRef<llvm::BasicBlock*>, llvm::BasicBlock*,
llvm::BasicBlock*, llvm::BasicBlock*, llvm::SmallDenseMap<llvm::BasicBlock*,
llvm::BasicBlock*, 16u, llvm::DenseMapInfo<llvm::BasicBlock*>,
llvm::detail::DenseMapPair<llvm::BasicBlock*, llvm::BasicBlock*> > const&,
llvm::ValueMap<llvm::Value const*, llvm::WeakTrackingVH,
llvm::ValueMapConfig<llvm::Value const*, llvm::sys::SmartMutex<false> > >&,
llvm::SmallVectorImpl<llvm::cfg::Update<llvm::BasicBlock*> >&,
llvm::AssumptionCache&, llvm::DominatorTree&, llvm::LoopInfo&,
llvm::MemorySSAUpdater*)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:1120:11
#17 0x00007f810c012292 unswitchNontrivialInvariants(llvm::Loop&,
llvm::Instruction&, llvm::ArrayRef<llvm::Value*>,
llvm::SmallVectorImpl<llvm::BasicBlock*>&, llvm::IVConditionInfo&,
llvm::DominatorTree&, llvm::LoopInfo&, llvm::AssumptionCache&,
llvm::function_ref<void (bool, bool, llvm::ArrayRef<llvm::Loop*>)>,
llvm::ScalarEvolution*, llvm::MemorySSAUpdater*)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:2154:25
#18 0x00007f810c00caa9 unswitchBestCondition(llvm::Loop&, llvm::DominatorTree&,
llvm::LoopInfo&, llvm::AssumptionCache&, llvm::AAResults&,
llvm::TargetTransformInfo&, llvm::function_ref<void (bool, bool,
llvm::ArrayRef<llvm::Loop*>)>, llvm::ScalarEvolution*, llvm::MemorySSAUpdater*)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:2961:3
#19 0x00007f810c00ab8c unswitchLoop(llvm::Loop&, llvm::DominatorTree&,
llvm::LoopInfo&, llvm::AssumptionCache&, llvm::AAResults&,
llvm::TargetTransformInfo&, bool, llvm::function_ref<void (bool, bool,
llvm::ArrayRef<llvm::Loop*>)>, llvm::ScalarEvolution*, llvm::MemorySSAUpdater*)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:3037:7
#20 0x00007f810c00a84a llvm::SimpleLoopUnswitchPass::run(llvm::Loop&,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:3090:7
#21 0x00007f810e153297 llvm::detail::PassModel<llvm::Loop,
llvm::SimpleLoopUnswitchPass, llvm::PreservedAnalyses,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManagerInternal.h:85:17
#22 0x00007f810be16032 llvm::Optional<llvm::PreservedAnalyses>
llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop,
llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&,
llvm::LPMUpdater&>::runSinglePass<llvm::Loop,
std::__1::unique_ptr<llvm::detail::PassConcept<llvm::Loop,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>,
std::__1::default_delete<llvm::detail::PassConcept<llvm::Loop,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&> > > >(llvm::Loop&,
std::__1::unique_ptr<llvm::detail::PassConcept<llvm::Loop,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>,
std::__1::default_delete<llvm::detail::PassConcept<llvm::Loop,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&> > >&,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&,
llvm::PassInstrumentation&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h:378:8
#23 0x00007f810be14cfa llvm::PassManager<llvm::Loop,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&,
llvm::LPMUpdater&>::runWithoutLoopNestPasses(llvm::Loop&,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/LoopPassManager.cpp:143:10
#24 0x00007f810be14771 llvm::PassManager<llvm::Loop,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&,
llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&,
llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/LoopPassManager.cpp:0:32
#25 0x00007f810e0d7207 llvm::detail::PassModel<llvm::Loop,
llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop,
llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&,
llvm::LPMUpdater&>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Loop,
llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&,
llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop,
llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&,
llvm::LPMUpdater&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManagerInternal.h:85:17
#26 0x00007f810be153bd llvm::FunctionToLoopPassAdaptor::run(llvm::Function&,
llvm::AnalysisManager<llvm::Function>&)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/Transforms/Scalar/LoopPassManager.cpp:279:14
#27 0x00007f810e156747 llvm::detail::PassModel<llvm::Function,
llvm::FunctionToLoopPassAdaptor, llvm::PreservedAnalyses,
llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&,
llvm::AnalysisManager<llvm::Function>&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManagerInternal.h:85:17
#28 0x00007f8109c2be2d llvm::PassManager<llvm::Function,
llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&,
llvm::AnalysisManager<llvm::Function>&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManager.h:509:16
#29 0x00007f810e14a887 llvm::detail::PassModel<llvm::Function,
llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >,
llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>
>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManagerInternal.h:85:17
#30 0x00007f8109c2ab03 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&,
llvm::AnalysisManager<llvm::Module>&)
/usr/local/google/home/aheejin/llvm-git/llvm/lib/IR/PassManager.cpp:117:14
#31 0x00000000002b7547 llvm::detail::PassModel<llvm::Module,
llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses,
llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&,
llvm::AnalysisManager<llvm::Module>&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManagerInternal.h:85:17
#32 0x00007f8109c2af7d llvm::PassManager<llvm::Module,
llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&,
llvm::AnalysisManager<llvm::Module>&)
/usr/local/google/home/aheejin/llvm-git/llvm/include/llvm/IR/PassManager.h:509:16
#33 0x00000000002813f7 llvm::runPassPipeline(llvm::StringRef, llvm::Module&,
llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*,
llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef,
llvm::ArrayRef<llvm::StringRef>, llvm::opt_tool::OutputKind,
llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool)
/usr/local/google/home/aheejin/llvm-git/llvm/tools/opt/NewPMDriver.cpp:457:3
#34 0x00000000002cb10e main
/usr/local/google/home/aheejin/llvm-git/llvm/tools/opt/opt.cpp:830:12
#35 0x00007f8108c2ad0a __libc_start_main ./csu/../csu/libc-start.c:308:16
#36 0x000000000027a77a _start
(/usr/local/google/home/aheejin/llvm-git/install.debug/bin/opt+0x27a77a)
Aborted
```
The reason this crash is while we are cloning loop exit blocks, we try to clone
a 'catchswitch' BB here:
https://github.com/llvm/llvm-project/blob/89c1c64cc3170a05a881bb9954feafc3edca6704/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp#L1115-L1120
But 'catchswitch' BB cannot be cloned and its predecessors cannot be split,
because tokens can't be phi'd. The old LoopUnswitch pass avoids this by bailing
out if BasicBlock::canSplitPredecessors
(https://github.com/llvm/llvm-project/blob/89c1c64cc3170a05a881bb9954feafc3edca6704/llvm/lib/IR/BasicBlock.cpp#L350-L360)
returns true:
https://github.com/llvm/llvm-project/blob/89c1c64cc3170a05a881bb9954feafc3edca6704/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp#L706-L707
1. By the way, I am not familiar with SimpleLoopUnswitch pass.. Why do we need
to clone loop exit blocks? Would only cloning the loop blocks and let the
cloned loops merge in (non-cloned) loop exit blocks not work?
2. I tried to insert BasicBlock::canSplitPredecessors check to
SimpleLoopUnswitch too, but it was hard to find the right place. Checking it
right before splitting the exit blocks wouldn't work because we have already
cleaned all loop blocks by then. The old LoopUnswitch pass checks it before
doing any transformation and does not optimize any loop with 'catchswitch' exit
blocks. Should we do a similar thing too?
3. It looks this bug existed from the beginning of SimpleLoopUnswitch pass, so
I am rather surprised this hasn't been hit by WinEH users. Reid, is this code
pass not being used by WinEH users? Or the way WinEH code is generated makes it
not vulnerable to this or something?
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210704/71464cc8/attachment-0001.html>
More information about the llvm-bugs
mailing list