<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/88141>88141</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
LoopUnroll fails to unroll forced loop due to inlinable calls, leading to linker errors
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
gburgessiv
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
gburgessiv
</td>
</tr>
</table>
<pre>
An AFDO profile roll broke Chromium's build with ThinLTO enabled by introducing linker warnings - which were promoted to errors - about `llvm.loop.unroll.enable`d 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.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEtv474R_zTMZRBBovw8-OA46yJAdlMUSXtcjMSRxH8oUiUpZ91PXwxlJ862SHsokB6yMLQRH_P4zYP6EUPQrSXaiPmNkLKtRt9SCPogpBTz2yscY-f85m38qnLquNla2O5vH2DwrtGGwDtjoPLumWDXedfrsRdyGaAatVHwomMHj522948PQBYrQwqqI2gbvVNjrW0LRttn8vCC3mrbBriGl07XHbyQJ1bTu0gKogPy3nmex8qNEcQiN-bQZ8a5IRstG5JNKsQiV8DDAayLUBGrmVaQEuVW5LciPz8X-emXXo3KjOE1AGJ-k4vypiz6pJjHeKjPMiH3Hz8615OQ-5oBoevKxdeXn96lt-BrIfeH1euftesHbcgLuY-jr1zosOGFPdadtnTthqh7_Q-M2tlrT2qsyWedKLeL1VyU26Jg-9jn5PKFsxA7gtPuBHOAMaHEkA7kG-f7tMbT30cKCWuPNvB40ibKmzT_fhR63XaMLSgdprg6D2GgWjeaFGCAAX0E1wBaGG0Yh8H5f5UOzivy2rb_5_gb95LMPGN_ra1J-BdlsRDldv2F_-fgvyrKL_g_D35ZyNkX_p-J_2ydutBXAD4rAHMuAJl_BeCzApC-gL4C8PUF-r_AvzZoWyFv-Fdu4RX5E02pXd-jVdCgZo2J4NAvHaF2iqAAIVdjILg-sHOBCLQ9uHpyQ64nFVbbP5BlTiQpRDcME1JhrN4ryP4tS5meT7ZxPo4WI5mjkDu4gxqtkMvItOmgFbHjQi4Jw1HIJXgaEusiz6CkqHjdaovM4AifsSUWgwF0BGfNEVxdjz68p3FsHJ5xrmE7RndJCJ0FhAP5Ixj0bWJwrcc-u7T8bx1GuIOfNdqfr7bqAMH1DNhbaCamp-2BQtQtRiZysdMBjKvRmONvZK7I4LEjuHdueEr5BwOGAB4tm8UOT6wwsn6lVcrUlt6y9WSlnOT8h8VpsMMDfUxFoaeICiOebDhDUf53SjpUwL4KuQpCrjmtmtHWDM9pWyLKiqgnBdoabYnzQGmFkQKzbbHIJzh2LsRvIeoeo_NikWfw3XlyBy76XcKncca4F4a59jqS1ziJ7ylC4zxgBEMYOD0omcUFPFW9kCuxyP_saUBPe-fvHx_Yey53scgbNIHR4CL4kIHrJkmSxQ6NuRblNx1-uLvkVhpfg5ALIRfw-HiX6XDPxwKpR7ebMNq_rZjkAf9LO1d7FtdhuLORvEVzr-2U85diz4seLN3rAz2F03xastyJ5Q7e-3ieujnrE3Iv5B6y7Jzzy9sPqpjLaQo2o64D1KP3ZKM5ApoXPAYIz5r7A-gmxTtdryiKVMcUcMCE_8eoAky4Pu2-ZT_GfsJz95YlQhaivIX8N1cA7u__-v3n7bebpz8JuVJVG85olTtR7kBICfDjtd-n-xxOhtQxUjKmRs-ZEjIx31khZUqBCxWe4ujtRdX-hcJoIjtUbp9s71Rq6Bd7PkY0tUGILnKHgNEq8iEyzJzgioL26eRpsNZGR4yUJpKxbL9rJnPB6GdK3YaLo-I-1ADCGMgDhueQ6qFxvqaLAKY2_P1hKszQudEoPqE8cb_keHlq0StDIWTvbU6NBGFwkWzUaKDRvyYxd0IujYFxMA4VBOdsdqU2pVqXa7yiTbEs5GK5Ksr8qtssZkW-rHA-W87na6S6XOJqhau6nud5gcXiSm9kLmf5LF8X8_lcltm6mlNdrwjVrFZYSTHLqUdtstTRnG-vdAgjbVarYlZcGazIhNOdoaUXSJOnK0O_4T3X1dgGMcuNDjG8SYk6GtpctGY-4AIHYjy9T1Cm9FFjCtFvCcTgGkKVTgF3PpGna8Gr0ZtNF-MQOG9SBbY6dmOV1a4Xcs92nP67Hrz7g2r-tknWByH3ybt_BgAA__--SvqD">