-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[PatternMatch] Introduce m_c_Select #114328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-llvm-transforms Author: David Green (davemgreen) ChangesThis matches m_Select(C, L, R) or m_Select(C, R, L). Full diff: https://github.com/llvm/llvm-project/pull/114328.diff 5 Files Affected:
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index c3349c9772c7ad..2713f858d28d8c 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -1706,7 +1706,8 @@ template <typename T0, typename T1, unsigned Opcode> struct TwoOps_match {
};
/// Matches instructions with Opcode and three operands.
-template <typename T0, typename T1, typename T2, unsigned Opcode>
+template <typename T0, typename T1, typename T2, unsigned Opcode,
+ bool CommutableOp2Op3 = false>
struct ThreeOps_match {
T0 Op1;
T1 Op2;
@@ -1718,8 +1719,12 @@ struct ThreeOps_match {
template <typename OpTy> bool match(OpTy *V) {
if (V->getValueID() == Value::InstructionVal + Opcode) {
auto *I = cast<Instruction>(V);
- return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1)) &&
- Op3.match(I->getOperand(2));
+ if (!Op1.match(I->getOperand(0)))
+ return false;
+ if (Op2.match(I->getOperand(1)) && Op3.match(I->getOperand(2)))
+ return true;
+ return CommutableOp2Op3 && Op2.match(I->getOperand(2)) &&
+ Op3.match(I->getOperand(1));
}
return false;
}
@@ -1771,6 +1776,13 @@ m_SelectCst(const Cond &C) {
return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
}
+/// Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
+template <typename Cond, typename LHS, typename RHS>
+inline ThreeOps_match<Cond, LHS, RHS, Instruction::Select, true>
+m_c_Select(const Cond &C, const LHS &L, const RHS &R) {
+ return ThreeOps_match<Cond, LHS, RHS, Instruction::Select, true>(C, L, R);
+}
+
/// Matches FreezeInst.
template <typename OpTy>
inline OneOps_match<OpTy, Instruction::Freeze> m_Freeze(const OpTy &Op) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 21588aca512758..ed2afe6fb3c320 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2241,8 +2241,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
if (!UI)
return false;
return match(UI,
- m_Select(m_Value(), m_Specific(Op1), m_Specific(&I))) ||
- match(UI, m_Select(m_Value(), m_Specific(&I), m_Specific(Op1)));
+ m_c_Select(m_Value(), m_Specific(Op1), m_Specific(&I)));
})) {
if (Value *NegOp1 = Negator::Negate(IsNegation, /* IsNSW */ IsNegation &&
I.hasNoSignedWrap(),
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 07b9405b941d68..cdaebc55168211 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1664,9 +1664,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
Value *X;
if (match(IIOperand, m_Neg(m_Value(X))))
return replaceOperand(*II, 0, X);
- if (match(IIOperand, m_Select(m_Value(), m_Value(X), m_Neg(m_Deferred(X)))))
- return replaceOperand(*II, 0, X);
- if (match(IIOperand, m_Select(m_Value(), m_Neg(m_Value(X)), m_Deferred(X))))
+ if (match(IIOperand,
+ m_c_Select(m_Value(), m_Neg(m_Value(X)), m_Deferred(X))))
return replaceOperand(*II, 0, X);
Value *Y;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 6bb39cabb0988b..cdb21e14c258f6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8462,9 +8462,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
case Instruction::Select:
// fcmp eq (cond ? x : -x), 0 --> fcmp eq x, 0
if (FCmpInst::isEquality(Pred) && match(RHSC, m_AnyZeroFP()) &&
- (match(LHSI,
- m_Select(m_Value(), m_Value(X), m_FNeg(m_Deferred(X)))) ||
- match(LHSI, m_Select(m_Value(), m_FNeg(m_Value(X)), m_Deferred(X)))))
+ match(LHSI, m_c_Select(m_Value(), m_FNeg(m_Value(X)), m_Deferred(X))))
return replaceOperand(I, 0, X);
if (Instruction *NV = FoldOpIntoSelect(I, cast<SelectInst>(LHSI)))
return NV;
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 72228b445a8b6e..3f127a829437b4 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3810,10 +3810,8 @@ static bool foldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
// These can often be turned into switches and other things.
auto IsBinOpOrAnd = [](Value *V) {
return match(
- V, m_CombineOr(
- m_BinOp(),
- m_CombineOr(m_Select(m_Value(), m_ImmConstant(), m_Value()),
- m_Select(m_Value(), m_Value(), m_ImmConstant()))));
+ V, m_CombineOr(m_BinOp(),
+ m_c_Select(m_Value(), m_ImmConstant(), m_Value())));
};
if (PN->getType()->isIntegerTy(1) &&
(IsBinOpOrAnd(PN->getIncomingValue(0)) ||
|
llvm/include/llvm/IR/PatternMatch.h
Outdated
| template <typename Cond, typename LHS, typename RHS> | ||
| inline ThreeOps_match<Cond, LHS, RHS, Instruction::Select, true> | ||
| m_c_Select(const Cond &C, const LHS &L, const RHS &R) { | ||
| return ThreeOps_match<Cond, LHS, RHS, Instruction::Select, true>(C, L, R); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to hide the condition, or add something to indicate the condition needs to be inverted. You can't safely directly use the condition if it's swapped
|
Reverse ping. |
|
I can update this, but I'm not sure if we considered it worth adding or not. I'm happy for you to take it over if you think it is useful. |
I think it is useful to avoid duplicate code when the condition is negligible. |
This matches m_Select(C, L, R) or m_Select(C, R, L).
6381114 to
fdff967
Compare
|
I've removed the first condition. My C++ is probably worse now than when I started working on a compiler, so let me know if anything looks wrong :) |
dtcxzyw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you!
This matches m_Select(m_Value(), L, R) or m_Select(m_Value(), R, L).
This matches m_Select(C, L, R) or m_Select(C, R, L).