Bug 41087 - [4.5/4.6 Regression]: cris-elf gfortran.dg/zero_sized_3.f90 -O3 -funroll-loops execution
Summary: [4.5/4.6 Regression]: cris-elf gfortran.dg/zero_sized_3.f90 -O3 -funroll-loo...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.5.0
: P4 normal
Target Milestone: 4.5.2
Assignee: Hans-Peter Nilsson
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-08-17 04:17 UTC by Hans-Peter Nilsson
Modified: 2010-09-13 01:07 UTC (History)
2 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: cris-axis-elf
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-12-03 04:08:06


Attachments
Somewhat simplified test-case (213 bytes, text/plain)
2010-09-08 02:13 UTC, Hans-Peter Nilsson
Details
patch (405 bytes, patch)
2010-09-09 08:11 UTC, Hans-Peter Nilsson
Details | Diff
Patch, take 2. (398 bytes, patch)
2010-09-10 03:25 UTC, Hans-Peter Nilsson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Hans-Peter Nilsson 2009-08-17 04:17:01 UTC
With revision r150587 this test passed.
From revision r150588 and on, this test has failed as follows:

Running /tmp/r150587-150588/gcc/gcc/testsuite/gfortran.dg/dg.exp ...
...
FAIL: gfortran.dg/zero_sized_3.f90  -O3 -fomit-frame-pointer -funroll-loops  execution test
FAIL: gfortran.dg/zero_sized_3.f90  -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions  execution test


With the message in the logfile being:
Executing on host: /tmp/r150587-150588/gccobj/gcc/testsuite/gfortran/../../gfortran -B/tmp/r150587-150588/gccobj/gcc/te\
stsuite/gfortran/../../ /tmp/r150587-150588/gcc/gcc/testsuite/gfortran.dg/zero_sized_3.f90   -O3 -fomit-frame-pointer -\
funroll-loops   -pedantic-errors   -isystem /tmp/r150587-150588/gccobj/cris-elf/./newlib/targ-include -isystem /tmp/r15\
0587-150588/gcc/newlib/libc/include -B/tmp/r150587-150588/gccobj/cris-elf/./libgloss/cris/ -L/tmp/r150587-150588/gccobj\
/cris-elf/./libgloss/cris -L/tmp/r150587-150588/gcc/libgloss/cris  -B/tmp/r150587-150588/gccobj/cris-elf/./newlib/ -L/t\
mp/r150587-150588/gccobj/cris-elf/./newlib -sim3  -B/tmp/r150587-150588/gccobj/cris-elf/./libgfortran/.libs -L/tmp/r150\
587-150588/gccobj/cris-elf/./libgfortran/.libs -L/tmp/r150587-150588/gccobj/cris-elf/./libiberty  -lm   -o ./zero_sized\
_3.exe    (timeout = 300)
PASS: gfortran.dg/zero_sized_3.f90  -O3 -fomit-frame-pointer -funroll-loops  (test for excess errors)
           0           0^M
program stopped with signal 6.^M
FAIL: gfortran.dg/zero_sized_3.f90  -O3 -fomit-frame-pointer -funroll-loops  execution test

Author of patch exposing the regression CC:ed.
I'll try and analyze a bit so I can point out the wrong code.
N.B., CRIS has post-increment.
Comment 1 Hans-Peter Nilsson 2009-08-17 04:56:17 UTC
I'll have to re-build r150587 to get a diff of the assembly.  Without that, the only things I can say are:
- it's the abort call in the test that is triggered
- the preceding line, "print *, pack (mm, mask)" can be safely commented out without affecting the bug.
- it's the first iteration
- j==1 and size (pack (mm, mask)) == 2 or vice versa.
Comment 2 Hans-Peter Nilsson 2009-12-03 04:08:06 UTC
Reappeared as described in (154917:154920] (which are non-specific changes)
Just keeping track, at the moment.
Comment 3 Hans-Peter Nilsson 2009-12-03 04:09:40 UTC
Forgot to mention that it had previously been hidden with a change in (151359..151366].
Comment 4 Richard Biener 2010-04-06 11:20:36 UTC
GCC 4.5.0 is being released.  Deferring to 4.5.1.
Comment 5 Richard Biener 2010-07-31 09:29:38 UTC
GCC 4.5.1 is being released, adjusting target milestone.
Comment 6 Hans-Peter Nilsson 2010-09-08 02:13:51 UTC
Created attachment 21731 [details]
Somewhat simplified test-case

