[Bug target/96176] Failure to omit extraneous movzx in atomic compare exchange with unsigned char

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Jul 13 10:48:05 GMT 2020


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The zero extension is initially there because the builtin has the arguments
promoted.  Normally combine would fix this up:
(insn 10 7 11 2 (set (reg:SI 88 [ new_val ])
        (zero_extend:SI (subreg:QI (reg:SI 93) 0))) "pr96176.c":3:5 143
{*zero_extendqisi2}
     (expr_list:REG_DEAD (reg:SI 93)
        (nil)))
(insn 11 10 0 2 (parallel [
            (set (reg:QI 89)
                (unspec_volatile:QI [
                        (mem/v:QI (reg/v/f:DI 83 [ addr ]) [-1  S1 A8])
                        (reg/v:QI 84 [ old_val ])
                        (subreg:QI (reg:SI 88 [ new_val ]) 0)
                        (const_int 0 [0])
                    ] UNSPECV_CMPXCHG))
            (set (mem/v:QI (reg/v/f:DI 83 [ addr ]) [-1  S1 A8])
                (unspec_volatile:QI [
                        (const_int 0 [0])
                    ] UNSPECV_CMPXCHG))
            (set (reg:CCZ 17 flags)
                (unspec_volatile:CCZ [
                        (const_int 0 [0])
                    ] UNSPECV_CMPXCHG))
        ]) "pr96176.c":3:5 6114 {atomic_compare_and_swapqi_1}
     (expr_list:REG_DEAD (reg:SI 88 [ new_val ])
        (expr_list:REG_DEAD (reg/v:QI 84 [ old_val ])
            (expr_list:REG_DEAD (reg/v/f:DI 83 [ addr ])
                (expr_list:REG_UNUSED (reg:QI 89)
                    (expr_list:REG_UNUSED (reg:CCZ 17 flags)
                        (nil)))))))

but it fails:
Trying 10 -> 11:
   10: r88:SI=zero_extend(r93:SI#0)
      REG_DEAD r93:SI
   11: {r89:QI=unspec/v[[r83:DI],r84:QI,r88:SI#0,0] 90;[r83:DI]=unspec/v[0]
90;flags:CCZ=unspec/v[0] 90;}
      REG_DEAD r88:SI
      REG_DEAD r84:QI
      REG_DEAD r83:DI
      REG_UNUSED r89:QI
      REG_UNUSED flags:CCZ
Failed to match this instruction:
(parallel [
        (set (reg:QI 89)
            (unspec_volatile:QI [
                    (mem/v:QI (reg/v/f:DI 83 [ addr ]) [-1  S1 A8])
                    (reg/v:QI 84 [ old_val ])
                    (subreg:QI (reg:SI 93) 0)
                    (const_int 0 [0])
                ] UNSPECV_CMPXCHG))
        (set (mem/v:QI (reg/v/f:DI 83 [ addr ]) [-1  S1 A8])
            (unspec_volatile:QI [
                    (const_int 0 [0])
                ] UNSPECV_CMPXCHG))
        (set (reg:CCZ 17 flags)
            (unspec_volatile:CCZ [
                    (const_int 0 [0])
                ] UNSPECV_CMPXCHG))
    ])
due to the MEM_VOLATILE_P and volatile_ok not being true during combine.
But we can do something about it during expansion.


More information about the Gcc-bugs mailing list