[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