[PATCH] D78430: [InstSimplify] fold and/or of compares with equality to min/max constant
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 18 09:41:39 PDT 2020
spatel created this revision.
spatel added reviewers: lebedev.ri, nikic, nlopes, regehr, aqjune.
Herald added subscribers: hiraditya, mcrosier.
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped compare operands, commuted logic operands).
We had partial logic to deal with these for the unsigned min (zero) case, but missed everything else.
I drafted an alternate implementation that uses ConstantRange instead of predicate+constant matching. It's slightly less code, but it requires many more code comments to follow the implied logic, so I think it's not worth the effort. I don't expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in 1 function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
https://reviews.llvm.org/D78430
Files:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/and-or-icmp-min-max.ll
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78430.258528.patch
Type: text/x-patch
Size: 36484 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200418/5b2fcfac/attachment.bin>
More information about the llvm-commits
mailing list