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
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;

Reply via email to