[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