Lawrence, Peter via llvm-dev
2016-Jul-05 22:42 UTC
[llvm-dev] missing opt in DAGCombiner ?
I've been surprised by how "over the top" the set of opts in
DAGCombiner are,
But here's one that might be missing
Array[ I + (pointer-difference) ]
Generates ... (shl (sra (sub pointer1, pointer2), 2), 2) ...
Which gets Combined into
(and (sub pointer1, pointer2), -4)
But IIUC the C/C++ languages require pointer1 and pointer2 to be addresses of
elements in the same array,
So their difference must be (0 mod element-size),
(even if the array itself is somehow misaligned, the difference between elements
will be aligned)
so the "SRA" is only shifting out zeros,
So the "AND" by "-4" is superfluous
Please let me know if I am misunderstanding something ?!
--Peter Lawrence.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160705/b78af34d/attachment.html>
On 5 July 2016 at 15:42, Lawrence, Peter via llvm-dev <llvm-dev at lists.llvm.org> wrote:> But IIUC the C/C++ languages require pointer1 and pointer2 to be addresses > of elements in the same array, So their difference must be (0 mod element-size),LLVM IR is much less strict about type punning (overlapping objects wouldn't be a problem, for example) so the DAG combiner is rather limited in what it can do. But Clang ought to be emitting "exact" modifiers on the relevant instructions so that LLVM's mid-end can do the right thing. When I compile unsigned long foo(int *idx1, int *idx2) { return 4 * (idx1 - idx2); } I find the shifts get eliminated based on reasoning very similar to yours. Cheers. Tim.