Bug 70725

Summary: Internal compiler error (ICE) on valid code
Product: gcc Reporter: Anton Mitrokhin <anton.mitrokhin>
Component: tree-optimizationAssignee: Marek Polacek <mpolacek>
Status: RESOLVED FIXED    
Severity: normal CC: hjl.tools
Priority: P3 Keywords: ice-on-valid-code
Version: 7.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: 6.1.0, 7.0 Last reconfirmed: 2016-04-19 00:00:00
Bug Depends on:    
Bug Blocks: 103035    
Attachments: Reproducer

Description Anton Mitrokhin 2016-04-19 09:09:05 UTC
Created attachment 38306 [details]
Reproducer

Test case produces internal compiler error with skylake-avx512, broadwell and knl targets on -O3 and -Ofast.

Reproducer:
> g++ -std=c++11 -Ofast -march=skylake-avx512 -c -o out small_if_conf.cpp
> g++ -std=c++11 -Ofast -march=broadwell -c -o out small_if_conf.cpp
> g++ -std=c++11 -Ofast -march=knl -c -o out small_if_conf.cpp

Output:
small.cpp: In function 'void fn1()':
small.cpp:13:6: internal compiler error: in predicate_mem_writes, at tree-if-conv.c:2033
 void fn1() {
      ^~~
0xd62007 predicate_mem_writes
        /export/users/gnutester/stability/svn/trunk/gcc/tree-if-conv.c:2033
0xd62007 combine_blocks
        /export/users/gnutester/stability/svn/trunk/gcc/tree-if-conv.c:2150
0xd644d8 tree_if_conversion
        /export/users/gnutester/stability/svn/trunk/gcc/tree-if-conv.c:2655
0xd644d8 execute
        /export/users/gnutester/stability/svn/trunk/gcc/tree-if-conv.c:2741
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.


------------------
> gcc -v:
------------------

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/export/users/amitrokh/gcc_trunk/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /export/users/gnutester/stability/svn/trunk/configure --with-arch=corei7 --with-cpu=corei7 --enable-clocale=gnu --with-system-zlib --enable-shared --with-demangler-in-ld --enable-cloog-backend=isl --with-fpmath=sse --with-pkgversion=Revision=235172/svn-rev:235172/ --prefix=/export/users/gnutester/stability/work/trunk/64/install --enable-languages=c,c++,fortran,java,lto
Thread model: posix
gcc version 7.0.0 20160418 (experimental) (Revision=235172/svn-rev:235172/)
Comment 1 Richard Biener 2016-04-19 09:57:55 UTC
Confirmed.

2043                    if (COMPARISON_CLASS_P (cond))
2044                      mask = gimple_build (&stmts, TREE_CODE (cond),
(gdb) l
2045                                           boolean_type_node,
2046                                           TREE_OPERAND (cond, 0),
2047                                           TREE_OPERAND (cond, 1));
2048                    else
2049                      {
2050                        gcc_assert (TREE_CODE (cond) == SSA_NAME);
2051                        mask = cond;
2052                      }

(gdb) p cond
$1 = <integer_cst 0x7ffff68a91b0>
(gdb) p debug_generic_expr (cond)
0

we guard against is_true_predicate but not against is_false_predicate.
Comment 2 Marek Polacek 2016-04-19 10:03:04 UTC
is_false_predicate doesn't seem to exist.  If this is all about adding that and using the new check, then I can take care of this.
Comment 3 Richard Biener 2016-04-19 10:09:33 UTC
I think so.  Of course only if-conversion figuring out a BB is unreachable
is "interesting", too ... (it doesn't handle that case very intelligently,
but that's another story).
Comment 4 Marek Polacek 2016-04-19 10:17:37 UTC
Thanks, I'll experiment with this a bit.
Comment 5 Marek Polacek 2016-04-20 09:33:17 UTC
Author: mpolacek
Date: Wed Apr 20 09:32:45 2016
New Revision: 235250

URL: https://gcc.gnu.org/viewcvs?rev=235250&root=gcc&view=rev
Log:
	PR tree-optimization/70725
	* tree-if-conv.c (is_false_predicate): New function.
	(predicate_mem_writes): Use it.

	* gcc.dg/pr70725.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr70725.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-if-conv.c
Comment 6 Marek Polacek 2016-04-20 10:09:03 UTC
Author: mpolacek
Date: Wed Apr 20 10:08:31 2016
New Revision: 235252

URL: https://gcc.gnu.org/viewcvs?rev=235252&root=gcc&view=rev
Log:
	PR tree-optimization/70725
	* tree-if-conv.c (is_false_predicate): New function.
	(predicate_mem_writes): Use it.

	* gcc.dg/pr70725.c: New test.

Added:
    branches/gcc-6-branch/gcc/testsuite/gcc.dg/pr70725.c
Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
    branches/gcc-6-branch/gcc/tree-if-conv.c
Comment 7 Marek Polacek 2016-04-20 10:11:39 UTC
Fixed.
Comment 8 H.J. Lu 2016-04-20 18:55:59 UTC
It leads to ICE on 32-bit host:

[hjl@gnu-6 gcc]$ ./xgcc -B./ /export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/pr70725.c -march=skylake-avx512 -O3
/export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/pr70725.c: In function ‘fn1’:
/export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/pr70725.c:13:1: internal compiler error: in phi_convertible_by_degenerating_args, at tree-if-conv.c:605
 fn1 ()
 ^~~
0x879899b phi_convertible_by_degenerating_args
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:605
0x879899b if_convertible_phi_p
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:664
0x879899b if_convertible_loop_p_1
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:1408
0x8798f27 if_convertible_loop_p
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:1466
0x8798f27 tree_if_conversion
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:2774
0x8798f27 execute
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:2875
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
[hjl@gnu-6 gcc]$ ./xgcc -v
Using built-in specs.
COLLECT_GCC=./xgcc
Target: i686-linux
Configured with: /export/gnu/import/git/sources/gcc/configure --enable-languages=c,c++ --disable-bootstrap i686-linux --prefix=/usr/gcc-7.0.0 --with-local-prefix=/usr/local --enable-gnu-indirect-function --enable-libmpx --disable-libcc1 --disable-libcilkrts --disable-libsanitizer --enable-clocale=gnu --with-system-zlib --with-demangler-in-ld --with-fpmath=sse
Thread model: posix
gcc version 7.0.0 20160420 (experimental) (GCC) 
[hjl@gnu-6 gcc]$
Comment 9 H.J. Lu 2016-04-20 19:09:13 UTC
gdb) f 1
#1  0x089eab96 in phi_convertible_by_degenerating_args (phi=0xf7895e00)
    at /export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:605
605	  gcc_assert (num_args > 2);
(gdb) p num_args
$3 = 1
(gdb)
Comment 10 H.J. Lu 2016-04-20 22:05:46 UTC
It also fails on x86-64:

/export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ /export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/pr70725.c -fno-diagnostics-show-caret -fdiagnostics-color=never -O3 -march=skylake-avx512 -S -o pr70725.s
/export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/pr70725.c: In function ‘fn1’:
/export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/pr70725.c:13:1: internal compiler error: in phi_convertible_by_degenerating_args, at tree-if-conv.c:605
0xec7591 phi_convertible_by_degenerating_args
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:605
0xec7761 if_convertible_phi_p
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:664
0xec9249 if_convertible_loop_p_1
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:1408
0xec9444 if_convertible_loop_p
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:1466
0xeccdc7 tree_if_conversion
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:2774
0xecd062 execute
	/export/gnu/import/git/sources/gcc/gcc/tree-if-conv.c:2875
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
[hjl@gnu-6 gcc]$
Comment 11 Richard Biener 2016-04-21 09:18:47 UTC
I think that's a separate issue.  if-conversion is confused about

.MEM_198 = PHI <.MEM_191(43)>

which it should simply ignore.

Index: tree-if-conv.c
===================================================================
--- tree-if-conv.c      (revision 235305)
+++ tree-if-conv.c      (working copy)
@@ -659,7 +659,7 @@ if_convertible_phi_p (struct loop *loop,
 
   if (bb != loop->header)
     {
-      if (gimple_phi_num_args (phi) != 2
+      if (gimple_phi_num_args (phi) > 2
          && !aggressive_if_conv
          && !phi_convertible_by_degenerating_args (phi))
        {

should fix the ICE but it leads to another latent issue:

/space/rguenther/src/svn/trunk/gcc/testsuite/gcc.dg/pr70725.c: In function 'fn1':
/space/rguenther/src/svn/trunk/gcc/testsuite/gcc.dg/pr70725.c:13:1: error: statement uses released SSA name:
# .MEM_202 = VDEF <.MEM_198>
# lhs access alignment 32+0
c[_73] = _ifc__387;
The use of .MEM_198 should have been replaced
/space/rguenther/src/svn/trunk/gcc/testsuite/gcc.dg/pr70725.c:13:1: internal compiler error: cannot update SSA form


Fixed by

Index: tree-if-conv.c
===================================================================
--- tree-if-conv.c      (revision 235305)
+++ tree-if-conv.c      (working copy)
@@ -1911,20 +1911,31 @@ predicate_all_scalar_phis (struct loop *
       if (bb == loop->header)
        continue;
 
-      if (EDGE_COUNT (bb->preds) == 1)
-       continue;
-
       phi_gsi = gsi_start_phis (bb);
       if (gsi_end_p (phi_gsi))
        continue;
 
-      gsi = gsi_after_labels (bb);
-      while (!gsi_end_p (phi_gsi))
+      if (EDGE_COUNT (bb->preds) == 1)
        {
-         phi = phi_gsi.phi ();
-         predicate_scalar_phi (phi, &gsi);
-         release_phi_node (phi);
-         gsi_next (&phi_gsi);
+         /* Propagate degenerate PHIs.  */
+         for (phi_gsi = gsi_start_phis (bb); !gsi_end_p (phi_gsi);
+              gsi_next (&phi_gsi))
+           {
+             gphi *phi = phi_gsi.phi ();
+             replace_uses_by (gimple_phi_result (phi),
+                              gimple_phi_arg_def (phi, 0));
+           }
+       }
+      else
+       {
+         gsi = gsi_after_labels (bb);
+         while (!gsi_end_p (phi_gsi))
+           {
+             phi = phi_gsi.phi ();
+             predicate_scalar_phi (phi, &gsi);
+             release_phi_node (phi);
+             gsi_next (&phi_gsi);
+           }
        }
 
       set_phi_nodes (bb, NULL);
Comment 12 Richard Biener 2016-04-21 09:22:34 UTC
Testing that.
Comment 13 Richard Biener 2016-04-21 14:10:05 UTC
Author: rguenth
Date: Thu Apr 21 14:09:33 2016
New Revision: 235341

URL: https://gcc.gnu.org/viewcvs?rev=235341&root=gcc&view=rev
Log:
2016-04-21  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/70725
	* tree-if-conv.c (if_convertible_phi_p): Adjust guard
	for phi_convertible_by_degenerating_args.
	(predicate_all_scalar_phis): Handle single-argument PHIs.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-if-conv.c
Comment 14 Richard Biener 2016-04-22 08:59:09 UTC
Fixed.