llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.84k stars 11.47k forks source link

LoopUnroll fails to unroll forced loop due to inlinable calls, leading to linker errors #88141

Open gburgessiv opened 5 months ago

gburgessiv commented 5 months ago

An AFDO profile roll broke Chromium's build with ThinLTO enabled by introducing linker warnings - which were promoted to errors - about llvm.loop.unroll.enabled loops not being unrolled:

ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-optimization-reducer.h:685:11: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:1316:9: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:813:9: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2124:9: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2149:13: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2154:20: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2185:20: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
ld.lld:  [0;31merror:  [0m../../../../../../../home/chrome-bot/chrome_root/src/v8/src/compiler/turboshaft/machine-optimization-reducer.h:685:11: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

Unfortunately, I can't provide an 'easy' reproducer of the original breakage, as it only occurs with ThinLTO and a specific AutoFDO profile on a very large program.

What I can provide is some information about investigating this locally:

  1. The LoopUnroll pass ran on the loops that did not get unrolled.
  2. The loops that did not get unrolled did have llvm.loop.unroll.enable metadata on them.
  3. The loops that did not get unrolled had call(s) to functions that were deemed inline candidates by UnrollCostEstimator. Moreover, the following criteria were met for at least one call per loop (PrepareForLTO was false):
if (!Call->isNoInline() && TTI.isLoweredToCall(F) &&
     ((F->hasInternalLinkage() && F->hasOneLiveUse()) || PrepareForLTO)) {
  // ...
}

and unrolling is currently always skipped if that's detected in a loop:

  if (UCE.NumInlineCandidates != 0) {
    LLVM_DEBUG(dbgs() << "  Not unrolling loop with inlinable calls.\n");
    return LoopUnrollResult::Unmodified;
  }

I can totally understand the desire to facilitate the inlining of calls like this, but if a user asks for forced unrolling, IMO that should be respected regardless.

I have a potential fix that I'll upload soon.

uazo commented 2 months ago

hello everyone. I am experiencing the same error:

2024-06-26T01:14:08.2571511Z [38570/38578] STAMP obj/chrome/android/chrome_public_apk__size_info.stamp
2024-06-26T01:23:15.2074627Z [38571/38578] SOLINK ./libchrome__combined.so
2024-06-26T01:23:15.2076602Z FAILED: libchrome__combined.so libchrome__combined.so.TOC lib.unstripped/libchrome__combined.so lib.unstripped/libchrome__combined.so.map.gz 
2024-06-26T01:23:15.2105773Z "python3" "../../build/toolchain/gcc_solink_wrapper.py" --readelf="../../third_party/llvm-build/Release+Asserts/bin/llvm-readelf" --nm="../../third_party/llvm-build/Release+Asserts/bin/llvm-nm" --strip=../../third_party/llvm-build/Release+Asserts/bin/llvm-strip  --sofile="./lib.unstripped/libchrome__combined.so" --tocfile="./libchrome__combined.so.TOC" --map-file "./lib.unstripped/libchrome__combined.so.map.gz" --output="./libchrome__combined.so" -- ../../third_party/llvm-build/Release+Asserts/bin/clang++ -shared -Wl,-soname="libchrome__combined.so" -Wl,--version-script=gen/chrome/android/libchrome_linker_script.txt -Wl,--hash-style=gnu -Wl,-soname,libchrome.so --partitioned-library -Werror -fuse-ld=lld -Wl,--fatal-warnings -Wl,--build-id=sha1 -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--icf=all -Wl,--color-diagnostics -Wl,-mllvm,-instcombine-lower-dbg-declare=0 -Wl,-mllvm,-split-threshold-for-reg-with-hint=0 -fexperimental-relative-c++-abi-vtables -Wl,--thinlto-cache-dir=thinlto-cache -Wl,--thinlto-cache-policy=cache_size=10\%:cache_size_bytes=40g:cache_size_files=100000 -flto=thin -Wl,--thinlto-jobs=all -Wl,-mllvm,-import-instr-limit=30 -Wl,-mllvm,-disable-auto-upgrade-debug-info -Wl,-mllvm,-inlinehint-threshold=360 -fwhole-program-vtables -Wl,--no-rosegment -Wl,--undefined-version -Wl,--no-call-graph-profile-sort -Wl,--exclude-libs=libvpx_assembly_arm.a -Wl,-z,max-page-size=16384 --target=aarch64-linux-android26 -Wl,-mllvm,-enable-machine-outliner=never -no-canonical-prefixes -Wl,--warn-shared-textrel -Wl,-O2 -Wl,--gc-sections -Wl,-z,defs -Wl,--as-needed --unwindlib=none -nostdlib++ --sysroot=../../third_party/android_toolchain/ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Wl,-z,force-bti -Wl,--lto-O2 -Wl,--pack-dyn-relocs=android -Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,malloc -Wl,-wrap,memalign -Wl,-wrap,posix_memalign -Wl,-wrap,pvalloc -Wl,-wrap,realloc -Wl,-wrap,valloc -Wl,-wrap,malloc_usable_size -Wl,-wrap,realpath -Wl,-wrap,strdup -Wl,-wrap,strndup -Wl,-wrap,getcwd -Wl,-wrap,asprintf -Wl,-wrap,vasprintf -Wl,--dynamic-linker,/system/bin/linker64 -o "./lib.unstripped/libchrome__combined.so" @"./libchrome__combined.so.rsp" obj/third_party/rust/cxx/v1/lib/libcxx_lib.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libstd_std.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/liballoc_alloc.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libcompiler_builtins_compiler_builtins.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/librustc_std_workspace_core_rustc_std_workspace_core.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libcore_core.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libprofiler_builtins_profiler_builtins.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libcfg_if_cfg_if.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libhashbrown_hashbrown.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/librustc_std_workspace_alloc_rustc_std_workspace_alloc.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libpanic_abort_panic_abort.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/liblibc_libc.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libpanic_unwind_panic_unwind.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libunwind_unwind.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/librustc_demangle_rustc_demangle.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libstd_detect_std_detect.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libaddr2line_addr2line.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libgimli_gimli.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libminiz_oxide_miniz_oxide.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libadler_adler.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libobject_object.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libmemchr_memchr.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libgetopts_getopts.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/librustc_std_workspace_std_rustc_std_workspace_std.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libunicode_width_unicode_width.rlib local_rustc_sysroot/lib/rustlib/aarch64-linux-android/lib/libtest_test.rlib obj/skia/libskia_cbridge_urust_uside.rlib obj/third_party/rust/font_types/v0_5/lib/libfont_types_lib.rlib obj/third_party/rust/bytemuck/v1/lib/libbytemuck_lib.rlib obj/third_party/rust/read_fonts/v0_19/lib/libread_fonts_lib.rlib obj/third_party/rust/skrifa/v0_19/lib/libskrifa_lib.rlib obj/build/rust/chromium_prelude/libchromium.rlib obj/third_party/blink/common/rust_crash/libthird_uparty_sblink_scommon_srust_ucrash_crs.rlib obj/components/qr_code_generator/libcomponents_sqr_ucode_ugenerator_cqr_ucode_ugenerator_uffi_uglue.rlib obj/third_party/rust/qr_code/v2/lib/libqr_code_lib.rlib 
2024-06-26T01:23:15.2131606Z ld.lld: error: ../../v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2158:9: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
2024-06-26T01:23:15.2134697Z ld.lld: error: ../../v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2161:13: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
2024-06-26T01:23:15.2137730Z ld.lld: error: ../../v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h:2521:9: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
2024-06-26T01:23:15.2139826Z clang++: error: linker command failed with exit code 1 (use -v to see invocation)
2024-06-26T01:23:15.2140873Z ninja: build stopped: subcommand failed.
2024-06-26T01:23:15.2847617Z ##[error]Process completed with exit code 1.

the strange thing is that relaunching the build, on the second start-up then, the error disappears. Do you know of a flag that can turn that error into a warning?