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]$

Reply via email to