[PATCH] D66232: [InstCombine] Try to reuse constant from select in leading comparison
Roman Lebedev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 10:47:40 PDT 2019
lebedev.ri created this revision.
lebedev.ri added reviewers: spatel, dmgreen, nikic, xbolva00.
lebedev.ri added a project: LLVM.
Herald added a subscriber: hiraditya.
If we have e.g.:
%t = icmp ult i32 %x, 65536
%r = select i1 %t, i32 %y, i32 65535
the constants `65535` and `65536` are suspiciously close.
We could perform a transformation to deduplicate them:
Name: ult
%t = icmp ult i32 %x, 65536
%r = select i1 %t, i32 %y, i32 65535
=>
%t.inv = icmp ugt i32 %x, 65535
%r = select i1 %t.inv, i32 65535, i32 %y
https://rise4fun.com/Alive/avb
While this may seem esoteric, this should certainly be good for vectors
(less constant pool usage) and for opt-for-size - need to have only one constant.
But the real fun part here is that it allows further transformation,
in particular it finishes cleaning up the `clamp` folding,
see e.g. `canonicalize-clamp-with-select-of-constant-threshold-pattern.ll`.
We start with e.g.
%dont_need_to_clamp_positive = icmp sle i32 %X, 32767
%dont_need_to_clamp_negative = icmp sge i32 %X, -32768
%clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
%dont_need_to_clamp = and i1 %dont_need_to_clamp_positive, %dont_need_to_clamp_negative
%R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
without this patch we currently produce
%1 = icmp slt i32 %X, 32768
%2 = icmp sgt i32 %X, -32768
%3 = select i1 %2, i32 %X, i32 -32768
%R = select i1 %1, i32 %3, i32 32767
which isn't really a `clamp` - both comparisons are performed on the original value,
this patch changes it into
%1.inv = icmp sgt i32 %X, 32767
%2 = icmp sgt i32 %X, -32768
%3 = select i1 %2, i32 %X, i32 -32768
%R = select i1 %1.inv, i32 32767, i32 %3
and then the magic happens! Some further transform finishes polishing it and we finally get:
%t1 = icmp sgt i32 %X, -32768
%t2 = select i1 %t1, i32 %X, i32 -32768
%t3 = icmp slt i32 %t2, 32767
%R = select i1 %t3, i32 %t2, i32 32767
which is beautiful and just what we want.
Proofs for `getFlippedStrictnessPredicateAndConstant()` for de-canonicalization:
https://rise4fun.com/Alive/THl
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D66232
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/canonicalize-clamp-with-select-of-constant-threshold-pattern.ll
llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll
llvm/test/Transforms/InstCombine/unrecognized_three-way-comparison.ll
llvm/test/Transforms/InstCombine/xor-of-icmps-with-extra-uses.ll
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66232.215164.patch
Type: text/x-patch
Size: 24793 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190814/0bbc694c/attachment-0001.bin>
More information about the llvm-commits
mailing list