https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82221
H.J. Lu <hjl.tools at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2017-09-15 Ever confirmed|0 |1 --- Comment #4 from H.J. Lu <hjl.tools at gmail dot com> --- [hjl@gnu-6 gcc]$ cat x.c typedef unsigned long long u64; typedef struct { u64 __attribute__((aligned(8))) counter; } atomic64_t; typedef unsigned int u32; static inline __attribute__((always_inline,unused)) __attribute__((no_instrument_function)) unsigned long long paravirt_read_pmc(int counter) { return ({ u64 __ret; unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; { asm volatile("# foo" : "=a" (__eax), "=d" (__edx), "=c" (__ecx) : "a" ((unsigned long)(counter)) : "memory", "cc" , "sp"); __ret = (u64)((((u64)__edx) << 32) | __eax); } __ret; }); } typedef struct { atomic64_t a; } local64_t; struct hw_perf_event { union { struct { int event_base_rdpmc; int idx; }; }; local64_t prev_count; }; static inline __attribute__((always_inline,unused)) __attribute__((no_instrument_function)) u64 __bar(volatile u64 *ptr, u64 old, u64 new) { u64 prev; asm volatile(".pushsection .smp_locks,\"a\"\n" ".balign 4\n" ".long 671f - .\n" ".popsection\n" "671:" "\n\tlock; " "cmpxchg8b %1" : "=A" (prev), "+m" (*ptr) : "b" ((u32)new), "c" ((u32)(new >> 32)), "0" (old) : "memory"); return prev; } static inline __attribute__((always_inline,unused)) __attribute__((no_instrument_function)) long long bar(atomic64_t *v, long long o, long long n) { return ((__typeof__(*(&v->counter)))__bar((&v->counter), (unsigned long long)(o), (unsigned long long)(n))); } u64 foo (struct hw_perf_event *hwc, int shift) { u64 prev_raw_count, new_raw_count; int idx = hwc->idx; u64 delta; again: ((new_raw_count) = paravirt_read_pmc(hwc->event_base_rdpmc)); if (bar((&(&hwc->prev_count)->a), (prev_raw_count), (new_raw_count)) != prev_raw_count) goto again; return new_raw_count; } [hjl@gnu-6 gcc]$ ./xgcc -B./ -m32 -march=i686 x.c -O2 -S -mpreferred-stack-boundary=2 during RTL pass: final x.c: In function ‘foo’: x.c:74:1: internal compiler error: output_operand: invalid use of register 'frame' } ^ 0xadb606 output_operand_lossage(char const*, ...) /export/gnu/import/git/sources/gcc/gcc/final.c:3453 0x1350cff print_reg(rtx_def*, int, _IO_FILE*) /export/gnu/import/git/sources/gcc/gcc/config/i386/i386.c:18798 0x13531ad ix86_print_operand_address_as /export/gnu/import/git/sources/gcc/gcc/config/i386/i386.c:19809 0x13524c2 ix86_print_operand(_IO_FILE*, rtx_def*, int) /export/gnu/import/git/sources/gcc/gcc/config/i386/i386.c:19552 0xadc636 output_operand(rtx_def*, int) /export/gnu/import/git/sources/gcc/gcc/final.c:3887 0xadc285 output_asm_insn(char const*, rtx_def**) /export/gnu/import/git/sources/gcc/gcc/final.c:3803 0xadacf8 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*) /export/gnu/import/git/sources/gcc/gcc/final.c:3055 0xad8fc1 final(rtx_insn*, _IO_FILE*, int) /export/gnu/import/git/sources/gcc/gcc/final.c:2048 0xadd9db rest_of_handle_final /export/gnu/import/git/sources/gcc/gcc/final.c:4488 0xaddcf2 execute /export/gnu/import/git/sources/gcc/gcc/final.c:4562 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. [hjl@gnu-6 gcc]$