https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124209

--- Comment #3 from Uroš Bizjak <ubizjak at gmail dot com> ---
We can handle some more tree codes:

--cut here--
diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index 245ba357b5e..3f2f0d0af5a 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -3672,8 +3672,13 @@ expand_asm_stmt (gasm *stmt)
       generating_concat_p = 0;

       gcc_assert (TREE_CODE (val) != INDIRECT_REF);
-      if (((TREE_CODE (val) == MEM_REF
-           && TREE_CODE (TREE_OPERAND (val, 0)) != ADDR_EXPR)
+      if ((((TREE_CODE (val) == MEM_REF
+            && TREE_CODE (TREE_OPERAND (val, 0)) != ADDR_EXPR)
+           || (TREE_CODE (val) == COMPONENT_REF
+               && ! DECL_BIT_FIELD (TREE_OPERAND (val, 1)))
+           || TREE_CODE (val) == ARRAY_REF
+           || TREE_CODE (val) == REALPART_EXPR
+           || TREE_CODE (val) == IMAGPART_EXPR)
           && allows_mem)
          || (DECL_P (val)
              && (allows_mem || REG_P (DECL_RTL (val)))
--cut here--

to improve the following testcases:

--cut here--
#define savesegment(seg, value)                 \
  asm ("movw %%" #seg ",%0" : "=rm" (value))

short z[8];

void bar (int i)
{
  savesegment(fs,z[i]);
}

_Complex short c;

void baz_r (void)
{
  savesegment(fs, __real__ c);
}

void baz_i (void)
{
  savesegment(fs, __imag__ c);
}
--cut here--

from:

bar:
        movslq  %edi, %rdi
        movw %fs,%ax
        movw    %ax, z(%rdi,%rdi)
        ret

baz_r:
        movw %fs,%ax
        movw    %ax, c(%rip)
        ret

baz_i:
        movw %fs,%ax
        movw    %ax, c+2(%rip)
        ret

to:

bar:
        movslq  %edi, %rdi
        movw %fs,z(%rdi,%rdi)
        ret

baz_r:
        movw %fs,c(%rip)
        ret

baz_i:
        movw %fs,c+2(%rip)
        ret

Reply via email to