VAX: Fix ill-formed `jbb<ccss>i<mode>' insn operands
authorMaciej W. Rozycki <macro@orcam.me.uk>
Wed, 21 Apr 2021 21:33:11 +0000 (23:33 +0200)
committerMaciej W. Rozycki <macro@orcam.me.uk>
Tue, 27 Apr 2021 18:02:06 +0000 (20:02 +0200)
The insn has extraneous operand #3 that is aliased in RTL to operand #0
with a constraint.  The operands specify a single-bit field in memory
that the machine instruction produced boths reads for the purpose of
determining whether to branch or not and either clears or sets according
to the machine operation selected with the `ccss' iterator.  The caller
of the insn is supposed to supply the same rtx for both operands.

This odd arrangement happens to work with old reload, but breaks with
libatomic if LRA is used instead:

.../libatomic/flag.c: In function 'atomic_flag_test_and_set':
.../libatomic/flag.c:36:1: error: unable to generate reloads for:
   36 | }
      | ^
(jump_insn 7 6 19 2 (unspec_volatile [
            (set (pc)
                (if_then_else (eq (zero_extract:SI (mem/v:QI (reg:SI 27) [-1  S1 A8])
                            (const_int 1 [0x1])
                            (const_int 0 [0]))
                        (const_int 1 [0x1]))
                    (label_ref:SI 25)
                    (pc)))
            (set (zero_extract:SI (mem/v:QI (reg:SI 28) [-1  S1 A8])
                    (const_int 1 [0x1])
                    (const_int 0 [0]))
                (const_int 1 [0x1]))
        ] 100) ".../libatomic/flag.c":35:10 669 {jbbssiqi}
     (nil)
 -> 25)
during RTL pass: reload
.../libatomic/flag.c:36:1: internal compiler error: in curr_insn_transform, at lra-constraints.c:4098
0x1112c587 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
.../gcc/rtl-error.c:108
0x10ee6563 curr_insn_transform
.../gcc/lra-constraints.c:4098
0x10eeaf87 lra_constraints(bool)
.../gcc/lra-constraints.c:5133
0x10ec97e3 lra(_IO_FILE*)
.../gcc/lra.c:2336
0x10e4633f do_reload
.../gcc/ira.c:5827
0x10e46b27 execute
.../gcc/ira.c:6013
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.

Switch to using `match_dup' as expected then for a machine instruction
that in its encoding only has one actual operand in for the single-bit
field.

gcc/
* config/vax/builtins.md (jbb<ccss>i<mode>): Remove operand #3.
(sync_lock_test_and_set<mode>): Adjust accordingly.
(sync_lock_release<mode>): Likewise.

gcc/config/vax/builtins.md

index 3d1cbcd..ff97ff3 100644 (file)
 
   label = gen_label_rtx ();
   emit_move_insn (operands[0], const1_rtx);
-  emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label,
-                                   operands[1]));
+  emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label));
   emit_move_insn (operands[0], const0_rtx);
   emit_label (label);
   DONE;
     FAIL;
 
   label = gen_label_rtx ();
-  emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label,
-                                   operands[0]));
+  emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label));
   emit_label (label);
   DONE;
 }")
     [(set (pc)
          (if_then_else
            (eq (zero_extract:SI
-                 (match_operand:VAXint 0 "any_memory_operand" "<bb_mem>")
+                 (match_operand:VAXint 0 "any_memory_operand" "+<bb_mem>")
                  (const_int 1)
                  (match_operand:SI 1 "general_operand" "nrmT"))
                (const_int bit))
            (label_ref (match_operand 2 "" ""))
            (pc)))
-     (set (zero_extract:SI (match_operand:VAXint 3 "any_memory_operand" "+0")
+     (set (zero_extract:SI (match_dup 0)
                           (const_int 1)
                           (match_dup 1))
          (const_int bit))]