[PATCH] D38514: [InstCombine] improve folds for icmp gt/lt (shr X, C1), C2

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 14:14:10 PDT 2017


spatel created this revision.
Herald added a subscriber: mcrosier.

We can always eliminate the shift in: icmp gt/lt (shr X, C1), C2 --> icmp gt/lt X, C'
This patch was supposed to just be an efficiency improvement because we were doing this 3-step process to fold:

  IC: Visiting:   %c = icmp ugt i4 %s, 1
  IC: ADD:   %s = lshr i4 %x, 1
  IC: ADD:   %1 = udiv i4 %x, 2
  IC: Old =   %c = icmp ugt i4 %1, 1
      New =   <badref> = icmp uge i4 %x, 4
  IC: ADD:   %c = icmp uge i4 %x, 4
  IC: ERASE   %2 = icmp ugt i4 %1, 1
  IC: Visiting:   %c = icmp uge i4 %x, 4
  IC: Old =   %c = icmp uge i4 %x, 4
      New =   <badref> = icmp ugt i4 %x, 3
  IC: ADD:   %c = icmp ugt i4 %x, 3
  IC: ERASE   %2 = icmp uge i4 %x, 4
  IC: Visiting:   %c = icmp ugt i4 %x, 3
  IC: DCE:   %1 = udiv i4 %x, 2
  IC: ERASE   %1 = udiv i4 %x, 2
  IC: DCE:   %s = lshr i4 %x, 1
  IC: ERASE   %s = lshr i4 %x, 1
  IC: Visiting:   ret i1 %c

When we could go directly to canonical icmp form:

  IC: Visiting:   %c = icmp ugt i4 %s, 1
  IC: Old =   %c = icmp ugt i4 %s, 1
      New =   <badref> = icmp ugt i4 %x, 3
  IC: ADD:   %c = icmp ugt i4 %x, 3
  IC: ERASE   %1 = icmp ugt i4 %s, 1
  IC: ADD:   %s = lshr i4 %x, 1
  IC: DCE:   %s = lshr i4 %x, 1
  IC: ERASE   %s = lshr i4 %x, 1
  IC: Visiting:   %c = icmp ugt i4 %x, 3

...but then I noticed that the folds were incomplete too:
https://godbolt.org/g/aB2hLE

Here are attempts to prove the logic with Alive:
https://rise4fun.com/Alive/92o

Name: lshr_ult
Pre: ((C2 << C1) u>> C1) == C2
%sh = lshr i8 %x, C1
%r = icmp ult i8 %sh, C2

  =>

%r = icmp ult i8 %x, (C2 << C1)

Name: ashr_slt
Pre: ((C2 << C1) >> C1) == C2
%sh = ashr i8 %x, C1
%r = icmp slt i8 %sh, C2

  =>

%r = icmp slt i8 %x, (C2 << C1)

Name: lshr_ugt
Pre: (C2 != 255) && (((C2+1) << C1) u>> C1) == (C2+1)
%sh = lshr i8 %x, C1
%r = icmp ugt i8 %sh, C2

  =>

%r = icmp ugt i8 %x, ((C2+1) << C1) - 1

Name: ashr_sgt
Pre: (C2 != 127) && ((C2+1) << C1 != -128) && (((C2+1) << C1) >> C1) == (C2+1)
%sh = ashr i8 %x, C1
%r = icmp sgt i8 %sh, C2

  =>

%r = icmp sgt i8 %x, ((C2+1) << C1) - 1

We did something similar for 'shl' in https://reviews.llvm.org/D28406.


https://reviews.llvm.org/D38514

Files:
  lib/Transforms/InstCombine/InstCombineCompares.cpp
  test/Transforms/InstCombine/icmp-shr-lt-gt.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38514.117577.patch
Type: text/x-patch
Size: 8704 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171003/c69332a2/attachment.bin>


More information about the llvm-commits mailing list