On S/390 there is a need to support more than 32 instruction alternatives per define_insn. Currently this is not explicitly prohibited or unsupported: MAX_RECOG_ALTERNATIVES is equal 35, and, futhermore, the related code uses uint64_t for bitmaps in most places.
However, genattrtab contains the logic to convert (eq_attr "attribute" "value") RTXs to (eq_attr_alt bitmap) RTXs, where bitmap contains alternatives, whose "attribute" has the corresponding "value". Unfortunately, bitmap is only 32 bits.
When adding the 33rd alternative, this led to (eq_attr "type" "larl") becoming (eq_attr_alt -1050625 1), where -1050625 == 0xffeff7ff. The cleared bits 12, 21 and 32 correspond to two existing and one newly added insn of type "larl". compute_alternative_mask sign extended this to 0xffffffffffeff7ff, which contained non-existent alternatives, and this made simplify_test_exp fail with "invalid alternative specified".
I'm not sure why it didn't fail the same way before, since the top bit, which led to sign extension, should have been set even with 32 alternatives. Maybe simplify_test_exp was not called for "type" attribute for some reason?
This patch widens EQ_ATTR_ALT bitmap to 64 bits, making it possible to gracefully handle up to 64 alternatives. It eliminates the problem with the 33rd alternative on S/390.
2018-09-24 Ilya Leoshkevich
- genattrtab.c (mk_attr_alt): Use alternative_mask. (attr_rtx_1): Adjust caching to match the new EQ_ATTR_ALT field types. (check_attr_test): Use alternative_mask. (get_attr_value): Likewise. (compute_alternative_mask): Use alternative_mask and XWINT. (make_alternative_compare): Use alternative_mask. (attr_alt_subset_p): Use XWINT. (attr_alt_subset_of_compl_p): Likewise. (attr_alt_intersection): Use alternative_mask and XWINT. (attr_alt_union): Likewise. (attr_alt_complement): Use HOST_WIDE_INT and XWINT. (mk_attr_alt): Use alternative_mask and HOST_WIDE_INT. (simplify_test_exp): Use alternative_mask and XWINT. (write_test_expr): Use alternative_mask and XWINT, adjust bit number calculation to support 64 bits. Generate code that checks 64-bit masks. (main): Use alternative_mask.
- rtl.def (EQ_ATTR_ALT): Change field types from ii to ww.
41023d5ef1b Change EQ_ATTR_ALT to support up to 64 alternatives
gcc/ChangeLog | 22 ++++++++++
gcc/genattrtab.c | 132 ++++++++++++++++++++++++++++++-------------------------
gcc/recog.h | 2 +-
gcc/rtl.def | 2 +-
4 files changed, 96 insertions(+), 62 deletions(-)