[llvm] 68c5d46 - [InstCombine] Improve bitreverse optimization

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Thu May 25 11:41:50 PDT 2023


Author: Austin Chang
Date: 2023-05-25T13:41:32-05:00
New Revision: 68c5d46b6ec46c59afa052d2b2945ca7b22f58d6

URL: https://github.com/llvm/llvm-project/commit/68c5d46b6ec46c59afa052d2b2945ca7b22f58d6
DIFF: https://github.com/llvm/llvm-project/commit/68c5d46b6ec46c59afa052d2b2945ca7b22f58d6.diff

LOG: [InstCombine] Improve bitreverse optimization

This patch utilizes the helper function implemented in D149699 and thus folds the following cases:

```
bitreverse(logic_op(x, bitreverse(y))) -> logic_op(bitreverse(x), y)
bitreverse(logic_op(bitreverse(x), y)) -> logic_op(x, bitreverse(y))
bitreverse(logic_op(bitreverse(x), bitreverse(y))) -> logic_op(x, y) in multiuse case
```

Reviewed By: goldstein.w.n, RKSimon

Differential Revision: https://reviews.llvm.org/D151246

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/test/Transforms/InstCombine/bitreverse.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 1d7bf48414a13..60ff2331754e7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1709,15 +1709,21 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     break;
   }
   case Intrinsic::bitreverse: {
+    Value *IIOperand = II->getArgOperand(0);
     // bitrev (zext i1 X to ?) --> X ? SignBitC : 0
     Value *X;
-    if (match(II->getArgOperand(0), m_ZExt(m_Value(X))) &&
+    if (match(IIOperand, m_ZExt(m_Value(X))) &&
         X->getType()->isIntOrIntVectorTy(1)) {
       Type *Ty = II->getType();
       APInt SignBit = APInt::getSignMask(Ty->getScalarSizeInBits());
       return SelectInst::Create(X, ConstantInt::get(Ty, SignBit),
                                 ConstantInt::getNullValue(Ty));
     }
+
+    if (Instruction *crossLogicOpFold =
+        foldBitOrderCrossLogicOp<Intrinsic::bitreverse>(IIOperand, Builder))
+      return crossLogicOpFold;
+
     break;
   }
   case Intrinsic::bswap: {

diff  --git a/llvm/test/Transforms/InstCombine/bitreverse.ll b/llvm/test/Transforms/InstCombine/bitreverse.ll
index f18acaa911690..dca52e2c545e1 100644
--- a/llvm/test/Transforms/InstCombine/bitreverse.ll
+++ b/llvm/test/Transforms/InstCombine/bitreverse.ll
@@ -378,10 +378,9 @@ define i64 @PR59897(i1 %X1_2) {
 
 define i16 @rev_xor_lhs_rev16(i16 %a, i16 %b) #0 {
 ; CHECK-LABEL: @rev_xor_lhs_rev16(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i16 @llvm.bitreverse.i16(i16 [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = xor i16 [[TMP1]], [[B:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call i16 @llvm.bitreverse.i16(i16 [[TMP2]])
-; CHECK-NEXT:    ret i16 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[B:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i16 [[TMP1]], [[A:%.*]]
+; CHECK-NEXT:    ret i16 [[TMP2]]
 ;
   %1 = tail call i16 @llvm.bitreverse.i16(i16 %a)
   %2 = xor i16 %1, %b
@@ -391,10 +390,9 @@ define i16 @rev_xor_lhs_rev16(i16 %a, i16 %b) #0 {
 
 define i32 @rev_and_rhs_rev32(i32 %a, i32 %b) #0 {
 ; CHECK-LABEL: @rev_and_rhs_rev32(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[B:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[TMP2]])
-; CHECK-NEXT:    ret i32 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
   %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
   %2 = and i32 %a, %1
@@ -404,10 +402,9 @@ define i32 @rev_and_rhs_rev32(i32 %a, i32 %b) #0 {
 
 define i32 @rev_or_rhs_rev32(i32 %a, i32 %b) #0 {
 ; CHECK-LABEL: @rev_or_rhs_rev32(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[B:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[TMP2]])
-; CHECK-NEXT:    ret i32 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
   %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
   %2 = or i32 %a, %1
@@ -417,10 +414,9 @@ define i32 @rev_or_rhs_rev32(i32 %a, i32 %b) #0 {
 
 define i64 @rev_or_rhs_rev64(i64 %a, i64 %b) #0 {
 ; CHECK-LABEL: @rev_or_rhs_rev64(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]])
-; CHECK-NEXT:    ret i64 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT:    ret i64 [[TMP2]]
 ;
   %1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
   %2 = or i64 %a, %1
@@ -430,10 +426,9 @@ define i64 @rev_or_rhs_rev64(i64 %a, i64 %b) #0 {
 
 define i64 @rev_xor_rhs_rev64(i64 %a, i64 %b) #0 {
 ; CHECK-LABEL: @rev_xor_rhs_rev64(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = xor i64 [[TMP1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]])
-; CHECK-NEXT:    ret i64 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i64 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT:    ret i64 [[TMP2]]
 ;
   %1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
   %2 = xor i64 %a, %1
@@ -443,10 +438,9 @@ define i64 @rev_xor_rhs_rev64(i64 %a, i64 %b) #0 {
 
 define <2 x i32> @rev_xor_rhs_i32vec(<2 x i32> %a, <2 x i32> %b) #0 {
 ; CHECK-LABEL: @rev_xor_rhs_i32vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[B:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], [[A:%.*]]
-; CHECK-NEXT:    [[TMP3:%.*]] = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[TMP2]])
-; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], [[B:%.*]]
+; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
 ;
   %1 = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %b)
   %2 = xor <2 x i32> %a, %1
@@ -486,11 +480,8 @@ define i64 @rev_and_rhs_rev64_multiuse2(i64 %a, i64 %b) #0 {
 
 define i64 @rev_all_operand64(i64 %a, i64 %b) #0 {
 ; CHECK-LABEL: @rev_all_operand64(
-; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
-; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[TMP1]], [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP3]])
-; CHECK-NEXT:    ret i64 [[TMP4]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i64 [[TMP1]]
 ;
   %1 = tail call i64 @llvm.bitreverse.i64(i64 %a)
   %2 = tail call i64 @llvm.bitreverse.i64(i64 %b)
@@ -503,11 +494,10 @@ define i64 @rev_all_operand64_multiuse_both(i64 %a, i64 %b) #0 {
 ; CHECK-LABEL: @rev_all_operand64_multiuse_both(
 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
 ; CHECK-NEXT:    [[TMP2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
-; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[TMP1]], [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP3]])
+; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[A]], [[B]]
 ; CHECK-NEXT:    call void @use_i64(i64 [[TMP1]])
 ; CHECK-NEXT:    call void @use_i64(i64 [[TMP2]])
-; CHECK-NEXT:    ret i64 [[TMP4]]
+; CHECK-NEXT:    ret i64 [[TMP3]]
 ;
   %1 = tail call i64 @llvm.bitreverse.i64(i64 %a)
   %2 = tail call i64 @llvm.bitreverse.i64(i64 %b)


        


More information about the llvm-commits mailing list