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.