I'm having a look at this.
I simplified the test-case somewhat, eliminating some loops and a print-call.
First appearing in the .ce2 dump of r150588 at -O3 -funroll-loops, we see:
...
IF-THEN-ELSE-JOIN block found, pass 1, test 15, then 37, else 36, join 38
scanning new insn with uid = 1223.
scanning new insn with uid = 1224.
scanning new insn with uid = 1225.
deleting insn with uid = 344.
deleting insn with uid = 332.
deleting insn with uid = 331.
deleting block 36
Removing jump 328.
deleting insn with uid = 328.
deleting insn with uid = 335.
deleting insn with uid = 334.
deleting block 37
merging block 38 into block 15
verify found no changes in insn with uid = 337.
verify found no changes in insn with uid = 338.
verify found no changes in insn with uid = 339.
verify found no changes in insn with uid = 340.
deleting insn with uid = 341.
Merged blocks 15 and 38.
Conversion succeeded on pass 1.
...
with a part of the simplified blocks having the somewhat suspicious instruction sequence:
...
(note 324 1220 327 15 NOTE_INSN_DELETED)

(insn 327 324 1223 15 /n/slask/hp_tmp/zs3a.f90:14 (set (cc0)
        (compare (mem/s:SI (post_inc:SI (reg:SI 241 [ ivtmp.23 ])) [3 S4 A8])
            (const_int 0 [0x0]))) 0 {*tstsi} (expr_list:REG_INC (reg:SI 241 [ ivtmp.23 ])
        (nil)))

(insn 1223 327 1224 15 /n/slask/hp_tmp/zs3a.f90:14 (set (cc0)
        (compare (mem/s:SI (post_inc:SI (reg:SI 241 [ ivtmp.23 ])) [3 S4 A8])
            (const_int 0 [0x0]))) 0 {*tstsi} (nil))

(insn 1224 1223 1225 15 /n/slask/hp_tmp/zs3a.f90:14 (set (reg:SI 324)
        (ne:SI (cc0)
            (const_int 0 [0x0]))) 210 {sne} (nil))

(insn 1225 1224 337 15 /n/slask/hp_tmp/zs3a.f90:14 (set (reg:SI 252 [ j ])
        (reg:SI 324)) 36 {*movsi_internal} (nil))
...

In the .combine dump, it's not apparent why this should be correct; note the first cc0 setter not having a user; with the only effect of the insn being the memory access (not volatile, so it doesn't count) and the post-increment.
This smells like a bug.
Whether in the post-combine ifcvt pass or in the input is unknown at this time.
Comment 7 Hans-Peter Nilsson 2010-09-09 04:08:03 UTC
Bother, I should have spotted the general area of this bug faster.  It's a matter of ifcvt.c calling
       emit_insn_before_setloc (seq, if_info->jump,
			       INSN_LOCATOR (if_info->insn_a));
when it should do
      emit_insn_before_setloc (seq, if_info->cond_earliest,
			       INSN_LOCATOR (if_info->insn_a));
(looks like most calls may be wrong)
*and* to handle the case where if_info->cond_earliest (insn 327 above) has side-effects, since try_redirect_by_replacing_jump (a callee of redirect_edge_and_branch_force) doesn't remove cc0 setters with side-effects (while without the if_info->cond_earliest change, it'd see the last of the emit_store_flag insns instead of the expected cc0 setter).  And last but not least, decorate the new insn(s) with REG_INC notes as appropriate, as regmove (the next pass) seems to expect them: note that insn 1223 doesn't have one.
Comment 8 Hans-Peter Nilsson 2010-09-09 04:11:11 UTC
(In reply to comment #7)
> And last but not
> least, decorate the new insn(s) with REG_INC notes as appropriate, as regmove
> (the next pass) seems to expect them: note that insn 1223 doesn't have one.

See-also PR11052, which got in trouble when the cstore *target* (not the test insn) had a post_inc.
Comment 9 Hans-Peter Nilsson 2010-09-09 08:11:17 UTC
Created attachment 21748 [details]
patch

The simplest solution is to correct noce_get_condition to not follow its documentation and not allow conditions that aren't "valid at JUMP" rather than "valid at EARLIEST", simply because we can't allow an additional side-effect.
Maybe too simple for some, but simple and safe enough for a release-branch.
Comment 10 Hans-Peter Nilsson 2010-09-10 03:25:01 UTC
Created attachment 21760 [details]
Patch, take 2.

Need to gate the side_effects_p call: tmp != NULL_RTX && side_effects_p (tmp).
Comment 11 Hans-Peter Nilsson 2010-09-11 04:56:06 UTC
Corrected component re: analysis.
Comment 12 Hans-Peter Nilsson 2010-09-13 00:49:42 UTC
Subject: Bug 41087

Author: hp
Date: Mon Sep 13 00:49:27 2010
New Revision: 164240

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164240
Log:
	PR rtl-optimization/41087
	* ifcvt.c (noce_get_condition): Don't allow conditions with
	side-effects.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/ifcvt.c

Comment 13 Hans-Peter Nilsson 2010-09-13 00:53:02 UTC
Subject: Bug 41087

Author: hp
Date: Mon Sep 13 00:52:48 2010
New Revision: 164241

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164241
Log:
	PR rtl-optimization/41087
	* ifcvt.c (noce_get_condition): Don't allow conditions with
	side-effects.

Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/ifcvt.c

Comment 14 Hans-Peter Nilsson 2010-09-13 01:07:58 UTC
committed <http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00932.html>