[InstCombine] Remove unnecessary variable indexing into single-element arrays
authorHal Finkel <hfinkel@anl.gov>
Fri, 20 Feb 2015 03:05:53 +0000 (03:05 +0000)
committerHal Finkel <hfinkel@anl.gov>
Fri, 20 Feb 2015 03:05:53 +0000 (03:05 +0000)
commit5ecf528fc2c9e018f78d17fc1260889b6fa7df8e
tree89c2ece9e6fd105cb3eb29f70c5e33b59fe9b952
parent38749b8e079e5c3fa5ca25970656ee04ead5bb18
[InstCombine] Remove unnecessary variable indexing into single-element arrays

This change addresses a deficiency pointed out in PR22629. To copy from the bug
report:

[from the bug report]

Consider this code:

int f(int x) {
  int a[] = {12};
  return a[x];
}

GCC knows to optimize this to

movl     $12, %eax
ret

The code generated by recent Clang at -O3 is:

movslq   %edi, %rax
movl     .L_ZZ1fiE1a(,%rax,4), %eax
retq

.L_ZZ1fiE1a:
  .long    12                      # 0xc

[end from the bug report]

This definitely seems worth fixing. I've also seen this kind of code before (as
the base case of generic vector wrapper templates with one element).

The general idea is to look at the GEP feeding a load or a store, which has
some variable as its first non-zero index, and determine if that index must be
zero (or else an out-of-bounds access would occur). We can do this for allocas
and globals with constant initializers where we know the maximum size of the
underlying object. When we find such a GEP, we create a new one for the memory
access with that first variable index replaced with a constant zero.

Even if we can't eliminate the memory access (and sometimes we can't), it is
still useful because it removes unnecessary indexing calculations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229959 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
test/Transforms/InstCombine/load-cmp.ll
test/Transforms/InstCombine/mem-gep-zidx.ll [new file with mode: 0644]