diff mbox series

avoid ice due to inconsistent argument types to fold_build (PR 90662)

Message ID b9c26ef6-a5fa-717c-98bd-cdcadaf0107d@gmail.com
State New
Headers show
Series avoid ice due to inconsistent argument types to fold_build (PR 90662) | expand

Commit Message

Martin Sebor June 13, 2019, 7:10 p.m. UTC
Attached is a fix for the fold_build call with inconsistent
argument types introduced in a recent commit of mine.

Tested on x86_64-linux.

Martin

Comments

Jeff Law June 14, 2019, 1:35 a.m. UTC | #1
On 6/13/19 1:10 PM, Martin Sebor wrote:
> Attached is a fix for the fold_build call with inconsistent
> argument types introduced in a recent commit of mine.
> 
> Tested on x86_64-linux.
> 
> Martin
> 
> gcc-90662.diff
> 
> PR tree-optimization/90662 - strlen of a string in a vla plus offset not folded
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/90662
> 	* tree-ssa-strlen.c (get_stridx): Convert fold_build2 operands
> 	to the same type.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR tree-optimization/90662
> 	* gcc.dg/pr90866-2.c: New test.
> 	* gcc.dg/pr90866.c: Ditto.
OK
jeff
Christophe Lyon June 18, 2019, 8:38 a.m. UTC | #2
On Fri, 14 Jun 2019 at 03:35, Jeff Law <law@redhat.com> wrote:
>
> On 6/13/19 1:10 PM, Martin Sebor wrote:
> > Attached is a fix for the fold_build call with inconsistent
> > argument types introduced in a recent commit of mine.
> >
> > Tested on x86_64-linux.
> >
> > Martin
> >
> > gcc-90662.diff
> >
> > PR tree-optimization/90662 - strlen of a string in a vla plus offset not folded
> >
> > gcc/ChangeLog:
> >
> >       PR tree-optimization/90662
> >       * tree-ssa-strlen.c (get_stridx): Convert fold_build2 operands
> >       to the same type.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       PR tree-optimization/90662
> >       * gcc.dg/pr90866-2.c: New test.
> >       * gcc.dg/pr90866.c: Ditto.
> OK
> jeff

Hi,

I've noticed that pr90866-2.c fails on arm-none-eabi:
/gcc/testsuite/gcc.dg/pr90866-2.c:17:5: error: conflicting types for 'i'
/gcc/testsuite/gcc.dg/pr90866-2.c:17:1: note: an argument type that
has a default promotion cannot match an empty parameter name list
declaration
/gcc/testsuite/gcc.dg/pr90866-2.c:16:5: note: previous declaration of
'i' was here
compiler exited with status 1
FAIL: gcc.dg/pr90866-2.c (test for excess errors)

Removing 'int i();' makes the test pass, but I'm wondering why is
passes on other targets without this change?

Christophe
Martin Sebor June 18, 2019, 1:07 p.m. UTC | #3
On 6/18/19 2:38 AM, Christophe Lyon wrote:
> On Fri, 14 Jun 2019 at 03:35, Jeff Law <law@redhat.com> wrote:
>>
>> On 6/13/19 1:10 PM, Martin Sebor wrote:
>>> Attached is a fix for the fold_build call with inconsistent
>>> argument types introduced in a recent commit of mine.
>>>
>>> Tested on x86_64-linux.
>>>
>>> Martin
>>>
>>> gcc-90662.diff
>>>
>>> PR tree-optimization/90662 - strlen of a string in a vla plus offset not folded
>>>
>>> gcc/ChangeLog:
>>>
>>>        PR tree-optimization/90662
>>>        * tree-ssa-strlen.c (get_stridx): Convert fold_build2 operands
>>>        to the same type.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>>        PR tree-optimization/90662
>>>        * gcc.dg/pr90866-2.c: New test.
>>>        * gcc.dg/pr90866.c: Ditto.
>> OK
>> jeff
> 
> Hi,
> 
> I've noticed that pr90866-2.c fails on arm-none-eabi:
> /gcc/testsuite/gcc.dg/pr90866-2.c:17:5: error: conflicting types for 'i'
> /gcc/testsuite/gcc.dg/pr90866-2.c:17:1: note: an argument type that
> has a default promotion cannot match an empty parameter name list
> declaration
> /gcc/testsuite/gcc.dg/pr90866-2.c:16:5: note: previous declaration of
> 'i' was here
> compiler exited with status 1
> FAIL: gcc.dg/pr90866-2.c (test for excess errors)
> 
> Removing 'int i();' makes the test pass, but I'm wondering why is
> passes on other targets without this change?

I'm sure it's because of the difference in type promotion rules
on the target.  The function declaration shouldn't have an impact
on the test case so I have removed it in r272418.

