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.