From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 0C3FA3858425; Fri, 13 Jan 2023 11:46:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0C3FA3858425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1673610404; bh=UdrTXthEN/1IJWIw/ckxufpU1YnPQcTjk1N9Xjz3rRE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=U1CLTfq88ueKe+J2uMjTysKuQ9NdZ8ZmJ3Muijxxstpg54foJAVq2SaTmOvc6r60x cRIXfq0oiB7OSfM5rsjALYb3/JTmmxHSZcZDU3ure6tpZrKdd1WIxXMIXD0D3h8Fo4 yOWaB8i1YOvCBtL1IQfK6XA/0kRI155bPe2jXTM0= From: "burnus at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug fortran/107424] [13 Regression] ICE in gfc_trans_omp_do, at fortran/trans-openmp.cc:5397 - and wrong code - with non-rectangular loops Date: Fri, 13 Jan 2023 11:46:42 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: fortran X-Bugzilla-Version: 13.0 X-Bugzilla-Keywords: accepts-invalid, ice-on-valid-code, openmp, wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: burnus at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P4 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 13.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: keywords 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=3D107424 Tobias Burnus changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |accepts-invalid --- Comment #7 from Tobias Burnus --- (In reply to Jakub Jelinek from comment #6) > I think there are multiple issues. For the do i =3D 1, 9, 1 case, the bu= g is > that we: > to =3D gfc_evaluate_now (se.expr, pblock); The patch simply skips this if se.expr is already a DECL_P (as it is then I= MHO pointless) or if there is a non-rectangular loop nest. =E2=80=94 In the la= tter case, it additionally replaces 'inner =3D outer + a1' by 'inner =3D (count.outer + lb.outer) + a1' Thus, semantically, that should be fine but breaks with: ... > If the inner loop of non-rectangular loop nest (well, in particular whene= ver > from or to > uses some outer loop iterator and is one of the allowed non-rectangular > forms): ... > var-outer + a2 ... > var-outer * a1 + a2 > then using the non-simple expansion just can't work, the middle-end expec= ts > the init and cond expressions to be literally something from the above li= st, In the testcase I have - which does not use 'count' - the original dump for Fortran is: for (k =3D j + -41; k <=3D p; k =3D k + 1) but for C it is for (k =3D j * 1 + -41; k <=3D p; k++ ) Both are valid according to the list, but possibly the gimplifier does not handle 'outer + a2' but only 'outer * a1 + a2' which would explain the issue I see. From the code, it also looks as if a v= ery specific order is required =E2=80=93 and a TREE_VEC and not a normal expres= sion: if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var !=3D decl) for (int j =3D i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))= ; j++) { t =3D TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); gcc_assert (TREE_CODE (t) =3D=3D MODIFY_EXPR); if (TREE_CODE (TREE_OPERAND (t, 1)) =3D=3D TREE_VEC && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) =3D=3D decl) TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) =3D var; * * * With regards to 'count', I think it would still work - but the replacement ll * 3 + a1 cannot be: (count.0 + lb) * 3 + a1 but has to be: count.0 * 3 + (lb*3 + a1) Given that already quite some specific format is required (see above), it s= eems as if just continuing to use 'count' would work. It also would permit to add some additional checks, ensuring that the forma= t of the loop is correct. It also seems to be simpler than: > Now, the reason I've added the above expansion is because the middle-end = representation > was chosen to be of the C/C++ loops and I wasn't sure if the Fortran DO l= oop semantics > can be easily mapped to it. For the non-rectangular loops, I'm afraid we= have to, > or have some flag on each of the OMP_FOR/GOMP_FOR loops to request Fortra= n semantics. Note regarding: > if that is turned into something divided by step, we've lost. I note that for Fortran, the OpenMP spec (I looked at 5.2) has: lb, ub One of the following: .... a1, a2, incr Integer expressions that are loop invariant with respect to the outermost loop of the10 loop nest. Thus, as soon as a DO loop has an increment expression (even if it evaluate= s to '1'), neither a1 nor a2 nor incr can depend on any outer loop variable. Thus, it seems to be doable in the Fortran FE itself. Regarding the latter, gfortran accepts: do k =3D i - 41, p, p *4 which I think is wrong ('i - 41' does not fulfill this requirement)'. Likew= ise wrong is do k =3D i - 41, p, 1 but I am not sure whether the ',1' vs. absent is trivially detectable or no= t.=