Bug type: crash
Component: ValueTracking
Bug location: llvm/lib/Analysis/ValueTracking.cpp: llvm::getUnderlyingObjectAggressive
Issue title: Crash on wasm-ld (failed Received SIGSEGV (-11))
Labels: crash
llvm:analysis
Reported by: yogisalomo

I came across this error when trying to build wasm artifact of [this repository](https://github.com/daquexian/onnx-simplifier) ( branch `v0.4.36` ) using ninja.

The `emsdk` version that I used was 3.1.72.

```
: && /home/yogisalomo/emsdk/upstream/emscripten/em++ -O3 -DNDEBUG -s ALLOW_MEMORY_GROWTH=1 -s EXIT_RUNTIME=1 -s FORCE_FILESYSTEM=1 -s MODULARIZE=1 -s 'EXPORT_NAME="create_onnxsim"' -s 'EXPORTED_RUNTIME_METHODS=[FS,ccall,cwrap,callMain]' -s EXPORTED_FUNCTIONS=[_main] CMakeFiles/onnxsim_bin.dir/onnxsim/bin/onnxsim_bin.cpp.o CMakeFiles/onnxsim_bin.dir/onnxsim/bin/onnxsim_option.cpp.o -o onnxsim.js  libonnxsim.a  third_party/onnx-optimizer/libonnx_optimizer.a  libonnxruntime_webassembly.a && :
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: /home/yogisalomo/emsdk/upstream/bin/wasm-ld -o onnxsim.wasm -L/home/yogisalomo/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten CMakeFiles/onnxsim_bin.dir/onnxsim/bin/onnxsim_bin.cpp.o CMakeFiles/onnxsim_bin.dir/onnxsim/bin/onnxsim_option.cpp.o libonnxsim.a third_party/onnx-optimizer/libonnx_optimizer.a libonnxruntime_webassembly.a -lGL-getprocaddr -lal -lhtml5 -lstubs -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpuew4mr6alibemscripten_js_symbols.so --strip-debug --export=_emscripten_stack_alloc --export=__get_temp_ret --export=__set_temp_ret --export=__funcs_on_exit --export=__wasm_call_ctors --export=emscripten_stack_get_current --export=_emscripten_stack_restore --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --max-memory=2147483648 --initial-heap=16777216 --no-entry --table-base=1 --global-base=1024
1.      Running pass "cgscc(function-attrs)" on module "ld-temp.o"
 #0 0x00005a6692b63088 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x1083088)
 #1 0x00005a6692b603ee llvm::sys::RunSignalHandlers() (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x10803ee)
 #2 0x00005a6692b63c7f SignalHandler(int) Signals.cpp:0:0
 #3 0x000079f165242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00005a66941e9d3c checkFunctionMemoryAccess(llvm::Function&, bool, llvm::AAResults&, llvm::SmallSetVector<llvm::Function*, 8u> const&) (.llvm.13958950707188126733) FunctionAttrs.cpp:0:0
 #5 0x00005a66941eb09a llvm::SmallSet<llvm::Function*, 8u, std::__2::less<llvm::Function*>> deriveAttrsInPostOrder<llvm::PostOrderFunctionAttrsPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&)::$_0&>(llvm::ArrayRef<llvm::Function*>, llvm::PostOrderFunctionAttrsPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&)::$_0&, bool) FunctionAttrs.cpp:0:0
 #6 0x00005a66941ea819 llvm::PostOrderFunctionAttrsPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x270a819)
 #7 0x00005a6693a8370d llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::PostOrderFunctionAttrsPass, 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&) PassBuilder.cpp:0:0
 #8 0x00005a6694de42f3 llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x33042f3)
 #9 0x00005a6693a605fd llvm::detail::PassModel<llvm::Module, llvm::ModuleToPostOrderCGSCCPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) PassBuilder.cpp:0:0
#10 0x00005a6695695c9a llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x3bb5c9a)
#11 0x00005a66939ba386 llvm::lto::opt(llvm::lto::Config const&, llvm::TargetMachine*, unsigned int, llvm::Module&, bool, llvm::ModuleSummaryIndex*, llvm::ModuleSummaryIndex const*, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>> const&) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x1eda386)
#12 0x00005a66939bc7e3 llvm::lto::backend(llvm::lto::Config const&, std::__2::function<llvm::Expected<std::__2::unique_ptr<llvm::CachedFileStream, std::__2::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>, unsigned int, llvm::Module&, llvm::ModuleSummaryIndex&) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x1edc7e3)
#13 0x00005a66939a602f llvm::lto::LTO::runRegularLTO(std::__2::function<llvm::Expected<std::__2::unique_ptr<llvm::CachedFileStream, std::__2::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x1ec602f)
#14 0x00005a66939a52ad llvm::lto::LTO::run(std::__2::function<llvm::Expected<std::__2::unique_ptr<llvm::CachedFileStream, std::__2::default_delete<llvm::CachedFileStream>>> (unsigned int, llvm::Twine const&)>, llvm::FileCache) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x1ec52ad)
#15 0x00005a6693014dd3 lld::wasm::BitcodeCompiler::compile() (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x1534dd3)
#16 0x00005a66930184b4 lld::wasm::SymbolTable::compileBitcodeFiles() (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x15384b4)
#17 0x00005a6692ffe90c lld::wasm::(anonymous namespace)::LinkerDriver::linkerMain(llvm::ArrayRef<char const*>) Driver.cpp:0:0
#18 0x00005a6692ff88f8 lld::wasm::link(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, bool, bool) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x15188f8)
#19 0x00005a6692b660f0 lld::unsafeLldMain(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, llvm::ArrayRef<lld::DriverDef>, bool) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0x10860f0)
#20 0x00005a6692aa64d1 lld_main(int, char**, llvm::ToolContext const&) (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0xfc64d1)
#21 0x00005a6692aa6ec4 main (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0xfc6ec4)
#22 0x000079f165229d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#23 0x000079f165229e40 call_init ./csu/../csu/libc-start.c:128:20
#24 0x000079f165229e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#25 0x00005a6692a1336a _start (/home/yogisalomo/emsdk/upstream/bin/wasm-ld+0xf3336a)
em++: error: '/home/yogisalomo/emsdk/upstream/bin/wasm-ld -o onnxsim.wasm -L/home/yogisalomo/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten CMakeFiles/onnxsim_bin.dir/onnxsim/bin/onnxsim_bin.cpp.o CMakeFiles/onnxsim_bin.dir/onnxsim/bin/onnxsim_option.cpp.o libonnxsim.a third_party/onnx-optimizer/libonnx_optimizer.a libonnxruntime_webassembly.a -lGL-getprocaddr -lal -lhtml5 -lstubs -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpuew4mr6alibemscripten_js_symbols.so --strip-debug --export=_emscripten_stack_alloc --export=__get_temp_ret --export=__set_temp_ret --export=__funcs_on_exit --export=__wasm_call_ctors --export=emscripten_stack_get_current --export=_emscripten_stack_restore --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --max-memory=2147483648 --initial-heap=16777216 --no-entry --table-base=1 --global-base=1024' failed (received SIGSEGV (-11))
ninja: build stopped: subcommand failed.
```

Please let me know if there's any other detail that I need to add to help solving this issue. Thank you.

Comments: author: aheejin
body: How can I reproduce it? I can't find any instructions in that repo. I cloned the repo and ran `./build_wasm.sh`, but it says
```console
aheejin@aheejin:~/test/onnx-simplifier$ ./build_wasm.sh 
+ command -v emcmake
+++ dirname -- ./build_wasm.sh
++ cd -- .
++ pwd
+ SCRIPT_DIR=/usr/local/google/home/aheejin/test/onnx-simplifier
+ WITH_NODE_RAW_FS=OFF
+ cd /usr/local/google/home/aheejin/test/onnx-simplifier
+ pushd third_party/onnxruntime/cmake/external/protobuf/cmake
./build_wasm.sh: line 11: pushd: third_party/onnxruntime/cmake/external/protobuf/cmake: No such file or directory
```
author: yogisalomo
body: @aheejin thank you for responding. From the error message, seems like you didn't clone the repository recursively and therefore missing the files of the third_party repositories. Can you please try that?
author: aheejin
body: Sorry for the long wait! In case you use emscripten releases, 4.0.1 release contains the fix: https://github.com/emscripten-core/emsdk/releases/tag/4.0.1

Fix patch:
commit 5a90168fa34e15b544d7749ca4d247a16d360119
Author: Heejin Ahn <aheejin@gmail.com>
Date:   Wed Jan 15 11:53:51 2025 -0800

    [ValueTracking] Provide getUnderlyingObjectAggressive fallback (#123019)
    
    This callsite assumes `getUnderlyingObjectAggressive` returns a non-null
    pointer:
    
    https://github.com/llvm/llvm-project/blob/273a94b3d5a78cd9122c7b3bbb5d5a87147735d2/llvm/lib/Transforms/IPO/FunctionAttrs.cpp#L124
    
    But it can return null when there are cycles in the value chain so there
    is no more `Worklist` item anymore to explore, in which case it just
    returns `Object` at the end of the function without ever setting it:
    https://github.com/llvm/llvm-project/blob/9b5857a68381652dbea2a0c9efa734b6c4cf38c9/llvm/lib/Analysis/ValueTracking.cpp#L6866-L6867
    https://github.com/llvm/llvm-project/blob/9b5857a68381652dbea2a0c9efa734b6c4cf38c9/llvm/lib/Analysis/ValueTracking.cpp#L6889
    
    `getUnderlyingObject` does not seem to return null either judging by
    looking at its code and its callsites, so I think it is not likely to be
    the author's intention that `getUnderlyingObjectAggressive` returns
    null.
    
    So this checks whether `Object` is null at the end, and if so, falls
    back to the original first value.
    
    ---
    
    The test case here was reduced by bugpoint and further reduced manually,
    but I find it hard to reduce it further.
    
    To trigger this bug, the memory operation should not be reachable from
    the entry BB, because the `phi`s should form a cycle without introducing
    another value from the entry. I tried a minimal `phi` cycle with three
    BBs (entry BB + two BBs in a cycle), but it was skipped here:
    https://github.com/llvm/llvm-project/blob/273a94b3d5a78cd9122c7b3bbb5d5a87147735d2/llvm/lib/Transforms/IPO/FunctionAttrs.cpp#L121-L122
    To get the result that's not `ModRefInfo::NoModRef`, the length of `phi`
    chain needed to be greater than the `MaxLookup` value set in this
    function:
    
    https://github.com/llvm/llvm-project/blob/02403f4e450b86d93197dd34045ff40a34b21494/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L744
    
    But just lengthening the `phi` chain to 8 didn't trigger the same error
    in `getUnderlyingObjectAggressive` because `getUnderlyingObject` here
    passes through a single-chain `phi`s so not all `phi`s end up in
    `Visited`:
    
    https://github.com/llvm/llvm-project/blob/9b5857a68381652dbea2a0c9efa734b6c4cf38c9/llvm/lib/Analysis/ValueTracking.cpp#L6863
    
    So I just submit here the smallest test case I managed to create.
    
    ---
    
    Fixes #117308 and fixes #122166.

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1bab9b32525c..1853b1c67159 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6886,7 +6886,7 @@ const Value *llvm::getUnderlyingObjectAggressive(const Value *V) {
       return FirstObject;
   } while (!Worklist.empty());
 
-  return Object;
+  return Object ? Object : FirstObject;
 }
 
 /// This is the function that does the work of looking through basic


Regression tests:
file: llvm/test/Transforms/FunctionAttrs/phi_cycle.ll
commands: opt -passes=function-attrs -S < %s
tests: test_name: <module>
test_body: 
; Regression test for a null-returning bug of getUnderlyingObjectAggressive().
; This should not crash.
define void @phi_cycle() {
bb:
  unreachable

bb1:                                              ; preds = %bb17
  br label %bb2

bb2:                                              ; preds = %bb5, %bb1
  %phi = phi ptr [ %phi6, %bb1 ], [ %phi6, %bb5 ]
  br i1 poison, label %bb4, label %bb3

bb3:                                              ; preds = %bb2
  %getelementptr = getelementptr inbounds i8, ptr %phi, i32 poison
  br label %bb5

bb4:                                              ; preds = %bb2
  br label %bb7

bb5:                                              ; preds = %bb15, %bb3
  %phi6 = phi ptr [ %getelementptr, %bb3 ], [ %phi16, %bb15 ]
  br i1 poison, label %bb17, label %bb2

bb7:                                              ; preds = %bb15, %bb4
  %phi8 = phi ptr [ %phi, %bb4 ], [ %phi16, %bb15 ]
  br i1 poison, label %bb11, label %bb9

bb9:                                              ; preds = %bb7
  %getelementptr10 = getelementptr inbounds i8, ptr %phi8, i32 1
  store i8 poison, ptr %phi8, align 1
  br label %bb15

bb11:                                             ; preds = %bb7
  br i1 poison, label %bb13, label %bb12

bb12:                                             ; preds = %bb11
  br label %bb13

bb13:                                             ; preds = %bb12, %bb11
  %getelementptr14 = getelementptr inbounds i8, ptr %phi8, i32 poison
  br label %bb15

bb15:                                             ; preds = %bb13, %bb9
  %phi16 = phi ptr [ %getelementptr14, %bb13 ], [ %getelementptr10, %bb9 ]
  br i1 poison, label %bb5, label %bb7

bb17:                                             ; preds = %bb5
  br label %bb1
}