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.