Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

recognize 'and' of disjoint ranges #28237

Open Quuxplusone opened 8 years ago

Quuxplusone commented 8 years ago
Bugzilla Link PR28238
Status NEW
Importance P normal
Reported by Sanjay Patel (spatel+llvm@rotateright.com)
Reported on 2016-06-21 10:09:32 -0700
Last modified on 2016-07-01 17:31:12 -0700
Version trunk
Hardware PC All
CC llvm-bugs@lists.llvm.org, me@manueljacob.de, sanjoy@playingwithpointers.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also PR28221, PR27869
Spinning this off from bug 27869 (and may have a different solution than bug
28221):

int f(int i) {
  return (i == 0) & (i >> 31);
}

'i' can't be 0 and have a bit set, so this should return 0.

$ ./clang -O1 sneaky_icmp.c -S -o - -emit-llvm
...
define i32 @f(i32 %i) {
  %cmp = icmp eq i32 %i, 0
  %conv = zext i1 %cmp to i32
  %shr = ashr i32 %i, 31
  %and = and i32 %conv, %shr
  ret i32 %and
}
Quuxplusone commented 8 years ago
This is different than what we started with in bug 27869. We don't actually
have to have an icmp slt equivalent. Ie, this is '0' too:

int f(int i) {
  return (i == 0) & (i >> 1);
}

define i32 @f(i32 %i) {
  %cmp = icmp eq i32 %i, 0
  %conv = zext i1 %cmp to i32
  %shr = ashr i32 %i, 1
  %and = and i32 %conv, %shr
  ret i32 %and
}
Quuxplusone commented 8 years ago
After reading this thread:
http://lists.llvm.org/pipermail/llvm-dev/2016-July/101837.html
...it might be better to handle this outside of InstSimplify.
Quuxplusone commented 8 years ago
But on looking at CVP a bit closer, it seems to defer single basic block cases
to InstCombine.

To make it even simpler, we don't handle this:

int foo(int i) {
  return (i == 0) & i;
}

GCC seems to have lost that optimization in v6.1; it worked in earlier revs.
ICC doesn't have it either.