Richard Sandiford <richard.sandif...@arm.com> writes: > Richard Sandiford <richard.sandif...@arm.com> writes: >> Marc Glisse <marc.gli...@inria.fr> writes: >>> On Thu, 15 Oct 2015, Richard Sandiford wrote: >>> >>>> This patch makes sure that, for every simplification that uses >>>> fold_strip_sign_ops, there are associated match.pd rules for the >>>> leaf sign ops, i.e. abs, negate and copysign. A follow-on patch >>>> will add a pass to handle more complex cases. >>>> >>>> Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. >>>> OK to install? >>>> >>>> Thanks, >>>> Richard >>>> >>>> >>>> gcc/ >>>> * match.pd: Add rules to simplify ccos, ccosh, hypot, copysign >>>> and x*x in cases where the operands are sign ops. Extend these >>>> rules to handle copysign as a sign op (including for cos, cosh >>>> and pow, which already treated negate and abs as sign ops). >>>> >>>> diff --git a/gcc/match.pd b/gcc/match.pd >>>> index 83c48cd..4331df6 100644 >>>> --- a/gcc/match.pd >>>> +++ b/gcc/match.pd >>>> @@ -61,6 +61,12 @@ along with GCC; see the file COPYING3. If not see >>>> (define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL) >>>> (define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL) >>>> (define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL) >>>> +(define_operator_list CCOS BUILT_IN_CCOSF BUILT_IN_CCOS BUILT_IN_CCOSL) >>>> +(define_operator_list CCOSH BUILT_IN_CCOSHF BUILT_IN_CCOSH >>>> BUILT_IN_CCOSHL) >>>> +(define_operator_list HYPOT BUILT_IN_HYPOTF BUILT_IN_HYPOT >>>> BUILT_IN_HYPOTL) >>>> +(define_operator_list COPYSIGN BUILT_IN_COPYSIGNF >>>> + BUILT_IN_COPYSIGN >>>> + BUILT_IN_COPYSIGNL) >>>> >>>> /* Simplifications of operations with one constant operand and >>>> simplifications to constants or single values. */ >>>> @@ -321,7 +327,69 @@ along with GCC; see the file COPYING3. If not see >>>> (pows (op @0) REAL_CST@1) >>>> (with { HOST_WIDE_INT n; } >>>> (if (real_isinteger (&TREE_REAL_CST (@1), &n) && (n & 1) == 0) >>>> - (pows @0 @1)))))) >>>> + (pows @0 @1))))) >>>> + /* Strip negate and abs from both operands of hypot. */ >>>> + (for hypots (HYPOT) >>>> + (simplify >>>> + (hypots (op @0) @1) >>>> + (hypots @0 @1)) >>>> + (simplify >>>> + (hypots @0 (op @1)) >>>> + (hypots @0 @1))) >>> >>> Out of curiosity, would hypots:c have worked? (it is probably not worth >>> gratuitously swapping the operands to save 3 lines though) >> >> Yeah, I think I'd prefer to keep it like it is if that's OK. >> >>>> + /* copysign(-x, y) and copysign(abs(x), y) -> copysign(x, y). */ >>>> + (for copysigns (COPYSIGN) >>>> + (simplify >>>> + (copysigns (op @0) @1) >>>> + (copysigns @0 @1))) >>>> + /* -x*-x and abs(x)*abs(x) -> x*x. Should be valid for all types. */ >>>> + (simplify >>>> + (mult (op @0) (op @1)) >>>> + (mult @0 @0))) >>> >>> Typo @1 -> @0 ? >> >> Argh! Thanks for catching that. Wonder how many proof-reads that >> escaped :-( >> >>> This will partially duplicate Naveen's patch "Move some bit and binary >>> optimizations in simplify and match". >> >> OK. Should I just limit it to the abs case? >> >>>> +/* copysign(x,y)*copysign(x,y) -> x*x. */ >>>> +(for copysigns (COPYSIGN) >>>> + (simplify >>>> + (mult (copysigns @0 @1) (copysigns @0 @1)) >>> >>> (mult (copysigns@2 @0 @1) @2) >>> ? Or is there some reason not to rely on CSE? (I don't think copysign has >>> any errno issue) >> >> No, simply didn't know about that trick. I'll use it for the >> (mult (op @0) (op @0)) case as well. > > Here's the updated patch. I've kept the (mult (negate@1 @0) @1) > pattern for now, but can limit it to abs as necessary when > Naveen's patch goes in. > > Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. > > Thanks, > Richard
Er... gcc/ * match.pd: Add rules to simplify ccos, ccosh, hypot, copysign and x*x in cases where the operands are sign ops. Extend these rules to handle copysign as a sign op (including for cos, cosh and pow, which already treated negate and abs as sign ops). diff --git a/gcc/match.pd b/gcc/match.pd index f3813d8..d677e69 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -61,6 +61,12 @@ along with GCC; see the file COPYING3. If not see (define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL) (define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL) (define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL) +(define_operator_list CCOS BUILT_IN_CCOSF BUILT_IN_CCOS BUILT_IN_CCOSL) +(define_operator_list CCOSH BUILT_IN_CCOSHF BUILT_IN_CCOSH BUILT_IN_CCOSHL) +(define_operator_list HYPOT BUILT_IN_HYPOTF BUILT_IN_HYPOT BUILT_IN_HYPOTL) +(define_operator_list COPYSIGN BUILT_IN_COPYSIGNF + BUILT_IN_COPYSIGN + BUILT_IN_COPYSIGNL) /* Simplifications of operations with one constant operand and simplifications to constants or single values. */ @@ -322,7 +328,69 @@ along with GCC; see the file COPYING3. If not see (pows (op @0) REAL_CST@1) (with { HOST_WIDE_INT n; } (if (real_isinteger (&TREE_REAL_CST (@1), &n) && (n & 1) == 0) - (pows @0 @1)))))) + (pows @0 @1))))) + /* Strip negate and abs from both operands of hypot. */ + (for hypots (HYPOT) + (simplify + (hypots (op @0) @1) + (hypots @0 @1)) + (simplify + (hypots @0 (op @1)) + (hypots @0 @1))) + /* copysign(-x, y) and copysign(abs(x), y) -> copysign(x, y). */ + (for copysigns (COPYSIGN) + (simplify + (copysigns (op @0) @1) + (copysigns @0 @1))) + /* -x*-x and abs(x)*abs(x) -> x*x. Should be valid for all types. */ + (simplify + (mult (op@1 @0) @1) + (mult @0 @0))) + +/* cos(copysign(x, y)) -> cos(x). Similarly for cosh. */ +(for coss (COS COSH) + copysigns (COPYSIGN) + (simplify + (coss (copysigns @0 @1)) + (coss @0))) + +/* pow(copysign(x, y), z) -> pow(x, z) if z is an even integer. */ +(for pows (POW) + copysigns (COPYSIGN) + (simplify + (pows (copysigns @0 @1) REAL_CST@1) + (with { HOST_WIDE_INT n; } + (if (real_isinteger (&TREE_REAL_CST (@1), &n) && (n & 1) == 0) + (pows @0 @1))))) + +(for hypots (HYPOT) + copysigns (COPYSIGN) + /* hypot(copysign(x, y), z) -> hypot(x, z). */ + (simplify + (hypots (copysigns @0 @1) @2) + (hypots @0 @2)) + /* hypot(x, copysign(y, z)) -> hypot(x, y). */ + (simplify + (hypots @0 (copysigns @1 @2)) + (hypots @0 @1))) + +/* copysign(copysign(x, y), z) -> copysign(x, z). */ +(for copysigns (COPYSIGN) + (simplify + (copysigns (copysigns @0 @1) @2) + (copysigns @0 @2))) + +/* copysign(x,y)*copysign(x,y) -> x*x. */ +(for copysigns (COPYSIGN) + (simplify + (mult (copysigns@2 @0 @1) @2) + (mult @0 @0))) + +/* ccos(-x) -> ccos(x). Similarly for ccosh. */ +(for ccoss (CCOS CCOSH) + (simplify + (ccoss (negate @0)) + (ccoss @0))) /* X % Y is smaller than Y. */ (for cmp (lt ge)