[llvm] 5dbb53b - [InstCombine] merge shuffled vector negate and multiply

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 24 07:25:22 PDT 2022


Author: Sanjay Patel
Date: 2022-03-24T10:25:16-04:00
New Revision: 5dbb53b1b4e07a0029569d394cf007a30a0882de

URL: https://github.com/llvm/llvm-project/commit/5dbb53b1b4e07a0029569d394cf007a30a0882de
DIFF: https://github.com/llvm/llvm-project/commit/5dbb53b1b4e07a0029569d394cf007a30a0882de.diff

LOG: [InstCombine] merge shuffled vector negate and multiply

Add the "(0 - X) --> (X * -1)" reverse identity to the list of alternate form binops.

We need a little hack to make the existing logic work because it does not expect to
move constants from op0 to op1, but the code comment hopefully makes that clear.
I don't think there are any other identities like that.

Fixes #54364

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
    llvm/test/Transforms/InstCombine/shuffle_select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index d2a92ad128c7f..066fbbaaaaa86 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -1934,6 +1934,11 @@ static BinopElts getAlternateBinop(BinaryOperator *BO, const DataLayout &DL) {
       return {Instruction::Add, BO0, BO1};
     break;
   }
+  case Instruction::Sub:
+    // sub 0, X --> mul X, -1
+    if (match(BO0, m_ZeroInt()))
+      return {Instruction::Mul, BO1, ConstantInt::getAllOnesValue(Ty)};
+    break;
   default:
     break;
   }
@@ -2052,14 +2057,19 @@ Instruction *InstCombinerImpl::foldSelectShuffle(ShuffleVectorInst &Shuf) {
       !match(Shuf.getOperand(1), m_BinOp(B1)))
     return nullptr;
 
+  // If one operand is "0 - X", allow that to be viewed as "X * -1"
+  // (ConstantsAreOp1) by getAlternateBinop below. If the neg is not paired
+  // with a multiply, we will exit because C0/C1 will not be set.
   Value *X, *Y;
-  Constant *C0, *C1;
+  Constant *C0 = nullptr, *C1 = nullptr;
   bool ConstantsAreOp1;
   if (match(B0, m_BinOp(m_Constant(C0), m_Value(X))) &&
       match(B1, m_BinOp(m_Constant(C1), m_Value(Y))))
     ConstantsAreOp1 = false;
-  else if (match(B0, m_BinOp(m_Value(X), m_Constant(C0))) &&
-           match(B1, m_BinOp(m_Value(Y), m_Constant(C1))))
+  else if (match(B0, m_CombineOr(m_BinOp(m_Value(X), m_Constant(C0)),
+                                 m_Neg(m_Value(X)))) &&
+           match(B1, m_CombineOr(m_BinOp(m_Value(Y), m_Constant(C1)),
+                                 m_Neg(m_Value(Y)))))
     ConstantsAreOp1 = true;
   else
     return nullptr;
@@ -2085,7 +2095,7 @@ Instruction *InstCombinerImpl::foldSelectShuffle(ShuffleVectorInst &Shuf) {
     }
   }
 
-  if (Opc0 != Opc1)
+  if (Opc0 != Opc1 || !C0 || !C1)
     return nullptr;
 
   // The opcodes must be the same. Use a new name to make that clear.

diff  --git a/llvm/test/Transforms/InstCombine/shuffle_select.ll b/llvm/test/Transforms/InstCombine/shuffle_select.ll
index 25064b5df13c3..03886b9f0eb8c 100644
--- a/llvm/test/Transforms/InstCombine/shuffle_select.ll
+++ b/llvm/test/Transforms/InstCombine/shuffle_select.ll
@@ -1394,10 +1394,8 @@ define <4 x i32> @shl_mul_2_vars(<4 x i32> %v0, <4 x i32> %v1) {
 
 define <4 x i32> @mul_neg(<4 x i32> %x) {
 ; CHECK-LABEL: @mul_neg(
-; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[X:%.*]], <i32 257, i32 -3, i32 poison, i32 -9>
-; CHECK-NEXT:    [[N:%.*]] = sub <4 x i32> <i32 poison, i32 poison, i32 0, i32 poison>, [[X]]
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[M]], <4 x i32> [[N]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
-; CHECK-NEXT:    ret <4 x i32> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[X:%.*]], <i32 257, i32 -3, i32 -1, i32 -9>
+; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
 ;
   %m = mul <4 x i32> %x, <i32 257, i32 -3, i32 poison, i32 -9>
   %n = sub <4 x i32> <i32 poison, i32 poison, i32 0, i32 poison>, %x
@@ -1407,10 +1405,8 @@ define <4 x i32> @mul_neg(<4 x i32> %x) {
 
 define <3 x i79> @neg_mul(<3 x i79> %x) {
 ; CHECK-LABEL: @neg_mul(
-; CHECK-NEXT:    [[N:%.*]] = sub nsw <3 x i79> <i79 0, i79 poison, i79 0>, [[X:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = mul nsw <3 x i79> [[X]], <i79 poison, i79 -3, i79 poison>
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x i79> [[N]], <3 x i79> [[M]], <3 x i32> <i32 0, i32 4, i32 2>
-; CHECK-NEXT:    ret <3 x i79> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw <3 x i79> [[X:%.*]], <i79 -1, i79 -3, i79 -1>
+; CHECK-NEXT:    ret <3 x i79> [[TMP1]]
 ;
   %n = sub nsw <3 x i79> <i79 0, i79 poison, i79 0>, %x
   %m = mul nsw <3 x i79> %x, <i79 poison, i79 -3, i79 poison>
@@ -1420,10 +1416,9 @@ define <3 x i79> @neg_mul(<3 x i79> %x) {
 
 define <4 x i32> @mul_neg_2_vars(<4 x i32> %x, <4 x i32> %y) {
 ; CHECK-LABEL: @mul_neg_2_vars(
-; CHECK-NEXT:    [[M:%.*]] = mul nuw <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 6>
-; CHECK-NEXT:    [[N:%.*]] = sub nsw <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>, [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[M]], <4 x i32> [[N]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
-; CHECK-NEXT:    ret <4 x i32> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
+; CHECK-NEXT:    [[TMP2:%.*]] = mul <4 x i32> [[TMP1]], <i32 42, i32 -1, i32 -1, i32 6>
+; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
 ;
   %m = mul nuw <4 x i32> %x, <i32 42, i32 poison, i32 poison, i32 6>
   %n = sub nsw <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>, %y
@@ -1433,10 +1428,9 @@ define <4 x i32> @mul_neg_2_vars(<4 x i32> %x, <4 x i32> %y) {
 
 define <4 x i32> @neg_mul_2_vars(<4 x i32> %x, <4 x i32> %y) {
 ; CHECK-LABEL: @neg_mul_2_vars(
-; CHECK-NEXT:    [[N:%.*]] = sub nsw <4 x i32> <i32 0, i32 poison, i32 0, i32 poison>, [[Y:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw <4 x i32> [[X:%.*]], <i32 poison, i32 42, i32 poison, i32 6>
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[N]], <4 x i32> [[M]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
-; CHECK-NEXT:    ret <4 x i32> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
+; CHECK-NEXT:    [[TMP2:%.*]] = mul nsw <4 x i32> [[TMP1]], <i32 -1, i32 42, i32 -1, i32 6>
+; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
 ;
   %n = sub nsw <4 x i32> <i32 0, i32 poison, i32 0, i32 poison>, %y
   %m = mul nuw nsw <4 x i32> %x, <i32 poison, i32 42, i32 poison, i32 6>


        


More information about the llvm-commits mailing list