Hi!

If an input operand of inline-asm doesn't allow registers, but allows
memory, we expand it with EXPAND_MEMORY modifier (the only case of using
that modifier).  But the movmisalign code added for 4.6 and especially
the extract_bit_field code added for 4.8 results in getting a REG from
expand_expr called with a *MEM_REF with EXPAND_MEMORY, instead of MEM the
caller expects and can only handle, therefore we ICE.

This patch fixes it by honoring EXPAND_MEMORY in these cases, it is the sole
responsibility of the inline asm writer to do the right thing in there for
misaligned mems (e.g. gcc could pessimistically expect it might be
misaligned, but user knows it will not).

Bootstrapped/regtested on {x86_64,i686,armv7hl,ppc,ppc64,s390,s390x}-linux,
ok for trunk?

2013-02-21  Jakub Jelinek  <ja...@redhat.com>

        PR inline-asm/56405
        * expr.c (expand_expr_real_1) <case TARGET_MEM_REF, MEM_REF>: Don't
        use movmisalign or extract_bit_field for EXPAND_MEMORY modifier.

        * gcc.c-torture/compile/pr56405.c: New test.

--- gcc/expr.c.jj       2013-01-18 18:09:40.000000000 +0100
+++ gcc/expr.c  2013-02-20 10:29:34.513143634 +0100
@@ -9551,6 +9551,7 @@ expand_expr_real_1 (tree exp, rtx target
        set_mem_addr_space (temp, as);
        align = get_object_alignment (exp);
        if (modifier != EXPAND_WRITE
+           && modifier != EXPAND_MEMORY
            && mode != BLKmode
            && align < GET_MODE_ALIGNMENT (mode)
            /* If the target does not have special handling for unaligned
@@ -9639,6 +9640,7 @@ expand_expr_real_1 (tree exp, rtx target
        if (TREE_THIS_VOLATILE (exp))
          MEM_VOLATILE_P (temp) = 1;
        if (modifier != EXPAND_WRITE
+           && modifier != EXPAND_MEMORY
            && mode != BLKmode
            && align < GET_MODE_ALIGNMENT (mode))
          {
--- gcc/testsuite/gcc.c-torture/compile/pr56405.c.jj    2013-02-20 
10:32:17.807250979 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr56405.c       2013-02-20 
10:32:46.963090873 +0100
@@ -0,0 +1,7 @@
+/* PR inline-asm/56405 */
+
+void
+foo (void)
+{
+  asm volatile ("" : "+m" (*(volatile unsigned short *) 0x1001UL));
+}

        Jakub

Reply via email to