<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/59633>59633</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Loop invariant expression using pointers not being optimized
</td>
</tr>
<tr>
<th>Labels</th>
<td>
llvm:optimizations,
missed-optimization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
markoshorro
</td>
</tr>
</table>
<pre>
For the following snippet (https://godbolt.org/z/3zMhr13rj):
```
#include <iostream>
template <typename T>
void bar(T arg);
void foo0(char *ptr) {
while (true) {
const auto mask = (uintptr_t)ptr & 0xf;
bar(mask);
ptr += 16;
}
}
void foo1(int64_t ptr) {
while (true) {
const auto mask = ptr & 0xf;
bar(mask);
ptr += 16;
}
}
```
In both cases, the computation of `mask` can be moved outside the loop, as `ptr` is incremented `0x10`, which is greater that the value of the mask `0xf`, therefore the 4 LSB of ptr remain the same as `bar` does not modify its value. However, in the first case `mask` is always computed within the loop. Taking a loop at the IR:
```
define dso_local void @_Z4foo0Pc(ptr noundef %0) local_unnamed_addr #3 !dbg !908 {
call void @llvm.dbg.value(metadata ptr %0, metadata !912, metadata !DIExpression()), !dbg !916
br label %2, !dbg !917
2: ; preds = %1, %2
%3 = phi ptr [ %0, %1 ], [ %6, %2 ]
call void @llvm.dbg.value(metadata ptr %3, metadata !912, metadata !DIExpression()), !dbg !916
%4 = ptrtoint ptr %3 to i64, !dbg !918
%5 = and i64 %4, 15, !dbg !919
call void @llvm.dbg.value(metadata i64 %5, metadata !913, metadata !DIExpression()), !dbg !920
tail call void @_Z3barImEvT_(i64 noundef %5), !dbg !921
%6 = getelementptr inbounds i8, ptr %3, i64 16, !dbg !922
call void @llvm.dbg.value(metadata ptr %6, metadata !912, metadata !DIExpression()), !dbg !916
br label %2, !dbg !917, !llvm.loop !923
}
define dso_local void @_Z4foo1l(i64 noundef %0) local_unnamed_addr #3 !dbg !932 {
call void @llvm.dbg.value(metadata i64 %0, metadata !936, metadata !DIExpression()), !dbg !940
%2 = and i64 %0, 15, !dbg !941
br label %3, !dbg !941
3: ; preds = %1, %3
call void @llvm.dbg.value(metadata i64 poison, metadata !936, metadata !DIExpression()), !dbg !940
call void @llvm.dbg.value(metadata i64 %2, metadata !937, metadata !DIExpression()), !dbg !942
tail call void @_Z3barIlEvT_(i64 noundef %2), !dbg !943
call void @llvm.dbg.value(metadata i64 poison, metadata !936, metadata !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value)), !dbg !940
br label %3, !dbg !941, !llvm.loop !944
}
```
For `foo0`, even though the cast `%4 = ptrtoint ptr %3 to i64, !dbg !918` is necessary, couldn't LLVM infer that this is, still, loop invariant?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8V01v2zwS_jX0ZVBDIiXZOviQxDU2QIotdoNdoBeDEimLDUUKJOU0_fUvhpITx3Y_EhQ1DFki5_PhM-MR917tjJQrkl-TfD3jQ2itW3XcPVjfWufsrLLiabWxDkIrobFa20dlduCN6nsZgNBlG0LvCbsidEPoZmdFZXWYW7cjdPOd0A37_ql1KXNfCS1RLFmT5HAtkuk7PlKmTK0HIYGwG2V9cJJ3hH081gmy6zUPUSQ89dLwTsL9s9DeKgEVd4Qu74FjECVh18cGokRjbULosm65A0Kv-uAILYEsJkkAgMdWaYkJBjfIs1381Nb4AHwIFjruH4CwNcoPyoQ-uG0gtOwD2i8g-dY8h3FQH6NEzeMgD7uj5jXaTIuXXbJYT8k837zKKiV0qUwosm2AP5fV30jjhAvxemugsqGFmnvpCb2JLKxt1w-BB2UN2AZIkUTnRQI1N1BJ6OxeCrBD8ErIqKKt7VGdexRHXIoElAdlaic7aYIUuJF8S2ME9AZxqlsU2TnJg0T-8xBt7bkeJDrGhxEh1GwmxdBKJxvrRscZ3P33GoURByc7rkxc98jaMRrEr0hAWOnB2ACdFap5AhX86GoO_7KPci8dWp_UG-V8iKgcp688cP3In_wEkRTwqEI76SAGc7jnD1i_PD7ClNLtf35emEI2ykgQ3m61rbmGyDaSJdsvGVbS55rQJWZo7GCEbIDQPEFyRentYLBIxZYLgWRgDAhNRbXDnzJZHlOw5vrFutb7bi6q3TzigCSTgQse-MSqPAL-vIjWUnq6tL79-K130ntlDaFL5Ch-b45jSIuD_8qB5pXUaJ2eSi2OIaKEXQFh19A7KfxU-3k66uT0YJDQnI0l1Kox7Pz6OXRUAJKv4_24XhwMxPV3ocL-OCqE5tmhDwSrTHh2BcGCKrJTzeWRZh41uREoGE2hdJqf6pRvzHaylp9newbA72RLk4P_wJV-HcT2C6u4u-0-7u-32F-L7Jjp-QVj6aHP0byI-e9kkDq2GoROmQr1Paglah4fHBpPi1N79H1UKP52gYwLMa7YYGLw7OI_1i-aSqrPkf7dnsLoO3rKxKfznsLOUPwdyLLkqAboaQ0kF2sgSy_BzH4gNV4Z9qE3fn7Yttg7MOut8gjDH0btbad2xuqSLd7ln_6yC-jLXYBeMHaA8y-guf7_9t-ft70e_HaIE1wkWNQat3zg9cN28vlT5H_BvUslnmU_n-bwBYIUSZy6xzFJ7iWOJXbYteNQx32AuPfmv5px8jGylt5z94QCtR20MIQuAtzd_e8TKNO8jHA498Vh0gelNd7EPJTZc6e4CYRtXs1C8ToTKyZKVvKZXKXFIi3SjBblrF2VKS_LoqrymtXLnKf1YpEnebWoUkHTJWcztaIJpSmlaVKmi6yc56JqyrpZZsUiSRuxJFmCg6GeR0yt282U94Nc5WXB2CwehY9vaJSiBGFXtg-qU9_jCOwJRfITSjvlvRQfjjdxL1_P3AoVP1TDziMBlQ_-xVlQQcvV3SsIQD5zCwaPA2OPZyHdOKJWEpcmR1LMBqdXJ6-BKrRDNa9tR-gmRj3-fOid_SrrQOgmJukJ3cQ8_wkAAP__WnkmZQ">