[InstCombine] Simplify shift-by-sext to shift-by-zext
authorRoman Lebedev <lebedev.ri@gmail.com>
Fri, 27 Sep 2019 18:12:15 +0000 (18:12 +0000)
committerRoman Lebedev <lebedev.ri@gmail.com>
Fri, 27 Sep 2019 18:12:15 +0000 (18:12 +0000)
commit269f1bea0d50070b3acedf248f25f33cc6288406
tree391516b8627ccba67c8c729260f5768a11f6845a
parente3fed89046b3651ab579250cc0fc37efc90aa7f3
[InstCombine] Simplify shift-by-sext to shift-by-zext

Summary:
This is valid for any `sext` bitwidth pair:
```
Processing /tmp/opt.ll..

----------------------------------------
  %signed = sext %y
  %r = shl %x, %signed
  ret %r
=>
  %unsigned = zext %y
  %r = shl %x, %unsigned
  ret %r
  %signed = sext %y

Done: 2016
Optimization is correct!
```

(This isn't so for funnel shifts, there it's illegal for e.g. i6->i7.)

Main motivation is the C++ semantics:
```
int shl(int a, char b) {
    return a << b;
}
```
ends as
```
  %3 = sext i8 %1 to i32
  %4 = shl i32 %0, %3
```
https://godbolt.org/z/0jgqUq
which is, as this shows, too pessimistic.

There is another problem here - we can only do the fold
if sext is one-use. But we can trivially have cases
where several shifts have the same sext shift amount.
This should be resolved, later.

Reviewers: spatel, nikic, RKSimon

Reviewed By: spatel

Subscribers: efriedma, hiraditya, nlopes, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68103

llvm-svn: 373106
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/test/Transforms/InstCombine/load-cmp.ll
llvm/test/Transforms/InstCombine/shift-by-signext.ll