@@ -2204,6 +2204,13 @@ static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
2204
2204
match (Op1, m_c_Xor (m_Specific (Or), m_Specific (Y))))
2205
2205
return Constant::getNullValue (Op0->getType ());
2206
2206
2207
+ const APInt *C1;
2208
+ Value *A;
2209
+ // (A ^ C) & (A ^ ~C) -> 0
2210
+ if (match (Op0, m_Xor (m_Value (A), m_APInt (C1))) &&
2211
+ match (Op1, m_Xor (m_Specific (A), m_SpecificInt (~*C1))))
2212
+ return Constant::getNullValue (Op0->getType ());
2213
+
2207
2214
if (Op0->getType ()->isIntOrIntVectorTy (1 )) {
2208
2215
if (std::optional<bool > Implied = isImpliedCondition (Op0, Op1, Q.DL )) {
2209
2216
// If Op0 is true implies Op1 is true, then Op0 is a subset of Op1.
@@ -2473,6 +2480,11 @@ static Value *simplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
2473
2480
if (Value *V = threadBinOpOverPHI (Instruction::Or, Op0, Op1, Q, MaxRecurse))
2474
2481
return V;
2475
2482
2483
+ // (A ^ C) | (A ^ ~C) -> -1, i.e. all bits set to one.
2484
+ if (match (Op0, m_Xor (m_Value (A), m_APInt (C1))) &&
2485
+ match (Op1, m_Xor (m_Specific (A), m_SpecificInt (~*C1))))
2486
+ return Constant::getAllOnesValue (Op0->getType ());
2487
+
2476
2488
if (Op0->getType ()->isIntOrIntVectorTy (1 )) {
2477
2489
if (std::optional<bool > Implied =
2478
2490
isImpliedCondition (Op0, Op1, Q.DL , false )) {
0 commit comments