VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins
authorMaciej W. Rozycki <macro@linux-mips.org>
Sat, 5 Dec 2020 18:26:25 +0000 (18:26 +0000)
committerMaciej W. Rozycki <macro@linux-mips.org>
Sat, 5 Dec 2020 18:26:25 +0000 (18:26 +0000)
commitfbe575958c2ec322ac1703a14737a95e6036c4e0
tree09e1db69fa321172ff984bc6c86a6173d292b770
parent2500add25bd3258a66cc7ae199ab7eae53cc3202
VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins

Remove an ICE like:

during RTL pass: expand
.../libatomic/tas_n.c: In function 'libat_test_and_set_1':
.../libatomic/tas_n.c:39:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1298
   39 | }
      | ^
0x108a09ff patch_jump_insn
.../gcc/cfgrtl.c:1298
0x108a0b07 redirect_branch_edge
.../gcc/cfgrtl.c:1325
0x108a124b rtl_redirect_edge_and_branch
.../gcc/cfgrtl.c:1458
0x1087f6d3 redirect_edge_and_branch(edge_def*, basic_block_def*)
.../gcc/cfghooks.c:373
0x11d6264b try_forward_edges
.../gcc/cfgcleanup.c:562
0x11d6b0eb try_optimize_cfg
.../gcc/cfgcleanup.c:2960
0x11d6ba4f cleanup_cfg(int)
.../gcc/cfgcleanup.c:3174
0x10870b3f execute
.../gcc/cfgexpand.c:6763

triggered with an RTL pattern like:

(jump_insn 8 7 20 2 (parallel [
            (set (pc)
                (if_then_else (ne (zero_extract:SI (mem/v:QI (mem/f/c:SI (reg/f:SI 16 virtual-incoming-args) [1 mptr+0 S4 A32]) [-1  S1 A8])
                            (const_int 1 [0x1])
                            (const_int 0 [0]))
                        (const_int 0 [0]))
                    (label_ref 10)
                    (pc)))
            (set (zero_extract:SI (mem/v:QI (mem/f/c:SI (reg/f:SI 16 virtual-incoming-args) [1 mptr+0 S4 A32]) [-1  S1 A8])
                    (const_int 1 [0x1])
                    (const_int 0 [0]))
                (const_int 1 [0x1]))
        ]) ".../libatomic/tas_n.c":38:12 -1
     (nil)
 -> 10)

caused by a volatile memory reference used that is not accepted by the
`memory_operand' predicate of the `jbbssiqi' insn explicitly referred
from the `sync_lock_test_and_setqi' expander.  Also seen with:

FAIL: gcc.dg/pr61756.c (internal compiler error)

Define a new `any_memory_operand' predicate accepting both ordinary and
volatile memory references and use it with the `jbb<ccss>i<mode>' insn,
so as to address the ICE.

Also remove useless operations from the `sync_lock_test_and_set<mode>'
and `sync_lock_release<mode>' expanders as those always either complete
or fail and therefore never fall through to using their template other
than to match operands.  Wrap `jbb<ccss>i<mode>' into `unspec_volatile'
instead so that the jump does not get removed or reordered.  Share one
index to avoid a complication around the iterators since the index is
nowhere referred to anyway and the pattern required pulled by its name.

Test cases will be added separately.

gcc/
* config/vax/predicates.md (volatile_mem_operand)
(any_memory_operand): New predicates.
* config/vax/builtins.md (VUNSPEC_UNLOCK): Remove constant.
(sync_lock_test_and_set<mode>): Remove `set' and `unspec'
operations, match operands only.  Reformat.
(sync_lock_release<mode>): Likewise.  Remove cruft.
(jbb<ccss>i<mode>): Wrap into `unspec_volatile', use
`any_memory_operand' predicate.
gcc/config/vax/builtins.md
gcc/config/vax/predicates.md