[llvm-dev] always allow canonicalizing to 8- and 16-bit ops?
Sanjay Patel via llvm-dev
llvm-dev at lists.llvm.org
Wed Jan 17 14:50:38 PST 2018
Example:
define i8 @narrow_add(i8 %x, i8 %y) {
%x32 = zext i8 %x to i32
%y32 = zext i8 %y to i32
%add = add nsw i32 %x32, %y32
%tr = trunc i32 %add to i8
ret i8 %tr
}
With no data-layout or with an x86 target where 8-bit integer is in the
data-layout, we reduce to:
$ ./opt -instcombine narrowadd.ll -S
define i8 @narrow_add(i8 %x, i8 %y) {
%add = add i8 %x, %y
ret i8 %add
}
But on a target that has 32-bit registers without explicit subregister ops,
we don't do that transform because we avoid changing operations from a
legal (as specified in the data-layout) width to an illegal width - see
InstCombiner::shouldChangeType().
Should we make an exception to allow narrowing for the common cases of i8
and i16?
In the motivating example from PR35875 (
https://bugs.llvm.org/show_bug.cgi?id=35875 ), an ARM target is stuck at 19
IR instructions:
declare void @use4(i8, i8, i8, i8)
define void @min_of_3_vals(i8 %x, i8 %y, i8 %z) {
%nx = xor i8 %x, -1
%ny = xor i8 %y, -1
%nz = xor i8 %z, -1
%zx = zext i8 %nx to i32
%zy = zext i8 %ny to i32
%zz = zext i8 %nz to i32
%cmpxz = icmp ult i32 %zx, %zz
%minxz = select i1 %cmpxz, i32 %zx, i32 %zz
%cmpyz = icmp ult i32 %zy, %zz
%minyz = select i1 %cmpyz, i32 %zy, i32 %zz
%cmpyx = icmp ult i8 %y, %x
%minxyz = select i1 %cmpyx, i32 %minxz, i32 %minyz
%tr_minxyz = trunc i32 %minxyz to i8
%new_zx = sub nsw i32 %zx, %minxyz
%new_zy = sub nsw i32 %zy, %minxyz
%new_zz = sub nsw i32 %zz, %minxyz
%new_x = trunc i32 %new_zx to i8
%new_y = trunc i32 %new_zy to i8
%new_z = trunc i32 %new_zz to i8
call void @use4(i8 %tr_minxyz, i8 %new_x, i8 %new_y, i8 %new_z)
ret void
}
...but x86 gets to shrink the subs which leads to a bunch of other
transforms, and we grind this down to 10 instructions between instcombine
and early-cse:
define void @min_of_3_vals(i8 %x, i8 %y, i8 %z) {
%nx = xor i8 %x, -1
%ny = xor i8 %y, -1
%nz = xor i8 %z, -1
%cmpxz = icmp ult i8 %nx, %nz
%minxz = select i1 %cmpxz, i8 %nx, i8 %nz
%1 = icmp ult i8 %minxz, %ny
%minxyz = select i1 %1, i8 %minxz, i8 %ny
%new_x = sub i8 %nx, %minxyz
%new_y = sub i8 %ny, %minxyz
%new_z = sub i8 %nz, %minxyz
call void @use4(i8 %minxyz, i8 %new_x, i8 %new_y, i8 %new_z)
ret void
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180117/e03f433e/attachment.html>
More information about the llvm-dev
mailing list