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

            Bug ID: 124209
           Summary: Address of member of struct is not propagated into
                    assembly output
           Product: gcc
           Version: 15.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

This testcase:

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

struct thread_struct {
  short gs;
  short fs;
} m;

void foo (void)
{
  savesegment(fs, m.fs);
}
--cut here--

compiles with -O2 to:

foo:
#APP
        movw %fs,%ax
#NO_APP
        movw    %ax, m+2(%rip)
        ret

This is not optimal, the address of m.fs should be propagated to the asm.

The code is expanded as:

;; __asm__("movw %%fs,%0" : "=rm" m.fs);

(insn 7 4 5 (parallel [
            (set (reg:HI 98)
                (asm_operands:HI ("movw %%fs,%0") ("=rm") 0 []
                     []
                     [] saveseg.c:13))
            (clobber (reg:CC 17 flags))
        ]) "saveseg.c":13:3 -1
     (nil))

(insn 5 7 6 (set (reg/f:DI 99)
        (symbol_ref:DI ("m") [flags 0x2]  <var_decl 0x7f1ab3fd6e40 m>))
"saveseg.c":13:3 -1
     (nil))

(insn 6 5 0 (set (mem/c:HI (plus:DI (reg/f:DI 99)
                (const_int 2 [0x2])) [2 m.fs+0 S2 A16])
        (reg:HI 98)) "saveseg.c":13:3 -1
     (nil))

and address of struct member is never propagated back to asm (it doesn't matter
if asm is volatile or not).

The compiler has no problem propagating address of struct member when output
constraint is defined as "=m":

foo:
#APP
        movw %fs,m+2(%rip)
#NO_APP
        ret

where the code gets expanded as:

;; __asm__("movw %%fs,%0" : "=m" m.fs);

(insn 5 4 6 (set (reg/f:DI 98)
        (symbol_ref:DI ("m") [flags 0x2]  <var_decl 0x7f98521d6e40 m>))
"saveseg.c":13:3 -1
     (nil))

(insn 6 5 0 (parallel [
            (set (mem/c:HI (plus:DI (reg/f:DI 98)
                        (const_int 2 [0x2])) [2 m.fs+0 S2 A16])
                (asm_operands:HI ("movw %%fs,%0") ("=m") 0 []
                     []
                     [] saveseg.c:13))
            (clobber (reg:CC 17 flags))
        ]) "saveseg.c":13:3 -1
     (nil))

Reply via email to