Bug 82597 - [8 Regression] ICE at -O2 and -O3 x86_64-linux-gnu in the 32-bit mode: in extract_constrain_insn, at recog.c:2207
Summary: [8 Regression] ICE at -O2 and -O3 x86_64-linux-gnu in the 32-bit mode: in ext...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
: 82592 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-10-18 03:40 UTC by Zhendong Su
Modified: 2017-11-10 16:45 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-10-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2017-10-18 03:40:21 UTC
$ gcctk -v
Using built-in specs.
COLLECT_GCC=gcctk
COLLECT_LTO_WRAPPER=/home/su/software/tmp/gcc/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/8.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/home/su/software/tmp/gcc/gcc-trunk --disable-bootstrap
Thread model: posix
gcc version 8.0.0 20171018 (experimental) [trunk revision 253840] (GCC) 
$ 
$ gcctk -m32 -Os -c -w small.c
$ 
$ gcctk -m32 -O2 -c -w small.c
small.c: In function ‘l’:
small.c:7:1: error: insn does not satisfy its constraints:
 void l () { j (); }
 ^~~~
(insn 56 8 10 2 (parallel [
            (set (reg:CCZ 17 flags)
                (compare:CCZ (plus:SI (reg:SI 2 cx [orig:88 _3 ] [88])
                        (const_int 1 [0x1]))
                    (const_int 0 [0])))
            (set (reg/v:SI 0 ax [orig:91 k ] [91])
                (plus:SI (reg:SI 2 cx [orig:88 _3 ] [88])
                    (const_int 1 [0x1])))
        ]) "small.c":6 225 {*addsi_2}
     (nil))
during RTL pass: pro_and_epilogue
small.c:7:1: internal compiler error: in extract_constrain_insn, at recog.c:2207
0x5fbe80 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
	../../gcc-source-trunk/gcc/rtl-error.c:108
0x5fbea6 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
	../../gcc-source-trunk/gcc/rtl-error.c:119
0xbc9ead extract_constrain_insn(rtx_insn*)
	../../gcc-source-trunk/gcc/recog.c:2207
0xbd33b6 copyprop_hardreg_forward_1
	../../gcc-source-trunk/gcc/regcprop.c:794
0xbd478e copyprop_hardreg_forward_bb_without_debug_insn(basic_block_def*)
	../../gcc-source-trunk/gcc/regcprop.c:1173
0xc39a03 prepare_shrink_wrap
	../../gcc-source-trunk/gcc/shrink-wrap.c:443
0xc39a03 try_shrink_wrapping(edge_def**, rtx_insn*)
	../../gcc-source-trunk/gcc/shrink-wrap.c:667
0x983fbc thread_prologue_and_epilogue_insns()
	../../gcc-source-trunk/gcc/function.c:6003
0x9847f2 rest_of_handle_thread_prologue_and_epilogue
	../../gcc-source-trunk/gcc/function.c:6488
0x9847f2 execute
	../../gcc-source-trunk/gcc/function.c:6530
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
$ 


-----------------------------------------------------------------


unsigned b, c, e, g;

int a (h, i) { return h > 0 && i ? : h + i; }
int d (int h, int i) { return h; }
long long f (long h, long long i) { return h + i; }
void j () { long k = f (d (1, e = c), g); a (k) && (b = 0); }
void l () { j (); }
Comment 1 Uroš Bizjak 2017-10-18 06:24:29 UTC
Postreload compare elimination pass creates invalid instruction when merging:

(insn 55 8 49 2 (set (reg/v:SI 0 ax [orig:92 k ] [92])
        (plus:SI (reg:SI 2 cx [orig:88 _2 ] [88])
            (const_int 1 [0x1]))) "pr82597.c":6 213 {*leasi}
     (nil))

and:

(insn 21 20 22 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg/v:SI 0 ax [orig:92 k ] [92])
            (const_int 0 [0]))) "pr82597.c":6 3 {*cmpsi_ccno_1}
     (nil))

The merged instruction:

