aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectOptimize.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2024-11-30 21:05:41 +0000
committerGitHub <noreply@github.com>2024-11-30 21:05:41 +0000
commit9a0f25158c2eff539de1efbd55de71e711135db7 (patch)
treebf43e16954fa2239ae55e34cbd45bd02bc3f5fa5 /llvm/lib/CodeGen/SelectOptimize.cpp
parent2e30df740ef0b9f8edb7075768540ce08678023d (diff)
downloadllvm-9a0f25158c2eff539de1efbd55de71e711135db7.zip
llvm-9a0f25158c2eff539de1efbd55de71e711135db7.tar.gz
llvm-9a0f25158c2eff539de1efbd55de71e711135db7.tar.bz2
[SelectOpt] Support ADD and SUB with zext operands. (#115489)
Extend the support for implicit selects in the form of OR with a ZExt operand to support ADD and SUB binops as well. They similarly can form implicit selects which can be profitable to convert back the branches. PR: https://github.com/llvm/llvm-project/pull/115489
Diffstat (limited to 'llvm/lib/CodeGen/SelectOptimize.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectOptimize.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp
index d480642..484705ea 100644
--- a/llvm/lib/CodeGen/SelectOptimize.cpp
+++ b/llvm/lib/CodeGen/SelectOptimize.cpp
@@ -489,8 +489,10 @@ static Value *getTrueOrFalseValue(
}
auto *BO = cast<BinaryOperator>(SI.getI());
- assert(BO->getOpcode() == Instruction::Or &&
- "Only currently handling Or instructions.");
+ assert((BO->getOpcode() == Instruction::Add ||
+ BO->getOpcode() == Instruction::Or ||
+ BO->getOpcode() == Instruction::Sub) &&
+ "Only currently handling Add, Or and Sub binary operators.");
auto *CBO = BO->clone();
auto CondIdx = SI.getConditionOpIndex();
@@ -786,8 +788,23 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
// An Or(zext(i1 X), Y) can also be treated like a select, with condition X
// and values Y|1 and Y.
if (auto *BO = dyn_cast<BinaryOperator>(I)) {
- if (BO->getType()->isIntegerTy(1) || BO->getOpcode() != Instruction::Or)
- return SelectInfo.end();
+ switch (I->getOpcode()) {
+ case Instruction::Add:
+ case Instruction::Sub: {
+ Value *X;
+ if (!((PatternMatch::match(I->getOperand(0),
+ m_OneUse(m_ZExt(m_Value(X)))) ||
+ PatternMatch::match(I->getOperand(1),
+ m_OneUse(m_ZExt(m_Value(X))))) &&
+ X->getType()->isIntegerTy(1)))
+ return SelectInfo.end();
+ break;
+ }
+ case Instruction::Or:
+ if (BO->getType()->isIntegerTy(1) || BO->getOpcode() != Instruction::Or)
+ return SelectInfo.end();
+ break;
+ }
for (unsigned Idx = 0; Idx < 2; Idx++) {
auto *Op = BO->getOperand(Idx);