@@ -2217,47 +2217,47 @@ foldBitwiseLogicWithIntrinsics(BinaryOperator &I,
2217
2217
}
2218
2218
}
2219
2219
2220
- // Try to simplify X | Y by replacing occurrences of Y in X with 0.
2221
- // Similarly, simplify X & Y by replacing occurrences of Y in X with -1.
2220
+ // Try to simplify V by replacing occurrences of Op with RepOp, but only look
2221
+ // through bitwise operations. In particular, for X | Y we try to replace Y with
2222
+ // 0 inside X and for X & Y we try to replace Y with -1 inside X.
2222
2223
// Return the simplified result of X if successful, and nullptr otherwise.
2223
- static Value *simplifyAndOrWithOpReplaced (Value *X, Value *Y, bool IsAnd,
2224
+ // If SimplifyOnly is true, no new instructions will be created.
2225
+ static Value *simplifyAndOrWithOpReplaced (Value *V, Value *Op, Value *RepOp,
2226
+ bool SimplifyOnly,
2224
2227
InstCombinerImpl &IC,
2225
2228
unsigned Depth = 0 ) {
2226
- if (isa<Constant>(X) || X == Y )
2229
+ if (Op == RepOp )
2227
2230
return nullptr ;
2228
2231
2229
- Value *RHS;
2230
- if (match (X, m_c_And (m_Specific (Y), m_Value (RHS)))) {
2231
- return IsAnd ? RHS : Constant::getNullValue (X->getType ());
2232
- } else if (match (X, m_c_Or (m_Specific (Y), m_Value (RHS)))) {
2233
- return IsAnd ? Constant::getAllOnesValue (X->getType ()) : RHS;
2234
- } else if (match (X, m_c_Xor (m_Specific (Y), m_Value (RHS)))) {
2235
- if (IsAnd) {
2236
- if (X->hasOneUse ())
2237
- return IC.Builder .CreateNot (RHS);
2232
+ if (V == Op)
2233
+ return RepOp;
2238
2234
2239
- if (Value *NotRHS =
2240
- IC.getFreelyInverted (RHS, RHS->hasOneUse (), &IC.Builder ))
2241
- return NotRHS;
2242
- } else
2243
- return RHS;
2244
- }
2235
+ auto *I = dyn_cast<BinaryOperator>(V);
2236
+ if (!I || !I->isBitwiseLogicOp () || Depth >= 3 )
2237
+ return nullptr ;
2245
2238
2246
- // Replace uses of Y in X recursively.
2247
- Value *Op0, *Op1;
2248
- if (Depth < 2 && match (X, m_BitwiseLogic (m_Value (Op0), m_Value (Op1)))) {
2249
- // TODO: Relax the one-use constraint to clean up existing hard-coded
2250
- // simplifications.
2251
- if (!X->hasOneUse ())
2252
- return nullptr ;
2253
- Value *NewOp0 = simplifyAndOrWithOpReplaced (Op0, Y, IsAnd, IC, Depth + 1 );
2254
- Value *NewOp1 = simplifyAndOrWithOpReplaced (Op1, Y, IsAnd, IC, Depth + 1 );
2255
- if (!NewOp0 && !NewOp1)
2256
- return nullptr ;
2257
- return IC.Builder .CreateBinOp (cast<BinaryOperator>(X)->getOpcode (),
2258
- NewOp0 ? NewOp0 : Op0, NewOp1 ? NewOp1 : Op1);
2259
- }
2260
- return nullptr ;
2239
+ if (!I->hasOneUse ())
2240
+ SimplifyOnly = true ;
2241
+
2242
+ Value *NewOp0 = simplifyAndOrWithOpReplaced (I->getOperand (0 ), Op, RepOp,
2243
+ SimplifyOnly, IC, Depth + 1 );
2244
+ Value *NewOp1 = simplifyAndOrWithOpReplaced (I->getOperand (1 ), Op, RepOp,
2245
+ SimplifyOnly, IC, Depth + 1 );
2246
+ if (!NewOp0 && !NewOp1)
2247
+ return nullptr ;
2248
+
2249
+ if (!NewOp0)
2250
+ NewOp0 = I->getOperand (0 );
2251
+ if (!NewOp1)
2252
+ NewOp1 = I->getOperand (1 );
2253
+
2254
+ if (Value *Res = simplifyBinOp (I->getOpcode (), NewOp0, NewOp1,
2255
+ IC.getSimplifyQuery ().getWithInstruction (I)))
2256
+ return Res;
2257
+
2258
+ if (SimplifyOnly)
2259
+ return nullptr ;
2260
+ return IC.Builder .CreateBinOp (I->getOpcode (), NewOp0, NewOp1);
2261
2261
}
2262
2262
2263
2263
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
@@ -2781,9 +2781,13 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
2781
2781
if (Instruction *Res = foldBitwiseLogicWithIntrinsics (I, Builder))
2782
2782
return Res;
2783
2783
2784
- if (Value *V = simplifyAndOrWithOpReplaced (Op0, Op1, /* IsAnd*/ true , *this ))
2784
+ if (Value *V =
2785
+ simplifyAndOrWithOpReplaced (Op0, Op1, Constant::getAllOnesValue (Ty),
2786
+ /* SimplifyOnly*/ false , *this ))
2785
2787
return BinaryOperator::CreateAnd (V, Op1);
2786
- if (Value *V = simplifyAndOrWithOpReplaced (Op1, Op0, /* IsAnd*/ true , *this ))
2788
+ if (Value *V =
2789
+ simplifyAndOrWithOpReplaced (Op1, Op0, Constant::getAllOnesValue (Ty),
2790
+ /* SimplifyOnly*/ false , *this ))
2787
2791
return BinaryOperator::CreateAnd (Op0, V);
2788
2792
2789
2793
return nullptr ;
@@ -3602,14 +3606,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
3602
3606
if (match (Op1, m_Xor (m_Specific (B), m_Specific (A))))
3603
3607
return BinaryOperator::CreateOr (Op1, C);
3604
3608
3605
- // ((A & B) ^ C) | B -> C | B
3606
- if (match (Op0, m_c_Xor (m_c_And (m_Value (A), m_Specific (Op1)), m_Value (C))))
3607
- return BinaryOperator::CreateOr (C, Op1);
3608
-
3609
- // B | ((A & B) ^ C) -> B | C
3610
- if (match (Op1, m_c_Xor (m_c_And (m_Value (A), m_Specific (Op0)), m_Value (C))))
3611
- return BinaryOperator::CreateOr (Op0, C);
3612
-
3613
3609
if (Instruction *DeMorgan = matchDeMorgansLaws (I, *this ))
3614
3610
return DeMorgan;
3615
3611
@@ -3965,9 +3961,13 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
3965
3961
if (Instruction *Res = foldBitwiseLogicWithIntrinsics (I, Builder))
3966
3962
return Res;
3967
3963
3968
- if (Value *V = simplifyAndOrWithOpReplaced (Op0, Op1, /* IsAnd*/ false , *this ))
3964
+ if (Value *V =
3965
+ simplifyAndOrWithOpReplaced (Op0, Op1, Constant::getNullValue (Ty),
3966
+ /* SimplifyOnly*/ false , *this ))
3969
3967
return BinaryOperator::CreateOr (V, Op1);
3970
- if (Value *V = simplifyAndOrWithOpReplaced (Op1, Op0, /* IsAnd*/ false , *this ))
3968
+ if (Value *V =
3969
+ simplifyAndOrWithOpReplaced (Op1, Op0, Constant::getNullValue (Ty),
3970
+ /* SimplifyOnly*/ false , *this ))
3971
3971
return BinaryOperator::CreateOr (Op0, V);
3972
3972
3973
3973
return nullptr ;
0 commit comments