We implement logic to convert a byte offset into a sequence of GEP indices for that offset in a number of places. This patch adds a DataLayout::getGEPIndicesForOffset() method, which implements the core logic. I've updated SROA, ConstantFolding and InstCombine to use it, and there's a few more places where it looks relevant.
Details
Diff Detail
Unit Tests
Event Timeline
llvm/lib/Analysis/ConstantFolding.cpp | ||
---|---|---|
1008 | We add extra zero indices in the hope that can return ResType without inserting a bitcast. But if that's not actually possible, we'll just add the maximum number of zeros and insert the bitcast anyway. |
llvm/lib/Analysis/ConstantFolding.cpp | ||
---|---|---|
1008 | ah I didn't see the bitcast below |
Hi @nikic,
This (admittedly silly) example starts hitting an assertion with this patch:
opt -passes='globalopt' -S -o - very_large_offset.ll
It fails with:
opt: ../lib/IR/DataLayout.cpp:913: void addElementIndex(SmallVectorImpl<llvm::APInt> &, llvm::TypeSize, llvm::APInt &): Assertion `Offset.isNonNegative() && "Remaining offset shouldn't be negative"' failed.
The input contains a huge (larger than half the address space) array @s and also a Gep with a huge offset into that object so possibly this is all UB but I suppose in a very nice world the compiler shouldn't crash with an assertion anyway since I guess the input is legal?
Seems like ElemSize is greater than 2^32 and we're getting some weird math in addElementIndex().
residual