From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 00D8A3858C35; Fri, 2 Feb 2024 08:50:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 00D8A3858C35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1706863804; bh=M/xtS9xOlxFk/GY0RGYwYROxKg2GgCdz0El4mphrUto=; h=From:To:Subject:Date:In-Reply-To:References:From; b=qT5WP1TgRzL6Y5yBUyxrHUzNytRqpiUD1w5f4EhqSBMg07g09wsQKcL2Ws3S3VK7P NcOPE2qU0cTWmeOQSOYAWA5zSGdPXQPyI+NP1wptmaBRI1DgNkeRgPLJ9qvToY3eBe jN5vDX+B4Nqmo1ImriTFNZ8Gbq/3viotpZKlKZ9U= From: "juzhe.zhong at rivai dot ai" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/113134] gcc does not version loops with early break conditions that don't have side-effects Date: Fri, 02 Feb 2024 08:49:41 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: enhancement X-Bugzilla-Who: juzhe.zhong at rivai dot ai X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D113134 --- Comment #22 from JuzheZhong --- I have done this following experiment. diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index bf017137260..8c36cc63d3b 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -1260,6 +1260,39 @@ canonicalize_loop_induction_variables (class loop *l= oop, may_be_zero =3D false; } + if (!exit) + { + auto_vec exits =3D get_loop_exit_edges (loop); + exit =3D exits[0]; + class tree_niter_desc desc1; + class tree_niter_desc desc2; + if (number_of_iterations_exit (loop, exits[0], &desc1, false) + && number_of_iterations_exit (loop, exits[1], &desc2, false)) + { + niter =3D fold_build2 (MIN_EXPR, unsigned_type_node, desc1.ni= ter, + desc2.niter); + create_canonical_iv (loop, exit, niter); + gcond *cond_stmt; + class nb_iter_bound *elt; + for (elt =3D loop->bounds; elt; elt =3D elt->next) + { + if (elt->is_exit + && !wi::ltu_p (loop->nb_iterations_upper_bound, + elt->bound)) + { + cond_stmt =3D as_a (elt->stmt); + break; + } + } + if (exits[1]->flags & EDGE_TRUE_VALUE) + gimple_cond_make_false (cond_stmt); + else + gimple_cond_make_true (cond_stmt); + update_stmt (cond_stmt); + return false; + } + } + I know the check is wrong just for experiment, Then: [local count: 69202658]: _21 =3D (unsigned int) N_13(D); _22 =3D MIN_EXPR <_21, 1001>; ---- > Use MIN_EXPR as the check. _23 =3D _22 + 1; goto ; [100.00%] [local count: 1014686025]: _1 =3D (long unsigned int) i_9; _2 =3D _1 * 4; _3 =3D a_14(D) + _2; _4 =3D *_3; _5 =3D b_15(D) + _2; _6 =3D *_5; _7 =3D c_16(D) + _2; _8 =3D _4 + _6; *_7 =3D _8; if (0 !=3D 0) goto ; [1.00%] else goto ; [99.00%] [local count: 1004539166]: i_18 =3D i_9 + 1; [local count: 1073741824]: # i_9 =3D PHI <0(2), i_18(4)> # ivtmp_19 =3D PHI <_23(2), ivtmp_20(4)> ivtmp_20 =3D ivtmp_19 - 1; if (ivtmp_20 !=3D 0) goto ; [94.50%] else goto ; [5.50%] [local count: 69202658]: return; Then it can vectorize. I am not sure whether it is the right place to put the codes.=