<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/133038>133038</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[LICM] LICM breaks `initializes` attribute
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
loopoptim,
generated by fuzzer
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
dtcxzyw
</td>
</tr>
</table>
<pre>
Reproducer: https://godbolt.org/z/evTP9P17j
```
; bin/opt -passes=licm reduced.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @_ZN25test7425_51072c957f3e023d3fn317hab8ab70cb1ea6b04E(ptr noalias writable align 2 dereferenceable(12) initializes((0, 12)) %0) {
%2 = alloca [56 x i8], align 8
%3 = getelementptr i8, ptr %0, i64 8
%4 = getelementptr i8, ptr %0, i64 10
br label %5
5: ; preds = %10, %1
%6 = getelementptr i8, ptr %2, i64 16
%7 = getelementptr i8, ptr %2, i64 16
store i16 0, ptr %3, align 2
store i16 0, ptr %4, align 2
%8 = load <4 x i32>, ptr %6, align 8
store <4 x i32> %8, ptr %7, align 8
br label %9
9: ; preds = %5
switch i8 1, label %11 [
i8 1, label %11
i8 0, label %10
]
10: ; preds = %9
store <4 x i16> zeroinitializer, ptr %0, align 2
br label %5
11: ; preds = %9, %9
ret void
}
define void @_ZN25test7425_51072c957f3e023d4main17hb2c14928af806df2E() {
%1 = alloca [64 x i8], align 8
call void @_ZN25test7425_51072c957f3e023d3fn317hab8ab70cb1ea6b04E(ptr %1)
ret void
}
```
After LICM, the first memory access to `%0` is `load <4 x i16>, ptr %0, align 1`, which breaks the `initializes` attribute:
> Initialization of memory means the first memory access is a non-volatile, non-atomic write.
> The initializes attribute does not imply writeonly since initializes allows reading from the pointer after writing.
```
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @_ZN25test7425_51072c957f3e023d3fn317hab8ab70cb1ea6b04E(ptr noalias writable align 2 dereferenceable(12) initializes((0, 12)) %0) {
%2 = alloca [56 x i8], align 8
%3 = getelementptr i8, ptr %0, i64 8
%4 = getelementptr i8, ptr %0, i64 10
%5 = getelementptr i8, ptr %2, i64 16
%6 = getelementptr i8, ptr %2, i64 16
%.promoted = load <4 x i32>, ptr %5, align 8
%.promoted1 = load <4 x i16>, ptr %0, align 1
br label %7
7: ; preds = %11, %1
%8 = phi <4 x i16> [ zeroinitializer, %11 ], [ %.promoted1, %1 ]
%9 = phi <4 x i32> [ %9, %11 ], [ %.promoted, %1 ]
br label %10
10: ; preds = %7
switch i8 1, label %12 [
i8 1, label %12
i8 0, label %11
]
11: ; preds = %10
br label %7
12: ; preds = %10, %10
%.lcssa2 = phi <4 x i16> [ %8, %10 ], [ %8, %10 ]
%.lcssa = phi <4 x i32> [ %9, %10 ], [ %9, %10 ]
store i16 0, ptr %3, align 2
store i16 0, ptr %4, align 2
store <4 x i32> %.lcssa, ptr %5, align 8
store <4 x i16> %.lcssa2, ptr %0, align 1
ret void
}
```
Should we clarify the LangRef wording on `initializes` to allow loads before the initialization is complete, if they are not externally observable?
This case is generated by rustlantis + llubi.
Original rust mir program: https://gist.github.com/dtcxzyw/fcf0905a562f8734428e0b216198e0c0
cc @haopliu @nikic
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWM1u4zgSfhr6UrBBUv8HH5wfAwPM7g6m-7SXBiWVbE5TpEBSSZynX5CyY8d2nOlG33aCwJbE-qqKVaz6ShbOyY1GXJLsjmQPMzH6rbHL1jcvr7vnWW3a3fJPHKxpxwYtSVaw9X5wJFkRviZ8vTFtbZRfGLshfP1K-Bqfvv5R_cGKvwhdkZzu_-mKJHdQS0342gwe5oNwDh1JHpRserAY9LcLpWD-hdCVF3aDHlrhhRI7M3ogyQMQznHek2SF84EXlCSrhMePcMve34arPI0fc_l2wXhJkhXj5bwr6f5Kx0f5AZ6n8y9BjPOjH97KQeHBh5cy_5an81F_1-ZZz5XU48t8o8cJQuiqxU5qhCcjWyAp_fbff_PMo_NFyrNvGaMFb6qs6BKkPGmTTies2Iq6FHVBm5qhyGuaPhJeDt6CNkJJ4eDZSi9qhSCU3Gjg0KLFDi3qBsNzwkvGCa9AaumlUPIVHQnbKCnh9xDXwjLhGY3fxR2hKwj3PG5MKGUaASS7y3J4AVmS7CEgJ3vlQTiJwhv0qLBH7YOPsgyC4WrSfg8yT4-Q9G9DGI2Y2oISNaqwlk0hzcLRC0dosNi6fSYyFpHh4mAr_8wWf7OVHzDFj2KcNxZBshzoiVRyjBa_IZaeixGeldEDZUQLJLlPQ_jDWXw8geXnuZi0vxOPqk4wxTnmNLDVFNjqamCzycSz9M0WZAksaHqDMhaOSRSBa6thRZbTro-Pp9yGUxUNs1B_8GN_F35WV0IRSvkRXtGaYynY89N2moArx42xX-LcdDijkxZ9bAhBf_HwE30i7YXUrNjWvGFpxUvRlTRvO_4Yq_xdQbOzgs7Tjwq6EUr9mj4Vi5BP-bi211MqWHUeLfz-2_2_gj9-i9BJ6zz02Bu7A9E06Bx4A0E8JCynIF24e1ciMdHXE8si8h6et7LZQm1RfHfREMnpaYPMKQjvraxHj4HTAk09wm8HCeGl0WC6g2c9Cu0-dFg6EKCNnj8ZJbwMPfk-3gtvetnEFo6LvY2vWzxt1Uc3oDXoQBsPsh_UbkIZrXbgpG7OQEqZZwcWRSv1Bjpr-ujdYKQOIRYx0EGD1JvFZSL-odn_Z5oN7e4n6PJnKHYxWNMbj-3nRJddicYbnF3ib3aB8_ZeTCenuD5NsPNpYuLlYSvPyIVkd9cI5kCNMaFB5p3rB4k9BUYD1YWBPZFP4OpTrRdKT3cb8_xGtRf7LW6TPL9J8vy4Qq_Q_wnPs49Gtw-Sw_gns97b6V2oxjnBbyTpMBBF2FkMzxbe6fybaTlXWV2q_LWz4gdD3-T0rSK6NiIdI3irfC7J_PSljq6-bM2oWnhGaJSwsttFBvpd6M2f2MGzsZGajL5Cvd5MDBYL2kGNXXDSnzLjxMDSQWP6QaGPnCq7ILQDYTESJb54tFootQNTO7RPsVMn68nBr9sAFw6Dmg1qtCI0onoHdnReCe3DbMHvQKmxloEl_2PlRmqhogD00sJgzcaK_sr7r3R-sZF-O9aLxvSEr_evzoSvu6ajFc1ElvOuLJI05SXSmrOcVSXSZh-_pgnktRVmUHIMl1p-lw0Qupq1y6StkkrMcMmKlFd5wXM-2y5ZVfO0KBgtuwrLiicdawUWOSs7ZHUrZnLJKc9ownOaJSlnC4F50SWi4zVvuqZJSUqxF1ItlHrqw8v7TDo34pIlCU3KWSxJF38T4LyXLgRfqpiLwL78nnCujBnM4GX_9uRdbLvxNXZFTrKHmV0GO_N63DiSUiWdd0fLXnoVf3-IA2H2EAfDw8x2Y16bjVYtz7NxkohgYP81H6z5CxtP-Dru0xG-3m_1acn_FwAA__-bub1m">