re PR rtl-optimization/5547 (g++ 3.1 crash in output_operand)
authorJakub Jelinek <jakub@redhat.com>
Wed, 13 Feb 2002 21:46:22 +0000 (22:46 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 13 Feb 2002 21:46:22 +0000 (22:46 +0100)
PR optimization/5547:
* config/i386/i386.c (i386_simplify_dwarf_addr): Simplify
all valid IA-32 address modes involving non-scaled %ebx and
GOT/GOTOFF as displacement.

* g++.dg/other/debug3.C: New test.

From-SVN: r49745

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/debug3.C [new file with mode: 0644]

index 349100284fc6f815fdf0b11718c02a507f5b47b9..ca7c17af6448fe8c9c7bd38364dd50af0a18f55d 100644 (file)
@@ -1,3 +1,10 @@
+2002-02-13  Jakub Jelinek  <jakub@redhat.com>
+
+       PR optimization/5547:
+       * config/i386/i386.c (i386_simplify_dwarf_addr): Simplify
+       all valid IA-32 address modes involving non-scaled %ebx and
+       GOT/GOTOFF as displacement.
+
 2002-02-13  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * config/s390/s390.c (s390_final_chunkify): Re-run shorten_branches
index 159ac165ac75f1367c9ddffd5128f3a3192d6a1e..40f88b5cc2f2f5fd791ad68554a08dc3b3160681 100644 (file)
@@ -5365,7 +5365,7 @@ rtx
 i386_simplify_dwarf_addr (orig_x)
      rtx orig_x;
 {
-  rtx x = orig_x;
+  rtx x = orig_x, y;
 
   if (TARGET_64BIT)
     {
@@ -5377,22 +5377,54 @@ i386_simplify_dwarf_addr (orig_x)
     }
 
   if (GET_CODE (x) != PLUS
-      || GET_CODE (XEXP (x, 0)) != REG
       || GET_CODE (XEXP (x, 1)) != CONST)
     return orig_x;
 
+  if (GET_CODE (XEXP (x, 0)) == REG
+      && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
+    /* %ebx + GOT/GOTOFF */
+    y = NULL;
+  else if (GET_CODE (XEXP (x, 0)) == PLUS)
+    {
+      /* %ebx + %reg * scale + GOT/GOTOFF */
+      y = XEXP (x, 0);
+      if (GET_CODE (XEXP (y, 0)) == REG
+         && REGNO (XEXP (y, 0)) == PIC_OFFSET_TABLE_REGNUM)
+       y = XEXP (y, 1);
+      else if (GET_CODE (XEXP (y, 1)) == REG
+              && REGNO (XEXP (y, 1)) == PIC_OFFSET_TABLE_REGNUM)
+       y = XEXP (y, 0);
+      else
+       return orig_x;
+      if (GET_CODE (y) != REG
+         && GET_CODE (y) != MULT
+         && GET_CODE (y) != ASHIFT)
+       return orig_x;
+    }
+  else
+    return orig_x;
+
   x = XEXP (XEXP (x, 1), 0);
   if (GET_CODE (x) == UNSPEC
       && (XINT (x, 1) == 6
          || XINT (x, 1) == 7))
-    return XVECEXP (x, 0, 0);
+    {
+      if (y)
+       return gen_rtx_PLUS (Pmode, y, XVECEXP (x, 0, 0));
+      return XVECEXP (x, 0, 0);
+    }
 
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 0)) == UNSPEC
       && GET_CODE (XEXP (x, 1)) == CONST_INT
       && (XINT (XEXP (x, 0), 1) == 6
          || XINT (XEXP (x, 0), 1) == 7))
-    return gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
+    {
+      x = gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
+      if (y)
+       return gen_rtx_PLUS (Pmode, y, x);
+      return x;
+    }
 
   return orig_x;
 }
index 56bd978f7afc81cca1388ab8389a6a491dfba847..58118cf9082aa784aeec582788ee8451809545f9 100644 (file)
@@ -1,3 +1,7 @@
+2002-02-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/other/debug3.C: New test.
+
 2002-02-13  Richard Smith <richard@ex-parrot.com>
 
        * g++.old-deja/g++.other/thunk1.C: New test.
diff --git a/gcc/testsuite/g++.dg/other/debug3.C b/gcc/testsuite/g++.dg/other/debug3.C
new file mode 100644 (file)
index 0000000..8525eef
--- /dev/null
@@ -0,0 +1,47 @@
+// PR optimization/5547
+// This testcase caused ICE on IA-32, since DWARF-2 was unable
+// to emit location expression for parameter a of operator+.
+// { dg-do compile }
+// { dg-options "-O2 -g -fpic" }
+
+struct A { char *s; };
+
+inline A operator+ (char a, const A &b)
+{
+  A s;
+  s.s = new char[12];
+  s.s[0] = a;
+  return s;
+}
+
+int b (const A &);
+
+void test1 (const A &x, int y)
+{
+  int j = b ("012345"[y] + x);
+  for (int i = 0; i < y; i++);
+}
+
+void test2 (const A &x, int y)
+{
+  int j = b ("012345678"[y + 2] + x);
+  for (int i = 0; i < y; i++);
+}
+
+void test3 (const A &x, int y)
+{
+  int j = b ("012345678"[y - 6] + x);
+  for (int i = 0; i < y; i++);
+}
+
+void test4 (const A &x, int y)
+{
+  int j = b ("012345678"[2 * y - 10] + x);
+  for (int i = 0; i < y; i++);
+}
+
+void test5 (const A &x, int y)
+{
+  int j = b ("012345678"[4 * y] + x);
+  for (int i = 0; i < y; i++);
+}