InstCombine: Turn (zext A) udiv (zext B) into (zext (A udiv B)). Same for urem or...
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 30 Apr 2011 18:16:07 +0000 (18:16 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 30 Apr 2011 18:16:07 +0000 (18:16 +0000)
commit7d6eb5a018ef4352730d63dc202cfaf013f489fe
tree5108ec0202dff8007f3ff5ca5163b1987fb2f161
parent23b02cd0315625d9d586118abcc972053298d50b
InstCombine: Turn (zext A) udiv (zext B) into (zext (A udiv B)). Same for urem or constant B.

This obviously helps a lot if the division would be turned into a libcall
(think i64 udiv on i386), but div is also one of the few remaining instructions
on modern CPUs that become more expensive when the bitwidth gets bigger.

This also helps register pressure on i386 when dividing chars, divb needs
two 8-bit parts of a 16 bit register as input where divl uses two registers.

int foo(unsigned char a) { return a/10; }
int bar(unsigned char a, unsigned char b) { return a/b; }

compiles into (x86_64)
_foo:
  imull $205, %edi, %eax
  shrl  $11, %eax
  ret
_bar:
  movzbl        %dil, %eax
  divb  %sil, %al
  movzbl        %al, %eax
  ret

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130615 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
test/Transforms/InstCombine/udivrem-change-width.ll