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

            Bug ID: 90977
           Summary: Inconsistencies with inline asm
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: glisse at gcc dot gnu.org
  Target Milestone: ---

#ifdef M
# define C "m"
#else
# define C "g"
#endif
typedef long double T;
T f(T t){
#ifdef TWO
  asm volatile("":"=" C(t):"0"(t));
#else
  asm volatile("":"+" C(t));
#endif
  return t;
}

If I compile with -O2 and no preprocessor defines, the optimized dump and final
asm are

  __asm__ __volatile__("" : "=g" t_2 : "0" t_1(D));

        fldt    8(%rsp)
        fstpt   -24(%rsp)
        fldt    -24(%rsp)

which seem sensible. With -DM

  __asm__ __volatile__("" : "=m" t : "m" t);

        fldt    8(%rsp)

Notice how "0" silently became "m" here? It seems like wrong code. Let's try to
force it with -DM -DTWO

b.c:16:1: warning: matching constraint does not allow a register
[repeated 408 times, with varying line numbers]

  __asm__ __volatile__("" : "=m" t : "0" t);

        fldt    8(%rsp)

Let's try again with -DTWO only

  __asm__ __volatile__("" : "=g" t_2 : "0" t_1(D));

        fldt    8(%rsp)
        fstpt   -24(%rsp)
        fldt    -24(%rsp)

Why would 'g' generate more code than 'm' when it is supposed to contain 'm'?

For a different type, let's try

typedef double T __attribute__((vector_size(32)));

(I am not using -mavx or anything, so I get the expected -Wpsabi warning)

With -DM, no problem (I still get the suspicious "m" input constraint without
-DTWO, but the generated asm makes sense). Without -DM

b.c:13:28: error: inconsistent operand constraints in an 'asm'

If I pass -mavx, it becomes happy...

On a different target, powerpc64le-linux-gnu, with gcc-8.3, the behavior is
similar, except that "g" ICEs on 32-byte vectors.

Reply via email to