forked from OSchip/llvm-project
[InstCombine] Clean up one-hot merge optimization (NFC)
Remove the requirement that the instruction is a BinaryOperator, make the predicate check more compact and use slightly more meaningful naming for the and operands.
This commit is contained in:
parent
764ad3b3fa
commit
1556540372
|
@ -798,36 +798,30 @@ foldAndOrOfEqualityCmpsWithConstants(ICmpInst *LHS, ICmpInst *RHS,
|
||||||
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
|
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
|
||||||
Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS,
|
Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS,
|
||||||
ICmpInst *RHS,
|
ICmpInst *RHS,
|
||||||
BinaryOperator &Logic) {
|
Instruction *CxtI,
|
||||||
bool JoinedByAnd = Logic.getOpcode() == Instruction::And;
|
bool IsAnd) {
|
||||||
assert((JoinedByAnd || Logic.getOpcode() == Instruction::Or) &&
|
CmpInst::Predicate Pred = IsAnd ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
|
||||||
"Wrong opcode");
|
if (LHS->getPredicate() != Pred || RHS->getPredicate() != Pred)
|
||||||
ICmpInst::Predicate Pred = LHS->getPredicate();
|
|
||||||
if (Pred != RHS->getPredicate())
|
|
||||||
return nullptr;
|
|
||||||
if (JoinedByAnd && Pred != ICmpInst::ICMP_NE)
|
|
||||||
return nullptr;
|
|
||||||
if (!JoinedByAnd && Pred != ICmpInst::ICMP_EQ)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!match(LHS->getOperand(1), m_Zero()) ||
|
if (!match(LHS->getOperand(1), m_Zero()) ||
|
||||||
!match(RHS->getOperand(1), m_Zero()))
|
!match(RHS->getOperand(1), m_Zero()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Value *A, *B, *C, *D;
|
Value *L1, *L2, *R1, *R2;
|
||||||
if (match(LHS->getOperand(0), m_And(m_Value(A), m_Value(B))) &&
|
if (match(LHS->getOperand(0), m_And(m_Value(L1), m_Value(L2))) &&
|
||||||
match(RHS->getOperand(0), m_And(m_Value(C), m_Value(D)))) {
|
match(RHS->getOperand(0), m_And(m_Value(R1), m_Value(R2)))) {
|
||||||
if (A == D || B == D)
|
if (L1 == R2 || L2 == R2)
|
||||||
std::swap(C, D);
|
std::swap(R1, R2);
|
||||||
if (B == C)
|
if (L2 == R1)
|
||||||
std::swap(A, B);
|
std::swap(L1, L2);
|
||||||
|
|
||||||
if (A == C &&
|
if (L1 == R1 &&
|
||||||
isKnownToBeAPowerOfTwo(B, false, 0, &Logic) &&
|
isKnownToBeAPowerOfTwo(L2, false, 0, CxtI) &&
|
||||||
isKnownToBeAPowerOfTwo(D, false, 0, &Logic)) {
|
isKnownToBeAPowerOfTwo(R2, false, 0, CxtI)) {
|
||||||
Value *Mask = Builder.CreateOr(B, D);
|
Value *Mask = Builder.CreateOr(L2, R2);
|
||||||
Value *Masked = Builder.CreateAnd(A, Mask);
|
Value *Masked = Builder.CreateAnd(L1, Mask);
|
||||||
auto NewPred = JoinedByAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
|
auto NewPred = IsAnd ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE;
|
||||||
return Builder.CreateICmp(NewPred, Masked, Mask);
|
return Builder.CreateICmp(NewPred, Masked, Mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1210,7 +1204,8 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
|
||||||
|
|
||||||
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
|
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
|
||||||
// if K1 and K2 are a one-bit mask.
|
// if K1 and K2 are a one-bit mask.
|
||||||
if (Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, And))
|
if (Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &And,
|
||||||
|
/* IsAnd */ true))
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
|
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
|
||||||
|
@ -2367,7 +2362,8 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
|
||||||
|
|
||||||
// Fold (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2)
|
// Fold (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2)
|
||||||
// if K1 and K2 are a one-bit mask.
|
// if K1 and K2 are a one-bit mask.
|
||||||
if (Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, Or))
|
if (Value *V = foldAndOrOfICmpsOfAndWithPow2(LHS, RHS, &Or,
|
||||||
|
/* IsAnd */ false))
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
|
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
|
||||||
|
|
|
@ -350,7 +350,7 @@ private:
|
||||||
Value *foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS, bool IsAnd);
|
Value *foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS, bool IsAnd);
|
||||||
|
|
||||||
Value *foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS, ICmpInst *RHS,
|
Value *foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS, ICmpInst *RHS,
|
||||||
BinaryOperator &Logic);
|
Instruction *CxtI, bool IsAnd);
|
||||||
Value *matchSelectFromAndOr(Value *A, Value *B, Value *C, Value *D);
|
Value *matchSelectFromAndOr(Value *A, Value *B, Value *C, Value *D);
|
||||||
Value *getSelectCondition(Value *A, Value *B);
|
Value *getSelectCondition(Value *A, Value *B);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue