@@ -625,7 +625,8 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
625
625
return RHS;
626
626
}
627
627
628
- if (Mask & BMask_Mixed) {
628
+ if (Mask & (BMask_Mixed | BMask_NotMixed)) {
629
+ // Mixed:
629
630
// (icmp eq (A & B), C) & (icmp eq (A & D), E)
630
631
// We already know that B & C == C && D & E == E.
631
632
// If we can prove that (B & D) & (C ^ E) == 0, that is, the bits of
@@ -636,24 +637,50 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
636
637
// We can't simply use C and E because we might actually handle
637
638
// (icmp ne (A & B), B) & (icmp eq (A & D), D)
638
639
// with B and D, having a single bit set.
640
+
641
+ // NotMixed:
642
+ // (icmp ne (A & B), C) & (icmp ne (A & D), E)
643
+ // -> (icmp ne (A & (B & D)), (C & E))
644
+ // Check the intersection (B & D) for inequality.
645
+ // Assume that (B & D) == B || (B & D) == D, i.e B/D is a subset of D/B
646
+ // and (B & D) & (C ^ E) == 0, bits of C and E, which are shared by both the
647
+ // B and the D, don't contradict.
648
+ // Note that we can assume (~B & C) == 0 && (~D & E) == 0, previous
649
+ // operation should delete these icmps if it hadn't been met.
650
+
639
651
const APInt *OldConstC, *OldConstE;
640
652
if (!match (C, m_APInt (OldConstC)) || !match (E, m_APInt (OldConstE)))
641
653
return nullptr ;
642
654
643
- const APInt ConstC = PredL != NewCC ? *ConstB ^ *OldConstC : *OldConstC;
644
- const APInt ConstE = PredR != NewCC ? *ConstD ^ *OldConstE : *OldConstE;
655
+ auto FoldBMixed = [&](ICmpInst::Predicate CC, bool IsNot) -> Value * {
656
+ CC = IsNot ? CmpInst::getInversePredicate (CC) : CC;
657
+ const APInt ConstC = PredL != CC ? *ConstB ^ *OldConstC : *OldConstC;
658
+ const APInt ConstE = PredR != CC ? *ConstD ^ *OldConstE : *OldConstE;
645
659
646
- // If there is a conflict, we should actually return a false for the
647
- // whole construct.
648
- if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue ())
649
- return ConstantInt::get (LHS->getType (), !IsAnd);
660
+ if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue ())
661
+ return IsNot ? nullptr : ConstantInt::get (LHS->getType (), !IsAnd);
650
662
651
- Value *NewOr1 = Builder.CreateOr (B, D);
652
- Value *NewAnd = Builder.CreateAnd (A, NewOr1);
653
- Constant *NewOr2 = ConstantInt::get (A->getType (), ConstC | ConstE);
654
- return Builder.CreateICmp (NewCC, NewAnd, NewOr2);
655
- }
663
+ if (IsNot && !ConstB->isSubsetOf (*ConstD) && !ConstD->isSubsetOf (*ConstB))
664
+ return nullptr ;
656
665
666
+ APInt BD, CE;
667
+ if (IsNot) {
668
+ BD = *ConstB & *ConstD;
669
+ CE = ConstC & ConstE;
670
+ } else {
671
+ BD = *ConstB | *ConstD;
672
+ CE = ConstC | ConstE;
673
+ }
674
+ Value *NewAnd = Builder.CreateAnd (A, BD);
675
+ Value *CEVal = ConstantInt::get (A->getType (), CE);
676
+ return Builder.CreateICmp (CC, CEVal, NewAnd);
677
+ };
678
+
679
+ if (Mask & BMask_Mixed)
680
+ return FoldBMixed (NewCC, false );
681
+ if (Mask & BMask_NotMixed) // can be else also
682
+ return FoldBMixed (NewCC, true );
683
+ }
657
684
return nullptr ;
658
685
}
659
686
0 commit comments