[PATCH] D33879: [InstCombine] fold lshr (sext X), C1 --> zext (lshr X, C2)

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 4 08:42:02 PDT 2017


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

This was discussed in https://reviews.llvm.org/D33338. We have larger pattern-matching ending in a truncate that we can reduce or remove by handling these smaller patterns first. Further motivation is that narrower shift ops are easier for value tracking and zext is better than sext.

http://rise4fun.com/Alive/rhh

Name: boolshift
%sext = sext i1 %x to i8
%r = lshr i8 %sext, 7

  =>

%r = zext i1 %x to i8

Name: noboolshift
%sext = sext i3 %x to i8
%r = lshr i8 %sext, 7

  =>

%sh = lshr i3 %x, 2
%r = zext i3 %sh to i8


https://reviews.llvm.org/D33879

Files:
  lib/Transforms/InstCombine/InstCombineShifts.cpp
  test/Transforms/InstCombine/lshr.ll


Index: test/Transforms/InstCombine/lshr.ll
===================================================================
--- test/Transforms/InstCombine/lshr.ll
+++ test/Transforms/InstCombine/lshr.ll
@@ -100,12 +100,9 @@
   ret <2 x i8> %lshr
 }
 
-; FIXME: The bool bit got smeared across a wide val, but then we zero'd out those bits. This is just a zext.
-
 define i16 @bool_zext(i1 %x) {
 ; CHECK-LABEL: @bool_zext(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 %x to i16
-; CHECK-NEXT:    [[HIBIT:%.*]] = lshr i16 [[SEXT]], 15
+; CHECK-NEXT:    [[HIBIT:%.*]] = zext i1 %x to i16
 ; CHECK-NEXT:    ret i16 [[HIBIT]]
 ;
   %sext = sext i1 %x to i16
@@ -115,8 +112,7 @@
 
 define <2 x i8> @bool_zext_splat(<2 x i1> %x) {
 ; CHECK-LABEL: @bool_zext_splat(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> %x to <2 x i8>
-; CHECK-NEXT:    [[HIBIT:%.*]] = lshr <2 x i8> [[SEXT]], <i8 7, i8 7>
+; CHECK-NEXT:    [[HIBIT:%.*]] = zext <2 x i1> %x to <2 x i8>
 ; CHECK-NEXT:    ret <2 x i8> [[HIBIT]]
 ;
   %sext = sext <2 x i1> %x to <2 x i8>
@@ -148,12 +144,10 @@
   ret <2 x i8> %hibit
 }
 
-; FIXME: All of the replicated sign bits are wiped out by the lshr. This could be lshr+zext.
-
 define i16 @fake_sext(i3 %x) {
 ; CHECK-LABEL: @fake_sext(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext i3 %x to i16
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[SEXT]], 15
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i3 %x, 2
+; CHECK-NEXT:    [[SH:%.*]] = zext i3 [[TMP1]] to i16
 ; CHECK-NEXT:    ret i16 [[SH]]
 ;
   %sext = sext i3 %x to i16
@@ -163,8 +157,8 @@
 
 define <2 x i8> @fake_sext_splat(<2 x i3> %x) {
 ; CHECK-LABEL: @fake_sext_splat(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i3> %x to <2 x i8>
-; CHECK-NEXT:    [[SH:%.*]] = lshr <2 x i8> [[SEXT]], <i8 7, i8 7>
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i3> %x, <i3 2, i3 2>
+; CHECK-NEXT:    [[SH:%.*]] = zext <2 x i3> [[TMP1]] to <2 x i8>
 ; CHECK-NEXT:    ret <2 x i8> [[SH]]
 ;
   %sext = sext <2 x i3> %x to <2 x i8>
Index: lib/Transforms/InstCombine/InstCombineShifts.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -680,6 +680,24 @@
       return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, Mask));
     }
 
+    if (match(Op0, m_SExt(m_Value(X)))) {
+      // Are we moving the sign bit to the low bit and widening with high zeros?
+      unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits();
+      if (ShAmt == BitWidth - 1) {
+        // lshr (sext i1 X to iN), N-1 --> zext X to iN
+        if (SrcTyBitWidth == 1)
+          return new ZExtInst(X, Ty);
+
+        // lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN
+        if (Op0->hasOneUse()) {
+          Value *NewLShr = Builder->CreateLShr(X, SrcTyBitWidth - 1);
+          return new ZExtInst(NewLShr, Ty);
+        }
+      }
+
+      // TODO: Convert to ashr+zext if the shift equals the extension amount.
+    }
+
     if (match(Op0, m_LShr(m_Value(X), m_APInt(ShOp1)))) {
       unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
       // Oversized shifts are simplified to zero in InstSimplify.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33879.101355.patch
Type: text/x-patch
Size: 3149 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170604/175aa5a8/attachment.bin>


More information about the llvm-commits mailing list