<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/81793>81793</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Faulty load-store forwarding with non byte-sized types
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
llvm:instcombine
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
bjope
</td>
</tr>
</table>
<pre>
Consider this example with a big-endian data layout:
```
target datalayout = "E"
define i8 @foo(ptr %p) {
entry:
store i9 -1, ptr %p, align 1
%r0 = load i8, ptr %p, align 1
ret i8 %r0
}
```
If running that through instcombine the result is:
```
target datalayout = "E"
define i8 @foo(ptr %p) {
store i9 -1, ptr %p, align 1
ret i8 -1
}
```
LLVM IR reference (nor the DataLayout) is describing where padding bits go when storing a non byte-sized type like that. In practice LLVM (at least the backends I know about) would (zero) extend up to the TypeStoreSize before storing the i9 to memory. So given a big-endian datalayout (and a 8-bit byte size) the above is a miscompile, as the load depends on the padding bits. Fora little-endian datalayout the optimization isn't totally wrong, but I don't think that LLVM should optimize this even for little-endian (afaik we have avioded such optimizations historically).
Here is an alive2 link showing that the above transformation is invalid: https://alive2.llvm.org/ce/z/LJpiuS
Assuming that we simply want to skip the transformation also for little endian, then a patch like this could solve the problem:
```
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index f1dda97aa32d..b63c5078f88e 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -534,9 +534,11 @@ static Value *getAvailableLoadStore(Instruction *Inst, const Value *Ptr,
TypeSize StoreSize = DL.getTypeSizeInBits(Val->getType());
TypeSize LoadSize = DL.getTypeSizeInBits(AccessTy);
- if (TypeSize::isKnownLE(LoadSize, StoreSize))
+ if (DL.typeSizeEqualsStoreSize(Val->getType()) &&
+ TypeSize::isKnownLE(LoadSize, StoreSize)) {
if (auto *C = dyn_cast<Constant>(Val))
return ConstantFoldLoadFromConst(C, AccessTy, DL);
+ }
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8Vk-P274R_TT0ZWBDouy1dPDBa6_RbV2g6P6QazGSRhazFKmSIzveT1-Qlv8kTZqkh59BWBI5nHnvcTgkeq8OhmglFs9isZ3gwK11q_Kz7WlS2vq82ljjVU0OuFUe6At2vSY4KW4BoVSHKZlaoYEaGUHj2Q4ssrVItiJZi6dkbPGT0R2Io-XFEES2BSHli5BynBH_a2qUIVA5iHnSWCtk3rMDIRe9kAWI5fPFjgy78y0agGfrCFQB01TIDdznbAC1OhhIr5ZCLlwSw2uLNaj8J_aOOMIJ00aky-13Sb424AZjlDkAt8jArbPDoQVlPFe2KwMxbgkc-UEzKP-nqfUb-ox0p-n_5rrff_o7vP4THDXkyFQEQubGukhwi4z7Sz7IApSHmnzlVBmUObXkCHqs6_BVKvZwsKHXRIyhE8FYA-WZaerVB9XA555Aq3eKus7g1UDvsGJVEUQgQubIoAk9RwAlVu9kag-v8G7sCbAcsZzsoOtg_kHOhg76wmRqGHpgG6f-ce7pLYj1pj4ISmqCbldkwUAVwbSjzrrzDN4sHNSRzH_viOvKyRxNDQj5tFQcWUFgFYIHd1jaIwWNEDrlK9v1SlNcFh_HY5LW1Ec61sS-R_VmsLMOQStmTd-JH-xtz6pTH8jKGlDeCLlkYMuo9RlOzppDCFgODK9Q23G4Veb9ksdRYt9G6UZXNNaEwLyx7pvwgXOD6h1OBC0eCfCobE01-KFqv0LjoVVR3CpgEbKYPab3X0KqBGlMSNIjSdABlG_t6WGTXTVkh8Y31nVXnqDMEbWqRbaGlrmP-03uhNxdvM20PnYz6w5C7ioScvch5G7_114Nb48o1t4P3S3eKSxf1wfh0AQVwb-rPsL4BgBqbx_EgYs4QWluY8L0yFV7zWvloYoKe6uPlzrRO1tq6n5UJWrVNDCdHhQDCrkLZMJDlULu1gb12SsfCFms_azqeyh_xeriW5mavkCT1jUWS8RM1rNZ-ZRVi2SZN3lOkCbJ03x-MZ5Op7-GYKQhny_tdwCJeSLmCUwX2VzITQFCPl9e0xTGMc_IqoJPqIdQjdYH4vURlcZSU_AWd7WQ-avx7IYqrpGQ6_AZFqWyxvN99j_YCbkZi-L4iLUhJP-9QITCvN3PDsTXwVfzrNgLmX9CPRXZyzgkZC5kEVp2K8oAd5cR4U88rquKvP_j_OhlGryoJuy5q31ImGyt_N-MPZn9i5D51XngecM-wrmuyd3Pdj_j0dXLvwfU_mHKj1iBkE-h3bz9X2AeTyy4A8KBbViTTRSnPpt_VehZZJtwQ2E0LLKXC7RHTnD9OeLBGbga76yuA4ads13sEzLfBDB3eTew3T-KPMpzOwwf37_Zm2OuTOpVVhdZgRNapctkWcwX-TKbtKu0yUokiXVZJNWipEUxz_IknedLStPFMp-olUzkPJHpXKZynmWzvCmeMMuxKCosn1Ip5gl1qPStfE2U9wOt8nRZZBONJWkfL3VS3k6UWJHC5UFuhJRxz2Xrh3tJGFpsJ24VhqblcPBinmjl2d-jsGJNqx0Oms_xWJpeLhWNdSd08UCKd8PvHN5-Mji9-roGHxS3QzmrbPdQBUL03tnPVLGQu8grFINI7T8BAAD__5DaVcI">