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