forked from OSchip/llvm-project
[InstCombine] Use m_APInt() in asymmetric masked icmp fold
This is mostly intended as code cleanup, but it does also add support for splat vectors to this fold.
This commit is contained in:
parent
e1fcf998dc
commit
5abaabed22
|
@ -379,9 +379,9 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
|
|||
//
|
||||
// We currently handle the case of B, C, D, E are constant.
|
||||
//
|
||||
ConstantInt *BCst, *CCst, *DCst, *ECst;
|
||||
if (!match(B, m_ConstantInt(BCst)) || !match(C, m_ConstantInt(CCst)) ||
|
||||
!match(D, m_ConstantInt(DCst)) || !match(E, m_ConstantInt(ECst)))
|
||||
const APInt *BCst, *CCst, *DCst, *OrigECst;
|
||||
if (!match(B, m_APInt(BCst)) || !match(C, m_APInt(CCst)) ||
|
||||
!match(D, m_APInt(DCst)) || !match(E, m_APInt(OrigECst)))
|
||||
return nullptr;
|
||||
|
||||
ICmpInst::Predicate NewCC = IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
|
||||
|
@ -390,19 +390,20 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
|
|||
// canonicalized as,
|
||||
// (icmp ne (A & D), 0) -> (icmp eq (A & D), D) or
|
||||
// (icmp ne (A & D), D) -> (icmp eq (A & D), 0).
|
||||
APInt ECst = *OrigECst;
|
||||
if (PredR != NewCC)
|
||||
ECst = cast<ConstantInt>(ConstantExpr::getXor(DCst, ECst));
|
||||
ECst ^= *DCst;
|
||||
|
||||
// If B or D is zero, skip because if LHS or RHS can be trivially folded by
|
||||
// other folding rules and this pattern won't apply any more.
|
||||
if (BCst->getValue() == 0 || DCst->getValue() == 0)
|
||||
if (*BCst == 0 || *DCst == 0)
|
||||
return nullptr;
|
||||
|
||||
// If B and D don't intersect, ie. (B & D) == 0, no folding because we can't
|
||||
// deduce anything from it.
|
||||
// For example,
|
||||
// (icmp ne (A & 12), 0) & (icmp eq (A & 3), 1) -> no folding.
|
||||
if ((BCst->getValue() & DCst->getValue()) == 0)
|
||||
if ((*BCst & *DCst) == 0)
|
||||
return nullptr;
|
||||
|
||||
// If the following two conditions are met:
|
||||
|
@ -421,22 +422,21 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
|
|||
// For example,
|
||||
// (icmp ne (A & 12), 0) & (icmp eq (A & 7), 1) -> (icmp eq (A & 15), 9)
|
||||
// (icmp ne (A & 15), 0) & (icmp eq (A & 7), 0) -> (icmp eq (A & 15), 8)
|
||||
if ((((BCst->getValue() & DCst->getValue()) & ECst->getValue()) == 0) &&
|
||||
(BCst->getValue() & (BCst->getValue() ^ DCst->getValue())).isPowerOf2()) {
|
||||
APInt BorD = BCst->getValue() | DCst->getValue();
|
||||
APInt BandBxorDorE = (BCst->getValue() & (BCst->getValue() ^ DCst->getValue())) |
|
||||
ECst->getValue();
|
||||
Value *NewMask = ConstantInt::get(BCst->getType(), BorD);
|
||||
Value *NewMaskedValue = ConstantInt::get(BCst->getType(), BandBxorDorE);
|
||||
if ((((*BCst & *DCst) & ECst) == 0) &&
|
||||
(*BCst & (*BCst ^ *DCst)).isPowerOf2()) {
|
||||
APInt BorD = *BCst | *DCst;
|
||||
APInt BandBxorDorE = (*BCst & (*BCst ^ *DCst)) | ECst;
|
||||
Value *NewMask = ConstantInt::get(A->getType(), BorD);
|
||||
Value *NewMaskedValue = ConstantInt::get(A->getType(), BandBxorDorE);
|
||||
Value *NewAnd = Builder.CreateAnd(A, NewMask);
|
||||
return Builder.CreateICmp(NewCC, NewAnd, NewMaskedValue);
|
||||
}
|
||||
|
||||
auto IsSubSetOrEqual = [](ConstantInt *C1, ConstantInt *C2) {
|
||||
return (C1->getValue() & C2->getValue()) == C1->getValue();
|
||||
auto IsSubSetOrEqual = [](const APInt *C1, const APInt *C2) {
|
||||
return (*C1 & *C2) == *C1;
|
||||
};
|
||||
auto IsSuperSetOrEqual = [](ConstantInt *C1, ConstantInt *C2) {
|
||||
return (C1->getValue() & C2->getValue()) == C2->getValue();
|
||||
auto IsSuperSetOrEqual = [](const APInt *C1, const APInt *C2) {
|
||||
return (*C1 & *C2) == *C2;
|
||||
};
|
||||
|
||||
// In the following, we consider only the cases where B is a superset of D, B
|
||||
|
@ -456,7 +456,7 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
|
|||
// For example,
|
||||
// (icmp ne (A & 3), 0) & (icmp eq (A & 7), 0) -> false.
|
||||
// (icmp ne (A & 15), 0) & (icmp eq (A & 3), 0) -> no folding.
|
||||
if (ECst->isZero()) {
|
||||
if (ECst.isZero()) {
|
||||
if (IsSubSetOrEqual(BCst, DCst))
|
||||
return ConstantInt::get(LHS->getType(), !IsAnd);
|
||||
return nullptr;
|
||||
|
@ -474,7 +474,7 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
|
|||
// ie. (B & E) != 0, then LHS is subsumed by RHS. For example.
|
||||
// (icmp ne (A & 12), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8).
|
||||
assert(IsSubSetOrEqual(BCst, DCst) && "Precondition due to above code");
|
||||
if ((BCst->getValue() & ECst->getValue()) != 0)
|
||||
if ((*BCst & ECst) != 0)
|
||||
return RHS;
|
||||
// Otherwise, LHS and RHS contradict and the whole expression becomes false
|
||||
// (or true if negated.) For example,
|
||||
|
|
|
@ -459,12 +459,9 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1(i32 %x) {
|
|||
|
||||
define <2 x i1> @masked_icmps_mask_notallzeros_bmask_mixed_1_vector(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_1_vector(
|
||||
; CHECK-NEXT: [[T1:%.*]] = and <2 x i32> [[X:%.*]], <i32 12, i32 12>
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ne <2 x i32> [[T1]], zeroinitializer
|
||||
; CHECK-NEXT: [[T3:%.*]] = and <2 x i32> [[X]], <i32 7, i32 7>
|
||||
; CHECK-NEXT: [[T4:%.*]] = icmp eq <2 x i32> [[T3]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: [[T5:%.*]] = and <2 x i1> [[T2]], [[T4]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[T5]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 15, i32 15>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 9, i32 9>
|
||||
; CHECK-NEXT: ret <2 x i1> [[TMP2]]
|
||||
;
|
||||
%t1 = and <2 x i32> %x, <i32 12, i32 12>
|
||||
%t2 = icmp ne <2 x i32> %t1, zeroinitializer
|
||||
|
|
Loading…
Reference in New Issue