aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectOptimize.cpp
diff options
context:
space:
mode:
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);