[llvm] r360605 - [InstCombine] try harder to form rotate (funnel shift) (PR20750)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon May 13 10:28:19 PDT 2019


Author: spatel
Date: Mon May 13 10:28:19 2019
New Revision: 360605

URL: http://llvm.org/viewvc/llvm-project?rev=360605&view=rev
Log:
[InstCombine] try harder to form rotate (funnel shift) (PR20750)

We have a similar match for patterns ending in a truncate. This
should be ok for all targets because the default expansion would
still likely be better from replacing 2 'and' ops with 1.

Attempt to show the logic equivalence in Alive (which doesn't
currently have funnel-shift in its vocabulary AFAICT):

  %shamt = zext i8 %i to i32
  %m = and i32 %shamt, 31
  %neg = sub i32 0, %shamt
  %and4 = and i32 %neg, 31
  %shl = shl i32 %v, %m
  %shr = lshr i32 %v, %and4
  %or = or i32 %shr, %shl
  =>
  %a = and i8 %i, 31
  %shamt2 = zext i8 %a to i32
  %neg2 = sub i32 0, %shamt2
  %and4 = and i32 %neg2, 31
  %shl = shl i32 %v, %shamt2
  %shr = lshr i32 %v, %and4
  %or = or i32 %shr, %shl

https://rise4fun.com/Alive/V9r

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/test/Transforms/InstCombine/rotate.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=360605&r1=360604&r2=360605&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Mon May 13 10:28:19 2019
@@ -1898,6 +1898,13 @@ static Instruction *matchRotate(Instruct
         match(R, m_And(m_Neg(m_Specific(X)), m_SpecificInt(Mask))))
       return X;
 
+    // Similar to above, but the shift amount may be extended after masking,
+    // so return the extended value as the parameter for the intrinsic.
+    if (match(L, m_ZExt(m_And(m_Value(X), m_SpecificInt(Mask)))) &&
+        match(R, m_And(m_Neg(m_ZExt(m_And(m_Specific(X), m_SpecificInt(Mask)))),
+                       m_SpecificInt(Mask))))
+      return L;
+
     return nullptr;
   };
 

Modified: llvm/trunk/test/Transforms/InstCombine/rotate.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/rotate.ll?rev=360605&r1=360604&r2=360605&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/rotate.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/rotate.ll Mon May 13 10:28:19 2019
@@ -710,13 +710,8 @@ define i32 @rotl_constant_expr(i32 %sham
 
 define i32 @rotateleft32_doubleand1(i32 %v, i8 %r) {
 ; CHECK-LABEL: @rotateleft32_doubleand1(
-; CHECK-NEXT:    [[M:%.*]] = and i8 [[R:%.*]], 31
-; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[M]] to i32
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[Z]]
-; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[NEG]], 31
-; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[V:%.*]], [[Z]]
-; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[V]], [[AND2]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHR]], [[SHL]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[R:%.*]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = call i32 @llvm.fshl.i32(i32 [[V:%.*]], i32 [[V]], i32 [[Z]])
 ; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %m = and i8 %r, 31
@@ -731,13 +726,8 @@ define i32 @rotateleft32_doubleand1(i32
 
 define i32 @rotateright32_doubleand1(i32 %v, i16 %r) {
 ; CHECK-LABEL: @rotateright32_doubleand1(
-; CHECK-NEXT:    [[M:%.*]] = and i16 [[R:%.*]], 31
-; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[M]] to i32
-; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[Z]]
-; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[NEG]], 31
-; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[V:%.*]], [[AND2]]
-; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[V]], [[Z]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHR]], [[SHL]]
+; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[R:%.*]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = call i32 @llvm.fshr.i32(i32 [[V:%.*]], i32 [[V]], i32 [[Z]])
 ; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %m = and i16 %r, 31




More information about the llvm-commits mailing list