Bug 92644 - [9 Regression] ICE in wide_int_to_tree_1, at tree.c:1530
Summary: [9 Regression] ICE in wide_int_to_tree_1, at tree.c:1530
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 9.3
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-11-24 04:11 UTC by Arseny Solokha
Modified: 2019-12-23 10:42 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 8.3.0
Known to fail: 10.0, 9.2.0
Last reconfirmed: 2019-11-24 00:00:00


Attachments
gcc10-pr92644.patch (785 bytes, patch)
2019-11-25 10:43 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2019-11-24 04:11:59 UTC
g++-10.0.0-alpha20191117 snapshot (r278376) and 9.2.0 ICE when compiling the following testcase w/ -O1 -fno-early-inlining:

int
x8 ()
{
  return ([rn = nullptr] () { return rn; } ()) ? 1 : 0;
}

% g++-10.0.0-alpha20191117 -O1 -fno-early-inlining -c hfy7acky.C
during GIMPLE pass: phiopt
hfy7acky.C: In function 'int x8()':
hfy7acky.C:5:1: internal compiler error: in wide_int_to_tree_1, at tree.c:1530
    5 | }
      | ^
0x7ae494 wide_int_to_tree_1
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191117/work/gcc-10-20191117/gcc/tree.c:1530
0x10b76d4 minmax_replacement
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191117/work/gcc-10-20191117/gcc/tree-ssa-phiopt.c:1389
0x10bb49b tree_ssa_phiopt_worker
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191117/work/gcc-10-20191117/gcc/tree-ssa-phiopt.c:348
Comment 1 Jakub Jelinek 2019-11-24 14:23:20 UTC
Started with r265909.
NULLPTR_TYPE only allows value 0, so doing
          rhs = wide_int_to_tree (TREE_TYPE (rhs),
                                  wi::min_value (TREE_TYPE (rhs)) + 1);
for it ICEs.
I'd say we should guard that only for INTEGRAL_TYPE_P types and perhaps pointer/reference types too, though transformation of == NULL to < (void *) 1
looks really weird.
Comment 2 Jakub Jelinek 2019-11-24 17:59:48 UTC
For pointers, it boils down whether say
void *
foo (void *p)
{
  return p ? p : (void *) 1;
}
optimization into MAX_EXPR <1B, p> is valid or not.  The original code doesn't involve any non-equality comparisons, while MAX_EXPR is a non-equality comparison which ought to be valid only as long as the two pointers are pointing into the same object.  Another possibility would be for pointers to do this optimization, but perform the MIN_EXPR/MAX_EXPR in pointer sized ints instead.

So, the fix can be either NULLPTR_TYPE specific, like:
--- gcc/tree-ssa-phiopt.c	2019-11-20 09:25:42.552157763 +0100
+++ gcc/tree-ssa-phiopt.c	2019-11-24 18:56:50.657172109 +0100
@@ -1381,7 +1381,8 @@ minmax_replacement (basic_block cond_bb,
 
   /* Turn EQ/NE of extreme values to order comparisons.  */
   if ((cmp == NE_EXPR || cmp == EQ_EXPR)
-      && TREE_CODE (rhs) == INTEGER_CST)
+      && TREE_CODE (rhs) == INTEGER_CST
+      && TREE_CODE (TREE_TYPE (rhs)) != NULLPTR_TYPE)
     {
       if (wi::eq_p (wi::to_wide (rhs), wi::min_value (TREE_TYPE (rhs))))
 	{
@@ -1407,7 +1408,8 @@ minmax_replacement (basic_block cond_bb,
       larger = rhs;
       /* If we have smaller < CST it is equivalent to smaller <= CST-1.
 	 Likewise smaller <= CST is equivalent to smaller < CST+1.  */
-      if (TREE_CODE (larger) == INTEGER_CST)
+      if (TREE_CODE (larger) == INTEGER_CST
+	  && TREE_CODE (TREE_TYPE (larger)) != NULLPTR_TYPE)
 	{
 	  if (cmp == LT_EXPR)
 	    {
@@ -1435,7 +1437,8 @@ minmax_replacement (basic_block cond_bb,
       larger = gimple_cond_lhs (cond);
       /* If we have larger > CST it is equivalent to larger >= CST+1.
 	 Likewise larger >= CST is equivalent to larger > CST-1.  */
-      if (TREE_CODE (smaller) == INTEGER_CST)
+      if (TREE_CODE (smaller) == INTEGER_CST
+	  && TREE_CODE (TREE_TYPE (larger)) != NULLPTR_TYPE)
 	{
 	  wi::overflow_type overflow;
 	  if (cmp == GT_EXPR)
or instead of it say && (INTEGRAL_TYPE_P (TREE_TYPE (rhs)) || POINTER_TYPE_P (TREE_TYPE (rhs))), or just && INTEGRAL_TYPE_P (TREE_TYPE (rhs)), and if allowing POINTER_TYPE_P, we can also special case
new_stmt = gimple_build_assign (result, minmax, arg0, arg1);
for pointers by casting to integers and back.
Thoughts?
Comment 3 Richard Biener 2019-11-25 10:25:32 UTC
INTEGRAL_TYPE_P
Comment 4 Jakub Jelinek 2019-11-25 10:43:04 UTC
Created attachment 47350 [details]
gcc10-pr92644.patch

Untested fix.
Comment 5 Jakub Jelinek 2019-11-26 08:43:58 UTC
Author: jakub
Date: Tue Nov 26 08:43:27 2019
New Revision: 278720

URL: https://gcc.gnu.org/viewcvs?rev=278720&root=gcc&view=rev
Log:
	PR tree-optimization/92644
	* tree-ssa-phiopt.c (minmax_replacement): Add INTEGRAL_TYPE_P check
	next to INTEGER_CST checks.

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

Added:
    trunk/gcc/testsuite/g++.dg/opt/pr92644.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-phiopt.c
Comment 6 Jakub Jelinek 2019-11-26 09:31:11 UTC
Fixed on the trunk so far.
Comment 7 Jakub Jelinek 2019-12-20 16:58:40 UTC
Author: jakub
Date: Fri Dec 20 16:58:07 2019
New Revision: 279652

URL: https://gcc.gnu.org/viewcvs?rev=279652&root=gcc&view=rev
Log:
	Backported from mainline
	2019-11-26  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/92644
	* tree-ssa-phiopt.c (minmax_replacement): Add INTEGRAL_TYPE_P check
	next to INTEGER_CST checks.

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

Added:
    branches/gcc-9-branch/gcc/testsuite/g++.dg/opt/pr92644.C
Modified:
    branches/gcc-9-branch/gcc/ChangeLog
    branches/gcc-9-branch/gcc/testsuite/ChangeLog
    branches/gcc-9-branch/gcc/tree-ssa-phiopt.c
Comment 8 Jakub Jelinek 2019-12-20 18:30:07 UTC
Fixed for 9.3+ too.
Comment 9 Arseny Solokha 2019-12-23 05:23:03 UTC
I believe, it can be closed now, as the gcc 8 branch is not affected?
Comment 10 Jakub Jelinek 2019-12-23 10:42:37 UTC
.