Thanks
Martin
Christophe Lyon June 18, 2019, 1:21 p.m. UTC | #4
On Tue, 18 Jun 2019 at 15:07, Martin Sebor <msebor@gmail.com> wrote:
>
> On 6/18/19 2:38 AM, Christophe Lyon wrote:
> > On Fri, 14 Jun 2019 at 03:35, Jeff Law <law@redhat.com> wrote:
> >>
> >> On 6/13/19 1:10 PM, Martin Sebor wrote:
> >>> Attached is a fix for the fold_build call with inconsistent
> >>> argument types introduced in a recent commit of mine.
> >>>
> >>> Tested on x86_64-linux.
> >>>
> >>> Martin
> >>>
> >>> gcc-90662.diff
> >>>
> >>> PR tree-optimization/90662 - strlen of a string in a vla plus offset not folded
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>>        PR tree-optimization/90662
> >>>        * tree-ssa-strlen.c (get_stridx): Convert fold_build2 operands
> >>>        to the same type.
> >>>
> >>> gcc/testsuite/ChangeLog:
> >>>
> >>>        PR tree-optimization/90662
> >>>        * gcc.dg/pr90866-2.c: New test.
> >>>        * gcc.dg/pr90866.c: Ditto.
> >> OK
> >> jeff
> >
> > Hi,
> >
> > I've noticed that pr90866-2.c fails on arm-none-eabi:
> > /gcc/testsuite/gcc.dg/pr90866-2.c:17:5: error: conflicting types for 'i'
> > /gcc/testsuite/gcc.dg/pr90866-2.c:17:1: note: an argument type that
> > has a default promotion cannot match an empty parameter name list
> > declaration
> > /gcc/testsuite/gcc.dg/pr90866-2.c:16:5: note: previous declaration of
> > 'i' was here
> > compiler exited with status 1
> > FAIL: gcc.dg/pr90866-2.c (test for excess errors)
> >
> > Removing 'int i();' makes the test pass, but I'm wondering why is
> > passes on other targets without this change?
>
> I'm sure it's because of the difference in type promotion rules
> on the target.
OK, it's surprising it work on arm-linux* and not on arm-none-eabi?

> The function declaration shouldn't have an impact
> on the test case so I have removed it in r272418.
OK thanks

>
> Thanks
> Martin
diff mbox series

Patch

PR tree-optimization/90662 - strlen of a string in a vla plus offset not folded

gcc/ChangeLog:

	PR tree-optimization/90662
	* tree-ssa-strlen.c (get_stridx): Convert fold_build2 operands
	to the same type.

gcc/testsuite/ChangeLog:

	PR tree-optimization/90662
	* gcc.dg/pr90866-2.c: New test.
	* gcc.dg/pr90866.c: Ditto.

Index: gcc/testsuite/gcc.dg/pr90866-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr90866-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr90866-2.c	(working copy)
@@ -0,0 +1,24 @@ 
+/* PR tree-optimization/90866 - ICE in fold_binary_loc, at fold-const.c:9827
+   { dg-do compile  }
+   { dg-options "-O2 -fsanitize=thread" } */
+
+typedef enum { a } b;
+typedef struct {
+  int c[0];
+} d;
+typedef struct {
+  int *data;
+} e;
+typedef struct {
+  e buffer;
+} f;
+int g, h;
+int i();
+int i(f *j, d *k, b l, int m) {
+  if (l)
+    if (m) {
+      h = j->buffer.data[0];
+      k->c[g] = k->c[g] * 8;
+    }
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/pr90866.c
===================================================================
--- gcc/testsuite/gcc.dg/pr90866.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr90866.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* PR tree-optimization/90866 - ICE in fold_binary_loc, at fold-const.c:9827
+   { dg-do compile  }
+   { dg-options "-O3 -Wall -fno-tree-loop-optimize" } */
+
+int a[1024], b[1024];
+
+void f (void)
+{
+  int i = 0;
+  for ( ; ; i++)
+    {
+    b[16] = a[i * 16 + 10];
+    b[i * 16 + 11] = a[i * 16 + 11] * 3;
+    b[i * 16 + 12] = a[i * 16 + 12] * 4;
+    b[i * 16 + 13] = a[i * 16 + 13] * 4;
+    b[i * 16 + 14] = a[i * 16 + 14] * 3;
+  }
+}
Index: gcc/tree-ssa-strlen.c
===================================================================
--- gcc/tree-ssa-strlen.c	(revision 272252)
+++ gcc/tree-ssa-strlen.c	(working copy)
@@ -322,11 +322,17 @@  get_stridx (tree exp)
 		  if (TREE_CODE (ptr) == ARRAY_REF)
 		    {
 		      off = TREE_OPERAND (ptr, 1);
-		      /* Scale the array index by the size of the element
-			 type (normally 1 for char).  */
-		      off = fold_build2 (MULT_EXPR, TREE_TYPE (off), off,
-					 eltsize);
 		      ptr = TREE_OPERAND (ptr, 0);
+		      if (!integer_onep (eltsize))
+			{
+			  /* Scale the array index by the size of the element
+			     type in the rare case that it's greater than
+			     the typical 1 for char, making sure both operands
+			     have the same type.  */
+			  eltsize = fold_convert (ssizetype, eltsize);
+			  off = fold_convert (ssizetype, off);
+			  off = fold_build2 (MULT_EXPR, ssizetype, off, eltsize);
+			}
 		    }
 		  else
 		    off = integer_zero_node;