Message ID | alpine.DEB.2.02.1605022320550.23827@laptop-mg.saclay.inria.fr |
---|---|
State | New |
Headers | show |
On Tue, May 3, 2016 at 8:36 AM, Marc Glisse <marc.glisse@inria.fr> wrote: > This removes the duplication. I also removed the case (A&B)&(A&C) which is > handled by reassoc. And I need 2 NOP checks, for the case where @0 is a > constant (that couldn't happen before my patch because canonicalization > would put the constant as second operand). Nicely spotted. Not sure we want to delay (A&B)&(A&C) until re-assoc. We have many patterns that reassoc would also catch, like (A + CST) + CST or (A + B)- A, albeit reassoc only handles the unsigned cases. > Bootstrap+regtest on powerpc64le-unknown-linux-gnu. Ok. Thanks, Richard. > 2016-05-03 Marc Glisse <marc.glisse@inria.fr> > > * match.pd ((A | B) & (A | C)): Generalize to BIT_XOR_EXPR. Mark > as commutative. Check both conversions are NOP. > ((A & B) OP (C & B)): Remove. > > -- > Marc Glisse > Index: gcc/match.pd > =================================================================== > --- gcc/match.pd (revision 235764) > +++ gcc/match.pd (working copy) > @@ -678,25 +678,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (simplify > (bit_xor:c (bit_and:c @0 @1) @1) > (bit_and (bit_not @0) @1)) > > /* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both > operands are another bit-wise operation with a common input. If so, > distribute the bit operations to save an operation and possibly two if > constants are involved. For example, convert > (A | B) & (A | C) into A | (B & C) > Further simplification will occur if B and C are constants. */ > -(for op (bit_and bit_ior) > - rop (bit_ior bit_and) > +(for op (bit_and bit_ior bit_xor) > + rop (bit_ior bit_and bit_and) > (simplify > - (op (convert? (rop:c @0 @1)) (convert? (rop @0 @2))) > - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) > + (op (convert? (rop:c @0 @1)) (convert? (rop:c @0 @2))) > + (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) > + && tree_nop_conversion_p (type, TREE_TYPE (@2))) > (rop (convert @0) (op (convert @1) (convert @2)))))) > > > (simplify > (abs (abs@1 @0)) > @1) > (simplify > (abs (negate @0)) > (abs @0)) > (simplify > @@ -780,26 +781,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > /* (x & y) | x -> x */ > (simplify > (bitop:c (rbitop:c @0 @1) @0) > @0) > /* (~x | y) & x -> x & y */ > /* (~x & y) | x -> x | y */ > (simplify > (bitop:c (rbitop:c (bit_not @0) @1) @0) > (bitop @0 @1))) > > -/* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */ > -(for bitop (bit_and bit_ior bit_xor) > - (simplify > - (bitop (bit_and:c @0 @1) (bit_and @2 @1)) > - (bit_and (bitop @0 @2) @1))) > - > /* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */ > (simplify > (bit_and (bit_ior @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2) > (bit_ior (bit_and @0 @2) (bit_and @1 @2))) > > /* Combine successive equal operations with constants. */ > (for bitop (bit_and bit_ior bit_xor) > (simplify > (bitop (bitop @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2) > (bitop @0 (bitop @1 @2)))) >
On Tue, 3 May 2016, Richard Biener wrote: > On Tue, May 3, 2016 at 8:36 AM, Marc Glisse <marc.glisse@inria.fr> wrote: >> This removes the duplication. I also removed the case (A&B)&(A&C) which is >> handled by reassoc. And I need 2 NOP checks, for the case where @0 is a >> constant (that couldn't happen before my patch because canonicalization >> would put the constant as second operand). > > Nicely spotted. Not sure we want to delay (A&B)&(A&C) until re-assoc. We have > many patterns that reassoc would also catch, like (A + CST) + CST or (A + B)- A, > albeit reassoc only handles the unsigned cases. (A&B)&A seems simple enough for match.pd, I thought (A&B)&(A&C) was starting to be a bit specialized. I could easily add it back (making it work with | at the same time), but then I am not convinced A&(B&C) is the best output. If A&B or A&C have several uses, then (A&B)&C or B&(A&C) seem preferable (and we would still have a transformation for (A&cst1)&cst2 so we wouldn't lose in the case where B and C are constants). We may still end up having to add some :s to the transformation I just touched.
On Tue, May 3, 2016 at 3:26 PM, Marc Glisse <marc.glisse@inria.fr> wrote: > On Tue, 3 May 2016, Richard Biener wrote: > >> On Tue, May 3, 2016 at 8:36 AM, Marc Glisse <marc.glisse@inria.fr> wrote: >>> >>> This removes the duplication. I also removed the case (A&B)&(A&C) which >>> is >>> handled by reassoc. And I need 2 NOP checks, for the case where @0 is a >>> constant (that couldn't happen before my patch because canonicalization >>> would put the constant as second operand). >> >> >> Nicely spotted. Not sure we want to delay (A&B)&(A&C) until re-assoc. We >> have >> many patterns that reassoc would also catch, like (A + CST) + CST or (A + >> B)- A, >> albeit reassoc only handles the unsigned cases. > > > (A&B)&A seems simple enough for match.pd, I thought (A&B)&(A&C) was starting > to be a bit specialized. I could easily add it back (making it work with | > at the same time), but then I am not convinced A&(B&C) is the best output. > If A&B or A&C have several uses, then (A&B)&C or B&(A&C) seem preferable > (and we would still have a transformation for (A&cst1)&cst2 so we wouldn't > lose in the case where B and C are constants). We may still end up having to > add some :s to the transformation I just touched. Yeah, these are always tricky questions. Note that re-assoc won't handle the case with multi-use A&C or A&B. The only reason to care for the single-use case is when we change operations for the mixed operand cases. For the all-&| case there is only the (usual) consideration about SSA lifetime extension. So maybe it makes sense to split out the all-&| cases. Richard. > -- > Marc Glisse
Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 235764) +++ gcc/match.pd (working copy) @@ -678,25 +678,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (bit_xor:c (bit_and:c @0 @1) @1) (bit_and (bit_not @0) @1)) /* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both operands are another bit-wise operation with a common input. If so, distribute the bit operations to save an operation and possibly two if constants are involved. For example, convert (A | B) & (A | C) into A | (B & C) Further simplification will occur if B and C are constants. */ -(for op (bit_and bit_ior) - rop (bit_ior bit_and) +(for op (bit_and bit_ior bit_xor) + rop (bit_ior bit_and bit_and) (simplify - (op (convert? (rop:c @0 @1)) (convert? (rop @0 @2))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (op (convert? (rop:c @0 @1)) (convert? (rop:c @0 @2))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) + && tree_nop_conversion_p (type, TREE_TYPE (@2))) (rop (convert @0) (op (convert @1) (convert @2)))))) (simplify (abs (abs@1 @0)) @1) (simplify (abs (negate @0)) (abs @0)) (simplify @@ -780,26 +781,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (x & y) | x -> x */ (simplify (bitop:c (rbitop:c @0 @1) @0) @0) /* (~x | y) & x -> x & y */ /* (~x & y) | x -> x | y */ (simplify (bitop:c (rbitop:c (bit_not @0) @1) @0) (bitop @0 @1))) -/* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */ -(for bitop (bit_and bit_ior bit_xor) - (simplify - (bitop (bit_and:c @0 @1) (bit_and @2 @1)) - (bit_and (bitop @0 @2) @1))) - /* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */ (simplify (bit_and (bit_ior @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2) (bit_ior (bit_and @0 @2) (bit_and @1 @2))) /* Combine successive equal operations with constants. */ (for bitop (bit_and bit_ior bit_xor) (simplify (bitop (bitop @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2) (bitop @0 (bitop @1 @2))))