From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id AD6AF384F00D; Fri, 13 Jan 2023 11:07:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AD6AF384F00D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1673608064; bh=4Rci484+ZyJ8RRPVlqetc6Lj++d41wIJi94lsanuH+o=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pmmo/f1JnCptyXv9z9iMUcxwFlc5iz8Hy8D3Z7r4eOIxemI4ZuRP6X8lQMwFtPH0M 9zxqXdvB1iGNjm+0nUgmLuvLTA7I/HxJXDgdMXE2AwAGpmuTNbIlk7WsjBOAMDJ/dU 7/XC9fj2IjqjHBH5Nx5bkWBCagQXsv9mYCeyhHzU= From: "jakub 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:07:43 +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: ice-on-valid-code, openmp, wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub 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: 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 --- Comment #6 from Jakub Jelinek --- I think there are multiple issues. For the do i =3D 1, 9, 1 case, the bug = is that we: gfc_init_se (&se, NULL); gfc_conv_expr_val (&se, code->ext.iterator->end); gfc_add_block_to_block (pblock, &se.pre); to =3D gfc_evaluate_now (se.expr, pblock); and therefore evaluate the upper expression (but ditto the lower expression) before the loop nest into a temporary rather than keeping it directly in the expression. That is fine for the cases where the expressions are loop invariant, which = was always the case before non-rectangular loops were introduced, but is not ok= for non-rectangular loops. I think the above patch deals with that somehow, but haven't studied yet exactly how. Don't know about the step2 case on the ou= ter loop, but guess it is similar to the below thing too. Another problem is that for steps other than -1 and 1, we use the non-simple expansion: /* STEP is not 1 or -1. Use: for (count =3D 0; count < (to + step - from) / step; count++) { dovar =3D from + count * step; body; cycle_label:; } */ If the inner loop of non-rectangular loop nest (well, in particular whenever from or to uses some outer loop iterator and is one of the allowed non-rectangular for= ms): var-outer var-outer + a2 a2 + var-outer var-outer - a2 a2 - var-outer a1 * var-outer a1 * var-outer + a2 a2 + a1 * var-outer a1 * var-outer - a2 a2 - a1 * var-outer var-outer * a1 var-outer * a1 + a2 a2 + var-outer * a1 var-outer * a1 - a2 a2 - var-outer * a1 then using the non-simple expansion just can't work, the middle-end expects the init and cond expressions to be literally something from the above list, if that is turned into something divided by step, we've lost. 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 loop semantics can be easily mapped to it. For the non-rectangular loops, I'm afraid we h= ave to, or have some flag on each of the OMP_FOR/GOMP_FOR loops to request Fortran semantics. If we do the latter, we'd need to adjust the middle-end (omp_extract_for_da= ta, everything that computes number of iterations, omp-expand loop expansion) to handle that. And I believe the non-simple outer loop is the same thing, for the non-rectangular loops the middle-end relies on the inner loop expressions that refer to var-outer= to be actually the outer loop's iterator. So if we use the non-simple expansion for the outer loop: for (count =3D 0; count < (to + step - from) / step; count++) { dovar =3D from + count * step; body; that would mean remapping the var_outer (aka dovar) in those expressions to count based computations.=