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.

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

    unsigned long foo(int *idx1, int *idx2) {
      return 4 * (idx1 - idx2);

I find the shifts get eliminated based on reasoning very similar to yours.