Issue |
81793
|
Summary |
Faulty load-store forwarding with non byte-sized types
|
Labels |
miscompilation,
llvm:instcombine
|
Assignees |
|
Reporter |
bjope
|
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);
+ }
}
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs