The result of expand_expr_addr_expr_1 is eventually converted to tmode,
and any variable offset is likewise applied in tmode, so tmode also seems
like the natural mode for applying constant offsets.  This patch makes sure
that the operand is converted to tmode first, just like we do for
variable offsets.  It fixes a case where the new plus_constant
assert triggers.

Tested on x86_64-linux-gnu.  Also tested by HJ on x32 (thanks).
OK to install?

Richard


gcc/
        PR middle-end/53698
        * expr.c (expand_expr_addr_expr_1): Convert to tmode before
        performing an addition.

gcc/testsuite/
        PR middle-end/53698
        * gcc.target/i386/pr53698.c: New test.

Index: gcc/expr.c
===================================================================
--- gcc/expr.c  2012-06-06 10:09:21.000000000 +0100
+++ gcc/expr.c  2012-06-18 09:35:35.361926943 +0100
@@ -7631,6 +7631,7 @@ expand_expr_addr_expr_1 (tree exp, rtx t
         of such an object.  */
       gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
 
+      result = convert_memory_address_addr_space (tmode, result, as);
       result = plus_constant (tmode, result, bitpos / BITS_PER_UNIT);
       if (modifier < EXPAND_SUM)
        result = force_operand (result, target);
Index: gcc/testsuite/gcc.target/i386/pr53698.c
===================================================================
--- /dev/null   2012-05-16 15:38:36.131804707 +0100
+++ gcc/testsuite/gcc.target/i386/pr53698.c     2012-06-18 09:36:01.033855874 
+0100
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-options "-O -mx32 -maddress-mode=long -fno-tree-dominator-opts" } */
+
+extern char foo[];
+
+void
+test2 (void)
+{
+  int s;
+  for (s = 0;; ++s)
+    {
+      if (foo[s] != s)
+       __builtin_abort ();
+      foo[s] = s;
+    }
+}

Reply via email to