| Issue |
185111
|
| Summary |
[InstCombine] `foldBitCastSelect` crashes on bitcast of select with fast-math flags
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
cardigan1008
|
Here is a crash case when reviewing https://github.com/llvm/llvm-project/pull/179042:
```llvm
define <2 x float> @bitcast_v2i32_select_to_v2f32_const_lhs(double %arg, <2 x i32> %vec) {
%cmp = fcmp one double %arg, 0x7FF0000000000000
%s.0.i.i = select nnan i1 %cmp, <2 x i32> <i32 0, i32 2146959360>, <2 x i32> %vec
%astype13.i.i = bitcast <2 x i32> %s.0.i.i to <2 x float>
ret <2 x float> %astype13.i.i
}
```
Compiler Explorer: https://alive2.llvm.org/ce/z/KM6Zv_
Crash:
```sh
While deleting: i1 %cmp
Use still stuck around after Def is destroyed: <badref> = select i1 %cmp, <2 x i32> <i32 0, i32 2146959360>, <2 x i32> %vec
Uses remain when a value is destroyed!
UNREACHABLE executed at llvm/lib/IR/Value.cpp:102!
```
Backtrace:
```sh
Stack dump:
0. Program arguments: bin/opt -S -S -passes=instcombine /data/tmp/tmpk4vajafo/orig.ll
#0 0x000072f4d793665c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (bin/../lib/libLLVMSupport.so.23.0git+0x33665c)
#1 0x000072f4d7936acf PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
#2 0x000072f4d7933112 llvm::sys::RunSignalHandlers() (bin/../lib/libLLVMSupport.so.23.0git+0x333112)
#3 0x000072f4d7935632 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#4 0x000072f4d7245330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#5 0x000072f4d729eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#6 0x000072f4d729eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
#7 0x000072f4d729eb2c pthread_kill ./nptl/pthread_kill.c:89:10
#8 0x000072f4d724527e raise ./signal/../sysdeps/posix/raise.c:27:6
#9 0x000072f4d72288ff abort ./stdlib/abort.c:81:7
#10 0x000072f4d77ae5ea bindingsErrorHandler(void*, char const*, bool) ErrorHandling.cpp:0:0
#11 0x000072f4cb9cd466 llvm::Value::~Value() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x5cd466)
#12 0x000072f4cb9cba49 llvm::User::~User() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x5cba49)
#13 0x000072f4cb842251 llvm::Instruction::~Instruction() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x442251)
#14 0x000072f4cb9cc7fe llvm::CmpInst::~CmpInst() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x5cc7fe)
#15 0x000072f4cb9cd96a llvm::FCmpInst::~FCmpInst() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x5cd96a)
#16 0x000072f4cb9ce737 llvm::Value::deleteValue() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x5ce737)
#17 0x000072f4cb5e3630 llvm::ilist_alloc_traits<llvm::Instruction>::deleteNode(llvm::Instruction*) (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1e3630)
#18 0x000072f4cb5eebc7 llvm::iplist_impl<llvm::simple_ilist<llvm::Instruction, llvm::ilist_iterator_bits<true>, llvm::ilist_parent<llvm::BasicBlock>>, llvm::SymbolTableListTraits<llvm::Instruction, llvm::ilist_iterator_bits<true>, llvm::ilist_parent<llvm::BasicBlock>>>::erase(llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void, true, llvm::BasicBlock>, false, false>) (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1eebc7)
#19 0x000072f4cb5ec9dc llvm::iplist_impl<llvm::simple_ilist<llvm::Instruction, llvm::ilist_iterator_bits<true>, llvm::ilist_parent<llvm::BasicBlock>>, llvm::SymbolTableListTraits<llvm::Instruction, llvm::ilist_iterator_bits<true>, llvm::ilist_parent<llvm::BasicBlock>>>::erase(llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void, true, llvm::BasicBlock>, false, false>, llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void, true, llvm::BasicBlock>, false, false>) (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1ec9dc)
#20 0x000072f4cb5ea676 llvm::iplist_impl<llvm::simple_ilist<llvm::Instruction, llvm::ilist_iterator_bits<true>, llvm::ilist_parent<llvm::BasicBlock>>, llvm::SymbolTableListTraits<llvm::Instruction, llvm::ilist_iterator_bits<true>, llvm::ilist_parent<llvm::BasicBlock>>>::clear() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1ea676)
#21 0x000072f4cb5e59ae llvm::BasicBlock::~BasicBlock() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1e59ae)
#22 0x000072f4cb5ed220 llvm::ilist_alloc_traits<llvm::BasicBlock>::deleteNode(llvm::BasicBlock*) (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1ed220)
#23 0x000072f4cb5eaf37 llvm::iplist_impl<llvm::simple_ilist<llvm::BasicBlock>, llvm::SymbolTableListTraits<llvm::BasicBlock>>::erase(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::BasicBlock, true, false, void, false, void>, false, false>) (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1eaf37)
#24 0x000072f4cb5e5f6d llvm::BasicBlock::eraseFromParent() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x1e5f6d)
#25 0x000072f4cb7fe256 llvm::Function::deleteBodyImpl(bool) (bin/../lib/../lib/libLLVMCore.so.23.0git+0x3fe256)
#26 0x000072f4cb7fa85b llvm::Function::dropAllReferences() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x3fa85b)
#27 0x000072f4cb917df3 llvm::Module::dropAllReferences() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x517df3)
#28 0x000072f4cb915828 llvm::Module::~Module() (bin/../lib/../lib/libLLVMCore.so.23.0git+0x515828)
#29 0x000072f4cc5743f8 std::default_delete<llvm::Module>::operator()(llvm::Module*) const (bin/../lib/../lib/libLLVMAsmParser.so.23.0git+0x1233f8)
#30 0x000072f4cc572b12 std::unique_ptr<llvm::Module, std::default_delete<llvm::Module>>::~unique_ptr() (bin/../lib/../lib/libLLVMAsmParser.so.23.0git+0x121b12)
#31 0x000072f4cc56fb3b llvm::parseAssembly(llvm::MemoryBufferRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::SlotMapping*, llvm::function_ref<std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> (llvm::StringRef, llvm::StringRef)>, llvm::AsmParserContext*) (bin/../lib/../lib/libLLVMAsmParser.so.23.0git+0x11eb3b)
#32 0x000072f4d4b092df llvm::parseIR(llvm::MemoryBufferRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::ParserCallbacks, llvm::AsmParserContext*) (bin/../lib/../lib/libLLVMIRReader.so.23.0git+0x62df)
#33 0x000072f4d4b0959b llvm::parseIRFile(llvm::StringRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::ParserCallbacks, llvm::AsmParserContext*) (bin/../lib/../lib/libLLVMIRReader.so.23.0git+0x659b)
#34 0x000072f4d7b7e439 optMain (bin/../lib/libLLVMOptDriver.so.23.0git+0x5f439)
#35 0x00006163f22941e8 main (bin/opt+0x11e8)
#36 0x000072f4d722a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#37 0x000072f4d722a28b call_init ./csu/../csu/libc-start.c:128:20
#38 0x000072f4d722a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#39 0x00006163f22940a5 _start (bin/opt+0x10a5)
```
> Note: This is a review assisted with a self-built agent. The reproducer was validated manually. Please let me know if anything is wrong.
**Bug Triggering Analysis:**
The provided test case triggers a crash in `opt` when running the `instcombine` pass. The crash occurs because the `foldBitCastSelect` function creates a new `SelectInst` and replaces the uses of the original `SelectInst` with the new one, but it does not properly handle the deletion of the original `SelectInst` or its operands. Specifically, the original `SelectInst` is still being used by something (likely the `BitCastInst` that was being folded), leading to a "Uses remain when a value is destroyed!" assertion failure when the `SelectInst` is destroyed.
**Fix Weakness Analysis:**
The weakness in the fix is that it creates a new `SelectInst` and returns it to replace the `BitCastInst`, but it does not properly update the uses of the original `SelectInst` or ensure that it can be safely deleted. The original `SelectInst` is still an operand of the `BitCastInst` being processed, and when the `BitCastInst` is replaced and deleted, the `SelectInst` might also be deleted if it has no other uses. However, the new `SelectInst` created by `foldBitCastSelect` uses the same condition operand (`%cmp`) as the original `SelectInst`. If the original `SelectInst` is deleted, it might cause issues with the condition operand or other related values. The crash trace shows that the condition operand (`%cmp`) is being deleted while it is still used by the original `SelectInst`, which indicates a use-after-free or similar issue caused by improper instruction replacement and deletion in `InstCombine`.
cc @arsenm
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs