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

            Bug ID: 92692
           Summary: Saving off the callee saved register between ldxr/stxr
                    (caused by shrink wrapping improvements)
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64-linux-gnu

Created attachment 47375
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47375&action=edit
compile at -O2

This was originally reported at
https://sourceware.org/bugzilla/show_bug.cgi?id=24924 but it turns out the
issue is a gcc issue and a glibc issue.

The UNSPECV_ATOMIC_CMPSW:
(insn 177 176 1270 17 (parallel [
            (set (reg:CC 66 cc)
                (unspec_volatile:CC [
                        (const_int 0 [0])
                    ] UNSPECV_ATOMIC_CMPSW))
            (set (reg:SI 8 x8 [251])
                (mem/v:SI (reg/f:DI 16 x16 [orig:346 _41 ] [346]) [-1  S4
A32]))
            (set (mem/v:SI (reg/f:DI 16 x16 [orig:346 _41 ] [346]) [-1  S4
A32])
                (unspec_volatile:SI [
                        (reg:SI 1 x1 [orig:117 _42 ] [117])
                        (reg:SI 5 x5 [249])
                        (const_int 1 [0x1])
                        (const_int 2 [0x2])
                        (const_int 0 [0])
                    ] UNSPECV_ATOMIC_CMPSW))
            (clobber (reg:SI 19 x19 [363]))
        ]) "pthread_rwlock_common.c":687:135 3712 {aarch64_compare_and_swapsi}
     (nil))

Is split (after register allocator/reload) into:
(insn 1580 176 1581 17 (set (reg:SI 8 x8 [251])
        (unspec_volatile:SI [
                (mem/v:SI (reg/f:DI 16 x16 [orig:346 _41 ] [346]) [-1  S4 A32])
                (const_int 2 [0x2])
            ] UNSPECV_LX)) "pthread_rwlock_common.c":687:135 3842
{aarch64_load_exclusivesi}
     (nil))
(insn 1581 1580 1582 17 (set (reg:CC 66 cc)
        (compare:CC (reg:SI 8 x8 [251])
            (reg:SI 1 x1 [orig:117 _42 ] [117])))
"pthread_rwlock_common.c":687:135 447 {cmpsi}
     (nil))
(jump_insn 1582 1581 1616 17 (set (pc)
        (if_then_else (ne (reg:CC 66 cc)
                (const_int 0 [0]))
            (label_ref:DI 1585)
            (pc))) "pthread_rwlock_common.c":687:135 9 {condjump}
     (int_list:REG_BR_PROB 536868 (nil))
 -> 1585)
...
(insn 1583 1616 1584 99 (parallel [
            (set (reg:SI 19 x19 [363])
                (unspec_volatile:SI [
                        (const_int 0 [0])
                    ] UNSPECV_SX))
            (set (mem/v:SI (reg/f:DI 16 x16 [orig:346 _41 ] [346]) [-1  S4
A32])
                (unspec_volatile:SI [
                        (reg:SI 5 x5 [249])
                        (const_int 2 [0x2])
                    ] UNSPECV_SX))
        ]) "pthread_rwlock_common.c":687:135 3847 {aarch64_store_exclusivesi}
     (nil))
(insn 1584 1583 1585 99 (set (reg:CC 66 cc)
        (compare:CC (reg:SI 19 x19 [363])
            (const_int 0 [0]))) "pthread_rwlock_common.c":687:135 447 {cmpsi}
     (nil))

Which is ok, but notice the register x19.  It is a callee saved register but it
is only used in the UNSPECV_SX/compare.
After .pro_and_epilogue:
We get for the UNSPECV_SX/compare:
(insn/f 1659 1616 1583 25 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 16 [0x10])) [38  S8 A8])
        (reg:DI 19 x19)) -1
     (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                    (const_int 16 [0x10])) [38  S8 A8])
            (reg:DI 19 x19))
        (nil)))
(insn 1583 1659 1584 25 (parallel [
            (set (reg:SI 19 x19 [363])
                (unspec_volatile:SI [
                        (const_int 0 [0])
                    ] UNSPECV_SX))
            (set (mem/v:SI (reg/f:DI 16 x16 [orig:346 _41 ] [346]) [-1  S4
A32])
                (unspec_volatile:SI [
                        (reg:SI 5 x5 [249])
                        (const_int 2 [0x2])
                    ] UNSPECV_SX))
        ]) "pthread_rwlock_common.c":687:135 3847 {aarch64_store_exclusivesi}
     (nil))
(insn 1584 1583 1661 25 (set (reg:CC 66 cc)
        (compare:CC (reg:SI 19 x19 [363])
            (const_int 0 [0]))) "pthread_rwlock_common.c":687:135 447 {cmpsi}
     (nil))
(insn/f 1661 1584 1585 25 (set (reg:DI 19 x19)
        (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 16 [0x10])) [38  S8 A8]))
"pthread_rwlock_common.c":687:135 -1
     (expr_list:REG_CFA_RESTORE (reg:DI 19 x19)
        (nil)))

---- CUT ---
This causes UNSPECV_SX to always fail on a few AARCH64 targets
(ThunderX1/OcteonTX1 and OcteonTX2).

Reply via email to