i386_simplify_dwarf_addr (orig_x)
rtx orig_x;
{
- rtx x = orig_x;
+ rtx x = orig_x, y;
if (TARGET_64BIT)
{
}
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;
}
--- /dev/null
+// 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++);
+}