From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by sourceware.org (Postfix) with ESMTPS id 825E63858D37 for ; Fri, 28 Apr 2023 10:38:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 825E63858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lj1-x22f.google.com with SMTP id 38308e7fff4ca-2a8bbea12d7so96719041fa.3 for ; Fri, 28 Apr 2023 03:38:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682678304; x=1685270304; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=M+zjYHbB4IIORp978/kAtq1CeMJrxGKGhuFo3scsxBI=; b=V2O7sVTFZWni5idFCHZpsAX7/Syx07Gh4XJwiLR15sd6xvXNWfwdz9wlR3YR1HwFV9 Cbivjlm1ZxTvvTasrWdGYFNYgyXjtpHX7OGTrN2IDSQP5HsA3TxzS/d3T8h0cGAKP9i7 esGA4O3jVDOyVDUmi1WF95JlvQNNXZFa5e/0ot2qXhROma7y+3UDPV8XCLDqJ77V4sCB gHuzfbDbCxi5leDc0BLywAAJRAPCXIv+/x/G1xRr8Vqmwe9/cPOg9mIJfzfCtQ+7K62W iOASeuNTNr7AF9kvJj1TJo0TI/8wVk18qn3z8Rb2ivJGy7NgDU1IHtJ+5rSc82AUIjLQ o+nQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682678304; x=1685270304; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=M+zjYHbB4IIORp978/kAtq1CeMJrxGKGhuFo3scsxBI=; b=WBoJbBw5kTMaGNgGZO2KNHp1G+rC0haCZ0gKGcqGV3JdNA/ss31/TleZkdSZFzzEd/ YoTNC7E5OyyLZXstOdpjlGy7nmgsR5Xh3FrX/4Uc5WvVVc331RZP6pM2Y+V1VpFtAizG E/IZ4paGQQ8jyk+BMV8LYxsUBQcugHNs+loc/FY6JVZw+JMYoVG2EfbeuJ5kbahAixy0 dvK+N+0Nrk+ZC/gI8Jgfvci/Lmc2VrG7EH7/NwxZFBmtJC0CGFCWLnTCmOkhd5hEHpLI Fg2lcM4O5r6S1KVKCammmapieR9alIGI4XBh2Hgnz1iSYblkrrANxNOmIJGpRdy2HNQx R0Gw== X-Gm-Message-State: AC+VfDzcLmq5D9YErEpl2qjDN2BUZ0RJ3EwXfxQE2ycPGF++zel8VAh0 PQa6CctJ7238Z7FLrWvBPbLQKOeBSslTLDR7Rf6VTiiA X-Google-Smtp-Source: ACHHUZ5MkHq4shSDB4iK4y+UG2g0iyBYfyuHMrkJamb1SOjdaXPR0fCUKVF6CnAxVEPzt9Lw4kcyCTvZ9is0mjrIyBU= X-Received: by 2002:a2e:9848:0:b0:2a7:80ff:86cd with SMTP id e8-20020a2e9848000000b002a780ff86cdmr1346629ljj.53.1682678303715; Fri, 28 Apr 2023 03:38:23 -0700 (PDT) MIME-Version: 1.0 References: <20230428033045.655785-1-apinski@marvell.com> In-Reply-To: <20230428033045.655785-1-apinski@marvell.com> From: Richard Biener Date: Fri, 28 Apr 2023 12:36:51 +0200 Message-ID: Subject: Re: [PATCH] PHIOPT: Move two_value_replacement to match.pd To: Andrew Pinski Cc: gcc-patches@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Fri, Apr 28, 2023 at 5:31=E2=80=AFAM Andrew Pinski via Gcc-patches wrote: > > This patch converts two_value_replacement function > into a match.pd pattern. > It is a direct translation with only one minor change, > does not check for the {0,+-1} case as that is handled > before in match.pd so there is no reason to do the extra > check for it. > > OK? Bootstrapped and tested on x86_64-linux-gnu with > no regressions. OK. Thanks, Richard. > gcc/ChangeLog: > > PR tree-optimization/100958 > * tree-ssa-phiopt.cc (two_value_replacement): Remove. > (pass_phiopt::execute): Don't call two_value_replacement. > * match.pd (a !=3D/=3D=3D CST1 ? CST2 : CST3): Add pattern to > handle what two_value_replacement did. > --- > gcc/match.pd | 94 ++++++++++++++++++++++++ > gcc/tree-ssa-phiopt.cc | 157 +---------------------------------------- > 2 files changed, 96 insertions(+), 155 deletions(-) > > diff --git a/gcc/match.pd b/gcc/match.pd > index 31fe5093218..e17597ead26 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -4632,6 +4632,100 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > ) > ) > ) > + > +/* Optimize > + # x_5 in range [cst1, cst2] where cst2 =3D cst1 + 1 > + x_5 ? cstN ? cst4 : cst3 > + # op is =3D=3D or !=3D and N is 1 or 2 > + to r_6 =3D x_5 + (min (cst3, cst4) - cst1) or > + r_6 =3D (min (cst3, cst4) + cst1) - x_5 depending on op, N and which > + of cst3 and cst4 is smaller. > + This was originally done by two_value_replacement in phiopt (PR 88676= ). */ > +(for eqne (ne eq) > + (simplify > + (cond (eqne SSA_NAME@0 INTEGER_CST@1) INTEGER_CST@2 INTEGER_CST@3) > + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) > + && INTEGRAL_TYPE_P (type) > + && (wi::to_widest (@2) + 1 =3D=3D wi::to_widest (@3) > + || wi::to_widest (@2) =3D=3D wi::to_widest (@3) + 1)) > + (with { > + value_range r; > + get_range_query (cfun)->range_of_expr (r, @0); > + if (r.undefined_p ()) > + r.set_varying (TREE_TYPE (@0)); > + > + wide_int min =3D r.lower_bound (); > + wide_int max =3D r.upper_bound (); > + } > + (if (min + 1 =3D=3D max > + && (wi::to_wide (@1) =3D=3D min > + || wi::to_wide (@1) =3D=3D max)) > + (with { > + tree arg0 =3D @2, arg1 =3D @3; > + tree type1; > + if ((eqne =3D=3D EQ_EXPR) ^ (wi::to_wide (@1) =3D=3D min)) > + std::swap (arg0, arg1); > + if (TYPE_PRECISION (TREE_TYPE (@0)) =3D=3D TYPE_PRECISION (type)) > + { > + /* Avoid performing the arithmetics in bool type which has dif= ferent > + semantics, otherwise prefer unsigned types from the two wit= h > + the same precision. */ > + if (TREE_CODE (TREE_TYPE (arg0)) =3D=3D BOOLEAN_TYPE > + || !TYPE_UNSIGNED (type)) > + type1 =3D TREE_TYPE (@0); > + else > + type1 =3D TREE_TYPE (arg0); > + } > + else if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)) > + type1 =3D TREE_TYPE (@0); > + else > + type1 =3D type; > + min =3D wide_int::from (min, TYPE_PRECISION (type1), > + TYPE_SIGN (TREE_TYPE (@0))); > + wide_int a =3D wide_int::from (wi::to_wide (arg0), TYPE_PRECISION= (type1), > + TYPE_SIGN (type)); > + enum tree_code code; > + wi::overflow_type ovf; > + if (tree_int_cst_lt (arg0, arg1)) > + { > + code =3D PLUS_EXPR; > + a -=3D min; > + if (!TYPE_UNSIGNED (type1)) > + { > + /* lhs is known to be in range [min, min+1] and we want to= add a > + to it. Check if that operation can overflow for those = 2 values > + and if yes, force unsigned type. */ > + wi::add (min + (wi::neg_p (a) ? 0 : 1), a, SIGNED, &ovf); > + if (ovf) > + type1 =3D unsigned_type_for (type1); > + } > + } > + else > + { > + code =3D MINUS_EXPR; > + a +=3D min; > + if (!TYPE_UNSIGNED (type1)) > + { > + /* lhs is known to be in range [min, min+1] and we want to= subtract > + it from a. Check if that operation can overflow for th= ose 2 > + values and if yes, force unsigned type. */ > + wi::sub (a, min + (wi::neg_p (min) ? 0 : 1), SIGNED, &ovf)= ; > + if (ovf) > + type1 =3D unsigned_type_for (type1); > + } > + } > + tree arg =3D wide_int_to_tree (type1, a); > + } > + (if (code =3D=3D PLUS_EXPR) > + (convert (plus (convert:type1 @0) { arg; })) > + (convert (minus { arg; } (convert:type1 @0))) > + ) > + ) > + ) > + ) > + ) > + ) > +) > #endif > > (simplify > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc > index 7fc6ac17b4a..4b43f1abdbc 100644 > --- a/gcc/tree-ssa-phiopt.cc > +++ b/gcc/tree-ssa-phiopt.cc > @@ -373,155 +373,6 @@ factor_out_conditional_conversion (edge e0, edge e1= , gphi *phi, > return newphi; > } > > -/* Optimize > - # x_5 in range [cst1, cst2] where cst2 =3D cst1 + 1 > - if (x_5 op cstN) # where op is =3D=3D or !=3D and N is 1 or 2 > - goto bb3; > - else > - goto bb4; > - bb3: > - bb4: > - # r_6 =3D PHI # where cst3 =3D=3D cst4 + 1 or cst4 = =3D=3D cst3 + 1 > - > - to r_6 =3D x_5 + (min (cst3, cst4) - cst1) or > - r_6 =3D (min (cst3, cst4) + cst1) - x_5 depending on op, N and which > - of cst3 and cst4 is smaller. */ > - > -static bool > -two_value_replacement (basic_block cond_bb, basic_block middle_bb, > - edge e1, gphi *phi, tree arg0, tree arg1) > -{ > - /* Only look for adjacent integer constants. */ > - if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)) > - || !INTEGRAL_TYPE_P (TREE_TYPE (arg1)) > - || TREE_CODE (arg0) !=3D INTEGER_CST > - || TREE_CODE (arg1) !=3D INTEGER_CST > - || (tree_int_cst_lt (arg0, arg1) > - ? wi::to_widest (arg0) + 1 !=3D wi::to_widest (arg1) > - : wi::to_widest (arg1) + 1 !=3D wi::to_widest (arg0))) > - return false; > - > - if (!empty_block_p (middle_bb)) > - return false; > - > - gcond *stmt =3D as_a (*gsi_last_bb (cond_bb)); > - tree lhs =3D gimple_cond_lhs (stmt); > - tree rhs =3D gimple_cond_rhs (stmt); > - > - if (TREE_CODE (lhs) !=3D SSA_NAME > - || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)) > - || TREE_CODE (rhs) !=3D INTEGER_CST) > - return false; > - > - switch (gimple_cond_code (stmt)) > - { > - case EQ_EXPR: > - case NE_EXPR: > - break; > - default: > - return false; > - } > - > - /* Defer boolean x ? 0 : {1,-1} or x ? {1,-1} : 0 to > - match_simplify_replacement. */ > - if (TREE_CODE (TREE_TYPE (lhs)) =3D=3D BOOLEAN_TYPE > - && (integer_zerop (arg0) > - || integer_zerop (arg1) > - || TREE_CODE (TREE_TYPE (arg0)) =3D=3D BOOLEAN_TYPE > - || (TYPE_PRECISION (TREE_TYPE (arg0)) > - <=3D TYPE_PRECISION (TREE_TYPE (lhs))))) > - return false; > - > - value_range r; > - get_range_query (cfun)->range_of_expr (r, lhs); > - if (r.undefined_p ()) > - r.set_varying (TREE_TYPE (lhs)); > - wide_int min =3D r.lower_bound (); > - wide_int max =3D r.upper_bound (); > - > - if (min + 1 !=3D max > - || (wi::to_wide (rhs) !=3D min > - && wi::to_wide (rhs) !=3D max)) > - return false; > - > - /* We need to know which is the true edge and which is the false > - edge so that we know when to invert the condition below. */ > - edge true_edge, false_edge; > - extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge)= ; > - if ((gimple_cond_code (stmt) =3D=3D EQ_EXPR) > - ^ (wi::to_wide (rhs) =3D=3D max) > - ^ (e1 =3D=3D false_edge)) > - std::swap (arg0, arg1); > - > - tree type; > - if (TYPE_PRECISION (TREE_TYPE (lhs)) =3D=3D TYPE_PRECISION (TREE_TYPE = (arg0))) > - { > - /* Avoid performing the arithmetics in bool type which has differe= nt > - semantics, otherwise prefer unsigned types from the two with > - the same precision. */ > - if (TREE_CODE (TREE_TYPE (arg0)) =3D=3D BOOLEAN_TYPE > - || !TYPE_UNSIGNED (TREE_TYPE (arg0))) > - type =3D TREE_TYPE (lhs); > - else > - type =3D TREE_TYPE (arg0); > - } > - else if (TYPE_PRECISION (TREE_TYPE (lhs)) > TYPE_PRECISION (TREE_TYPE = (arg0))) > - type =3D TREE_TYPE (lhs); > - else > - type =3D TREE_TYPE (arg0); > - > - min =3D wide_int::from (min, TYPE_PRECISION (type), > - TYPE_SIGN (TREE_TYPE (lhs))); > - wide_int a =3D wide_int::from (wi::to_wide (arg0), TYPE_PRECISION (typ= e), > - TYPE_SIGN (TREE_TYPE (arg0))); > - enum tree_code code; > - wi::overflow_type ovf; > - if (tree_int_cst_lt (arg0, arg1)) > - { > - code =3D PLUS_EXPR; > - a -=3D min; > - if (!TYPE_UNSIGNED (type)) > - { > - /* lhs is known to be in range [min, min+1] and we want to add = a > - to it. Check if that operation can overflow for those 2 val= ues > - and if yes, force unsigned type. */ > - wi::add (min + (wi::neg_p (a) ? 0 : 1), a, SIGNED, &ovf); > - if (ovf) > - type =3D unsigned_type_for (type); > - } > - } > - else > - { > - code =3D MINUS_EXPR; > - a +=3D min; > - if (!TYPE_UNSIGNED (type)) > - { > - /* lhs is known to be in range [min, min+1] and we want to subt= ract > - it from a. Check if that operation can overflow for those 2 > - values and if yes, force unsigned type. */ > - wi::sub (a, min + (wi::neg_p (min) ? 0 : 1), SIGNED, &ovf); > - if (ovf) > - type =3D unsigned_type_for (type); > - } > - } > - > - tree arg =3D wide_int_to_tree (type, a); > - gimple_seq stmts =3D NULL; > - lhs =3D gimple_convert (&stmts, type, lhs); > - tree new_rhs; > - if (code =3D=3D PLUS_EXPR) > - new_rhs =3D gimple_build (&stmts, PLUS_EXPR, type, lhs, arg); > - else > - new_rhs =3D gimple_build (&stmts, MINUS_EXPR, type, arg, lhs); > - new_rhs =3D gimple_convert (&stmts, TREE_TYPE (arg0), new_rhs); > - gimple_stmt_iterator gsi =3D gsi_for_stmt (stmt); > - gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); > - > - replace_phi_edge_with_variable (cond_bb, e1, phi, new_rhs); > - > - /* Note that we optimized this PHI. */ > - return true; > -} > > /* Return TRUE if SEQ/OP pair should be allowed during early phiopt. > Currently this is to allow MIN/MAX and ABS/NEGATE and constants. */ > @@ -4170,12 +4021,8 @@ pass_phiopt::execute (function *) > } > > /* Do the replacement of conditional if it can be done. */ > - if (!early_p > - && !diamond_p > - && two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) > - cfgchanged =3D true; > - else if (match_simplify_replacement (bb, bb1, bb2, e1, e2, phi, > - arg0, arg1, early_p, diamond_p= )) > + if (match_simplify_replacement (bb, bb1, bb2, e1, e2, phi, > + arg0, arg1, early_p, diamond_p)) > cfgchanged =3D true; > else if (!early_p > && !diamond_p > -- > 2.31.1 >