(insn 56 8 10 2 (parallel [
            (set (reg:CCZ 17 flags)
                (compare:CCZ (plus:SI (reg:SI 2 cx [orig:88 _3 ] [88])
                        (const_int 1 [0x1]))
                    (const_int 0 [0])))
            (set (reg/v:SI 0 ax [orig:91 k ] [91])
                (plus:SI (reg:SI 2 cx [orig:88 _3 ] [88])
                    (const_int 1 [0x1])))
        ]) "pr82597.c":6 -1
     (nil))

does not satisfy constraints:

(define_insn "*add<mode>_2"
  [(set (reg FLAGS_REG)
	(compare
	  (plus:SWI
	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
	    (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
	  (const_int 0)))
   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
	(plus:SWI (match_dup 1) (match_dup 2)))]

since input and output register has to be matched. cmpelim pass should check if merged instruction satisfies constraints.

(Must be some recent development that introduced the failure. IIRC, cmpelim pass substitutes FLAGS_REG clobber in the pattern with the follow-up comparison. LEA has no clobber, so that should prevent merging).

Confirmed as a rtl-optimization problem.
Comment 2 Drea Pinski 2017-10-18 06:29:24 UTC
Most likely caused by:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ba23db3e5d047f35d95c6a14cd404b63926e196

2017-10-14  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
    Michael Collison <michael.collison@arm.com>

* compare-elim.c: Include emit-rtl.h.
(can_merge_compare_into_arith): New function.
(try_validate_parallel): Likewise.
(try_merge_compare): Likewise.
(try_eliminate_compare): Call the above when no previous clobber
is available.
(execute_compare_elim_after_reload): Add DF_UD_CHAIN and DF_DU_CHAIN
dataflow problems.

2017-10-14  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
    Michael Collison <michael.collison@arm.com>

* gcc.target/aarch64/cmpelim_mult_uses_1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253764 138bc75d-0d04-0410-961f-82ee72b054a4
Comment 3 Arseny Solokha 2017-10-18 06:30:18 UTC
*** Bug 82592 has been marked as a duplicate of this bug. ***
Comment 4 Michael Collison 2017-10-19 18:40:24 UTC
I am testing a patch that adds constrain the operands in compare-elim.c. Note however that the test case has bug in it that seems to trigger the ICE. Without the bug in the test case, the ICE no longer occurs.

Specifically the function 'int a (h, i)' has two parameters that default to int. However in the call to function 'a' in:

void j () { long k = f (d (1, e = c), g); a (k) && (b = 0); }

only one argument 'k' is passed. When I modify the test case to add another argument the ICE does not occur.
Comment 5 Arseny Solokha 2017-10-19 19:09:27 UTC
So there is another testcase in PR82592.
Comment 6 Michael Collison 2017-10-19 20:17:44 UTC
Yes I am aware of that report. I have a fix that should be sent to gcc-patches shortly.
Comment 7 Jakub Jelinek 2017-11-01 21:52:53 UTC
Author: jakub
Date: Wed Nov  1 21:52:21 2017
New Revision: 254328

URL: https://gcc.gnu.org/viewcvs?rev=254328&root=gcc&view=rev
Log:
	PR rtl-optimization/82778
	PR rtl-optimization/82597
	* compare-elim.c (struct comparison): Add in_a_setter field.
	(find_comparison_dom_walker::before_dom_children): Remove killed
	bitmap and df_simulate_find_defs call, instead walk the defs.
	Compute last_setter and initialize in_a_setter.  Merge definitions
	with first initialization for a few variables.
	(try_validate_parallel): Use insn_invalid_p instead of
	recog_memoized.  Return insn rather than just the pattern.
	(try_merge_compare): Fix up comment.  Don't uselessly test if
	in_a is a REG_P.  Use cmp->in_a_setter instead of walking UD
	chains.
	(execute_compare_elim_after_reload): Remove df_chain_add_problem
	call.

	* g++.dg/opt/pr82778.C: New test.

2017-11-01  Michael Collison  <michael.collison@arm.com>

	PR rtl-optimization/82597
	* gcc.dg/pr82597.c: New test.

Added:
    trunk/gcc/testsuite/g++.dg/opt/pr82778.C
    trunk/gcc/testsuite/gcc.dg/pr82597.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/compare-elim.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Arseny Solokha 2017-11-10 10:04:59 UTC
Is it safe to close this PR now?
Comment 9 Jakub Jelinek 2017-11-10 16:45:00 UTC
Fixed.