@@ -2699,10 +2699,31 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
2699
2699
return BinaryOperator::CreateXor (Or, ConstantInt::get (I.getType (), *CV));
2700
2700
}
2701
2701
2702
- // (A & C)| (B & D)
2702
+ // (A & C) | (B & D)
2703
2703
Value *A, *B, *C, *D;
2704
2704
if (match (Op0, m_And (m_Value (A), m_Value (C))) &&
2705
2705
match (Op1, m_And (m_Value (B), m_Value (D)))) {
2706
+
2707
+ const APInt *MaskC0, *MaskC1;
2708
+ if (match (C, m_APInt (MaskC0)) && match (D, m_APInt (MaskC1)) &&
2709
+ *MaskC0 == ~*MaskC1) {
2710
+ Value *X;
2711
+
2712
+ // ((X | B) & C1) | (B & C2) -> (X & C1) | B iff C1 == ~C2
2713
+ if (match (A, m_c_Or (m_Value (X), m_Specific (B))))
2714
+ return BinaryOperator::CreateOr (Builder.CreateAnd (X, *MaskC0), B);
2715
+ // (A & C2) | ((X | A) & C1) -> (X & C2) | A iff C1 == ~C2
2716
+ if (match (B, m_c_Or (m_Specific (A), m_Value (X))))
2717
+ return BinaryOperator::CreateOr (Builder.CreateAnd (X, *MaskC1), A);
2718
+
2719
+ // ((X ^ B) & C1) | (B & C2) -> (X & C1) ^ B iff C1 == ~C2
2720
+ if (match (A, m_c_Xor (m_Value (X), m_Specific (B))))
2721
+ return BinaryOperator::CreateXor (Builder.CreateAnd (X, *MaskC0), B);
2722
+ // (A & C2) | ((X ^ A) & C1) -> (X & C2) ^ A iff C1 == ~C2
2723
+ if (match (B, m_c_Xor (m_Specific (A), m_Value (X))))
2724
+ return BinaryOperator::CreateXor (Builder.CreateAnd (X, *MaskC1), A);
2725
+ }
2726
+
2706
2727
// (A & C1)|(B & C2)
2707
2728
ConstantInt *C1, *C2;
2708
2729
if (match (C, m_ConstantInt (C1)) && match (D, m_ConstantInt (C2))) {
@@ -2738,24 +2759,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
2738
2759
Builder.getInt (C1->getValue ()|C2->getValue ()));
2739
2760
}
2740
2761
}
2741
-
2742
- if (C1->getValue () == ~C2->getValue ()) {
2743
- Value *X;
2744
-
2745
- // ((X|B)&C1)|(B&C2) -> (X&C1) | B iff C1 == ~C2
2746
- if (match (A, m_c_Or (m_Value (X), m_Specific (B))))
2747
- return BinaryOperator::CreateOr (Builder.CreateAnd (X, C1), B);
2748
- // (A&C2)|((X|A)&C1) -> (X&C2) | A iff C1 == ~C2
2749
- if (match (B, m_c_Or (m_Specific (A), m_Value (X))))
2750
- return BinaryOperator::CreateOr (Builder.CreateAnd (X, C2), A);
2751
-
2752
- // ((X^B)&C1)|(B&C2) -> (X&C1) ^ B iff C1 == ~C2
2753
- if (match (A, m_c_Xor (m_Value (X), m_Specific (B))))
2754
- return BinaryOperator::CreateXor (Builder.CreateAnd (X, C1), B);
2755
- // (A&C2)|((X^A)&C1) -> (X&C2) ^ A iff C1 == ~C2
2756
- if (match (B, m_c_Xor (m_Specific (A), m_Value (X))))
2757
- return BinaryOperator::CreateXor (Builder.CreateAnd (X, C2), A);
2758
- }
2759
2762
}
2760
2763
2761
2764
// Don't try to form a select if it's unlikely that we'll get rid of at
0 commit comments