From c5fd8a9157c440c2039e7c7015f012800d1e524d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 5 Dec 2020 00:16:39 +0000 Subject: Daily bump. --- gcc/ChangeLog | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 39 +++++++++++++++++++++++ gcc/testsuite/ChangeLog | 58 ++++++++++++++++++++++++++++++++++ 4 files changed, 181 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44dadd3..853d3b2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,86 @@ +2020-12-04 Jason Merrill + + * vec.h (begin, end): Add overloads for vec*. + * tree.c (build_constructor_from_vec): Remove *. + +2020-12-04 David Edelsohn + + * config/rs6000/rs6000.c (rs6000_option_override_internal): + Change PTR_SIZE to POINTER_SIZE_UNITS. + +2020-12-04 Hans-Peter Nilsson + Martin Sebor + + PR middle-end/94600 + * doc/implement-c.texi (Qualifiers implementation): Add blurb + about access to the whole of a volatile aggregate object, only for + same-size as a scalar object. + +2020-12-04 Jakub Jelinek + + PR c++/98130 + * gimple.c (gimple_call_fnspec): Only return ".co " for replaceable + operator delete or ".mC" for replaceable operator new called from + new/delete. + +2020-12-04 Jakub Jelinek + + PR target/96226 + * config/i386/i386.md (splitter after *3_mask, + splitter after *3_mask_1): New combine splitters. + +2020-12-04 Jakub Jelinek + + PR libstdc++/93121 + * fold-const.c (native_encode_initializer): Use build_zero_cst + instead of build_constructor. + +2020-12-04 Jakub Jelinek + + PR target/98100 + * cfgexpand.c (expand_gimple_basic_block): For vars with + vector type, use TYPE_MODE rather than DECL_MODE. + +2020-12-04 Jakub Jelinek + + * common.opt (-gdwarf32, -gdwarf64): New options. + * config/rs6000/rs6000.c (rs6000_option_override_internal): Default + dwarf_offset_size to 8 if not overridden from the command line. + * dwarf2out.c: Change all occurrences of DWARF_OFFSET_SIZE to + dwarf_offset_size. + * doc/invoke.texi (-gdwarf32, -gdwarf64): Document. + +2020-12-04 Martin Liska + + * doc/tm.texi: Change argument of the record_gcc_switches + hook and remove SWITCH_TYPE_* enum values. + * dwarf2out.c (gen_producer_string): Move to opts.c and remove + handling of the dwarf_record_gcc_switches option. + (dwarf2out_early_finish): Use moved gen_producer_string + function. + * opts.c (gen_producer_string): New. + * opts.h (gen_producer_string): New. + * target.def: Change type of record_gcc_switches. + * target.h (enum print_switch_type): Remove. + (elf_record_gcc_switches): Change first argument. + * toplev.c (MAX_LINE): Remove. + (print_to_asm_out_file): Likewise. + (print_to_stderr): Likewise. + (print_single_switch): Likewise. + (print_switch_values): Likewise. + (init_asm_output): Use new gen_producer_string function. + (process_options): Likewise. + * varasm.c (elf_record_gcc_switches): Just save the string argument + to the ELF container. + +2020-12-04 Eric Botcazou + + * ipa-sra.c (verify_access_tree_1): Relax assertion on the size. + +2020-12-04 Martin Liska + + * doc/invoke.texi: Add missing params. + 2020-12-03 Martin Sebor PR c++/90629 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3fac2aa..e4face1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20201204 +20201205 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1bf50cd..6d5caf0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,42 @@ +2020-12-04 Jason Merrill + + PR c++/93083 + * pt.c (convert_template_argument): Handle equivalent placeholders. + (do_class_deduction): Look through EXPR_PACK_EXPANSION, too. + +2020-12-04 Jason Merrill + + * decl2.c (clear_consteval_vfns): Remove *. + * pt.c (do_auto_deduction): Remove *. + * parser.c (cp_parser_late_parsing_default_args): Change loop + to use range 'for'. + +2020-12-04 Nathan Sidwell + + PR c++/98116 + * cp-tree.h (comparing_typenames): Delete. + (cplus_build_array_type): Remove default parm. + * pt.c (comparing_typenames): Delete. + (spec_hasher::equal): Don't increment it. + * tree.c (set_array_type_canon): Remove dep parm. + (build_cplus_array_type): Remove dep parm changes. + (cp_build_qualified_type_real): Remove dependent array type + changes. + (strip_typedefs): Likewise. + * typeck.c (structural_comptypes): Revert comparing_typename + changes. + +2020-12-04 Nathan Sidwell + + * cp-tree.h: Add various inline module state predicates, and + declare the API that will be provided by modules.cc + +2020-12-04 Jakub Jelinek + + PR c++/80780 + * cp-gimplify.c (fold_builtin_source_location): Use 2 instead of 0 + as last argument to cxx_printable_name. + 2020-12-03 Jason Merrill * cp-tree.h (releasing_vec::operator[]): Change parameter type to diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e91a06..b5f39ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,61 @@ +2020-12-04 Jason Merrill + + PR c++/93083 + * g++.dg/cpp2a/nontype-class40.C: New test. + +2020-12-04 Jakub Jelinek + + PR c++/98130 + * g++.dg/opt/pr98130.C: New test. + +2020-12-04 Jakub Jelinek + + PR target/96226 + * gcc.target/i386/pr96226.c: New test. + +2020-12-04 Jakub Jelinek + + PR libstdc++/93121 + * g++.dg/cpp2a/bit-cast6.C: New test. + +2020-12-04 Nathan Sidwell + + PR c++/98116 + * g++.dg/template/pr98116.C: Enable robust checking. + +2020-12-04 Jakub Jelinek + + PR target/98100 + * gcc.target/i386/pr98100.c: New test. + +2020-12-04 Martin Liska + + PR testsuite/98123 + * gcc.dg/tree-ssa/if-to-switch-4.c: Add param to make the test + stable on all architectures. + * gcc.dg/tree-ssa/if-to-switch-6.c: Likewise. + * gcc.dg/tree-ssa/if-to-switch-8.c: Likewise. + +2020-12-04 Eric Botcazou + + * gcc.dg/pr98099.c: Compile only for dfp targets. + +2020-12-04 Eric Botcazou + + * gnat.dg/opt91.ads, gnat.dg/opt91.adb: New test. + * gnat.dg/opt91_pkg.ads, gnat.dg/opt91_pkg.adb: New helper. + +2020-12-04 Jakub Jelinek + + PR c++/80780 + * g++.dg/cpp2a/srcloc1.C (quux): Use __PRETTY_FUNCTION__ instead of + function. + * g++.dg/cpp2a/srcloc2.C (quux): Likewise. + * g++.dg/cpp2a/srcloc15.C (S::S): Likewise. + (bar): Likewise. Adjust expected column. + * g++.dg/cpp2a/srcloc17.C (S::S): Likewise. + (bar): Likewise. Adjust expected column. + 2020-12-03 Jason Merrill * g++.dg/cpp2a/concepts-nodiscard1.C: XFAIL. -- cgit v1.1 From 43e84ce7d62be121445e17cc0ee009a81fb285d7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 5 Dec 2020 01:30:08 +0100 Subject: c++: Fix constexpr access to union member through pointer-to-member [PR98122] We currently incorrectly reject the first testcase, because cxx_fold_indirect_ref_1 doesn't attempt to handle UNION_TYPEs. As the second testcase shows, it isn't that easy, because I believe we need to take into account the active member and prefer that active member over other members, because if we pick a non-active one, we might reject valid programs. 2020-12-05 Jakub Jelinek PR c++/98122 * constexpr.c (cxx_union_active_member): New function. (cxx_fold_indirect_ref_1): Add ctx argument, pass it through to recursive call. Handle UNION_TYPE. (cxx_fold_indirect_ref): Add ctx argument, pass it to recursive calls and cxx_fold_indirect_ref_1. (cxx_eval_indirect_ref): Adjust cxx_fold_indirect_ref calls. * g++.dg/cpp1y/constexpr-98122.C: New test. * g++.dg/cpp2a/constexpr-98122.C: New test. --- gcc/cp/constexpr.c | 64 ++++++++++++++++++++++------ gcc/testsuite/g++.dg/cpp1y/constexpr-98122.C | 14 ++++++ gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C | 25 +++++++++++ 3 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-98122.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C (limited to 'gcc') diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index e0d3580..cb477c84 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4611,11 +4611,32 @@ same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2) return same_type_ignoring_top_level_qualifiers_p (type1, type2); } +/* Try to determine the currently active union member for an expression + with UNION_TYPE. If it can be determined, return the FIELD_DECL, + otherwise return NULL_TREE. */ + +static tree +cxx_union_active_member (const constexpr_ctx *ctx, tree t) +{ + constexpr_ctx new_ctx = *ctx; + new_ctx.quiet = true; + bool non_constant_p = false, overflow_p = false; + tree ctor = cxx_eval_constant_expression (&new_ctx, t, false, + &non_constant_p, + &overflow_p); + if (TREE_CODE (ctor) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (ctor) == 1 + && CONSTRUCTOR_ELT (ctor, 0)->index + && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL) + return CONSTRUCTOR_ELT (ctor, 0)->index; + return NULL_TREE; +} + /* Helper function for cxx_fold_indirect_ref_1, called recursively. */ static tree -cxx_fold_indirect_ref_1 (location_t loc, tree type, tree op, - unsigned HOST_WIDE_INT off, bool *empty_base) +cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, + tree op, unsigned HOST_WIDE_INT off, bool *empty_base) { tree optype = TREE_TYPE (op); unsigned HOST_WIDE_INT const_nunits; @@ -4674,13 +4695,29 @@ cxx_fold_indirect_ref_1 (location_t loc, tree type, tree op, tree index = size_int (idx + tree_to_uhwi (min_val)); op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index, NULL_TREE, NULL_TREE); - return cxx_fold_indirect_ref_1 (loc, type, op, rem, + return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem, empty_base); } } /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */ - else if (TREE_CODE (optype) == RECORD_TYPE) + else if (TREE_CODE (optype) == RECORD_TYPE + || TREE_CODE (optype) == UNION_TYPE) { + if (TREE_CODE (optype) == UNION_TYPE) + /* For unions prefer the currently active member. */ + if (tree field = cxx_union_active_member (ctx, op)) + { + unsigned HOST_WIDE_INT el_sz + = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); + if (off < el_sz) + { + tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), + op, field, NULL_TREE); + if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop, + off, empty_base)) + return ret; + } + } for (tree field = TYPE_FIELDS (optype); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL @@ -4691,13 +4728,13 @@ cxx_fold_indirect_ref_1 (location_t loc, tree type, tree op, if (!tree_fits_uhwi_p (pos)) continue; unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos); - unsigned el_sz + unsigned HOST_WIDE_INT el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); if (upos <= off && off < upos + el_sz) { tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field, NULL_TREE); - if (tree ret = cxx_fold_indirect_ref_1 (loc, type, cop, + if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop, off - upos, empty_base)) return ret; @@ -4718,7 +4755,8 @@ cxx_fold_indirect_ref_1 (location_t loc, tree type, tree op, with TBAA in fold_indirect_ref_1. */ static tree -cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) +cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, + tree op0, bool *empty_base) { tree sub = op0; tree subtype; @@ -4756,7 +4794,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) return op; } else - return cxx_fold_indirect_ref_1 (loc, type, op, 0, empty_base); + return cxx_fold_indirect_ref_1 (ctx, loc, type, op, 0, empty_base); } else if (TREE_CODE (sub) == POINTER_PLUS_EXPR && tree_fits_uhwi_p (TREE_OPERAND (sub, 1))) @@ -4766,7 +4804,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) STRIP_NOPS (op00); if (TREE_CODE (op00) == ADDR_EXPR) - return cxx_fold_indirect_ref_1 (loc, type, TREE_OPERAND (op00, 0), + return cxx_fold_indirect_ref_1 (ctx, loc, type, TREE_OPERAND (op00, 0), tree_to_uhwi (op01), empty_base); } /* *(foo *)fooarrptr => (*fooarrptr)[0] */ @@ -4776,7 +4814,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) tree type_domain; tree min_val = size_zero_node; tree newsub - = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); + = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL); if (newsub) sub = newsub; else @@ -4811,8 +4849,8 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, } /* First try to simplify it directly. */ - tree r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), orig_op0, - &empty_base); + tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), + orig_op0, &empty_base); if (!r) { /* If that didn't work, evaluate the operand first. */ @@ -4831,7 +4869,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, return t; } - r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0, + r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0, &empty_base); if (r == NULL_TREE) { diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-98122.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-98122.C new file mode 100644 index 0000000..86b8aa9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-98122.C @@ -0,0 +1,14 @@ +// PR c++/98122 +// { dg-do compile { target c++14 } } + +union U { int a; }; + +constexpr bool +foo () +{ + U f { 42 }; + constexpr auto m = &U::a; + return (f.*m) == 42; +} + +static_assert (foo (), ""); diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C new file mode 100644 index 0000000..01bdfa5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C @@ -0,0 +1,25 @@ +// PR c++/98122 +// { dg-do compile { target c++20 } } + +union V { int a; char b; }; +union W { int a; int b; }; + +constexpr bool +bar () +{ + V f { .b = 42 }; + constexpr auto m = &V::a; + return (f.*m) == 42; +} + +constexpr bool +baz () +{ + W f { .b = 42 }; + constexpr auto m = &W::b; + return (f.*m) == 42; +} + +static_assert (bar (), ""); // { dg-error "non-constant condition for static assertion" } + // { dg-error "accessing 'V::a' member instead of initialized 'V::b' member in constant expression" "" { target *-*-* } .-1 } +static_assert (baz (), ""); -- cgit v1.1 From 625e002396f7d0108f845bfba6a6f4f4fcadad05 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 5 Dec 2020 01:31:08 +0100 Subject: i386: Combine splitters followup [PR96226] Here is the patch to simplify the newly added combine splitters, when we split into 2 insns anyway, no reason to split into the masking define_insn_and_split we'd be splitting shortly after. 2020-12-05 Jakub Jelinek PR target/96226 * config/i386/i386.md (splitter after *3_mask, splitter after *3_mask_1): Drop the masking from the patterns to split into. --- gcc/config/i386/i386.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 129d47b..0b28895 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11988,8 +11988,7 @@ [(set (match_dup 4) (match_dup 1)) (set (match_dup 0) (any_rotate:SWI48 (match_dup 4) - (subreg:QI - (and:SI (match_dup 2) (match_dup 3)) 0)))] + (subreg:QI (match_dup 2) 0)))] "operands[4] = gen_reg_rtx (mode);") (define_insn_and_split "*3_mask_1" @@ -12023,8 +12022,7 @@ == GET_MODE_BITSIZE (mode) - 1" [(set (match_dup 4) (match_dup 1)) (set (match_dup 0) - (any_rotate:SWI48 (match_dup 4) - (and:QI (match_dup 2) (match_dup 3))))] + (any_rotate:SWI48 (match_dup 4) (match_dup 2)))] "operands[4] = gen_reg_rtx (mode);") ;; Implement rotation using two double-precision -- cgit v1.1 From 3e2ae3ee285a57455d5a23bd352a68c289130186 Mon Sep 17 00:00:00 2001 From: Venkataramanan Kumar Date: Sat, 5 Dec 2020 11:12:15 +0530 Subject: X86_64: Enable support for next generation AMD Zen3 CPU. 2020-12-03 Venkataramanan Kumar Sharavan Kumar gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_amd_cpu) recognize znver3. * common/config/i386/i386-common.c (processor_names): Add znver3. (processor_alias_table): Add znver3 and AMDFAM19H entry. * common/config/i386/i386-cpuinfo.h (processor_types): Add AMDFAM19H. (processor_subtypes): AMDFAM19H_ZNVER3. * config.gcc (i[34567]86-*-linux* | ...): Likewise. * config/i386/driver-i386.c: (host_detect_local_cpu): Let -march=native recognize znver3 processors. * config/i386/i386-c.c (ix86_target_macros_internal): Add znver3. * config/i386/i386-options.c (m_znver3): New definition. (m_ZNVER): Include m_znver3. (processor_cost_table): Add znver3. * config/i386/i386.c (ix86_reassociation_width): Likewise. * config/i386/i386.h (TARGET_znver3): New definition. (enum processor_type): Add PROCESSOR_ZNVER3. * config/i386/i386.md (define_attr "cpu"): Add znver3. * config/i386/x86-tune-sched.c: (ix86_issue_rate): Likewise. (ix86_adjust_cost): Likewise. * config/i386/x86-tune.def (X86_TUNE_AVOID_256FMA_CHAINS: Likewise. * config/i386/znver1.md: Add new reservations for znver3. * doc/extend.texi: Add details about znver3. * doc/invoke.texi: Likewise. gcc/testsuite/ChangeLog: * gcc.target/i386/funcspec-56.inc: Handle new march. * g++.target/i386/mv29.C: New file. --- gcc/common/config/i386/cpuinfo.h | 17 ++ gcc/common/config/i386/i386-common.c | 16 +- gcc/common/config/i386/i386-cpuinfo.h | 2 + gcc/config.gcc | 10 +- gcc/config/i386/driver-i386.c | 5 + gcc/config/i386/i386-c.c | 7 + gcc/config/i386/i386-options.c | 4 +- gcc/config/i386/i386.c | 5 +- gcc/config/i386/i386.h | 2 + gcc/config/i386/i386.md | 2 +- gcc/config/i386/x86-tune-sched.c | 2 + gcc/config/i386/x86-tune.def | 2 +- gcc/config/i386/znver1.md | 353 +++++++++++++++++--------- gcc/doc/extend.texi | 6 + gcc/doc/invoke.texi | 7 + gcc/testsuite/g++.target/i386/mv29.C | 79 ++++++ gcc/testsuite/gcc.target/i386/funcspec-56.inc | 6 + 17 files changed, 397 insertions(+), 128 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/mv29.C (limited to 'gcc') diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 41728a2..4f1ab63 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -241,6 +241,23 @@ get_amd_cpu (struct __processor_model *cpu_model, cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1; } break; + case 0x19: + cpu_model->__cpu_type = AMDFAM19H; + /* AMD family 19h version 1. */ + if (model <= 0x0f) + { + cpu = "znver3"; + CHECK___builtin_cpu_is ("znver3"); + cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3; + } + else if (has_cpu_feature (cpu_model, cpu_features2, + FEATURE_VAES)) + { + cpu = "znver3"; + CHECK___builtin_cpu_is ("znver3"); + cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3; + } + break; default: break; } diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index 8f809c1..2a1d31f 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -1762,7 +1762,8 @@ const char *const processor_names[] = "btver1", "btver2", "znver1", - "znver2" + "znver2", + "znver3" }; /* Guarantee that the array is aligned with enum processor_type. */ @@ -2004,6 +2005,17 @@ const pta processor_alias_table[] = | PTA_SHA | PTA_LZCNT | PTA_POPCNT | PTA_CLWB | PTA_RDPID | PTA_WBNOINVD, M_CPU_SUBTYPE (AMDFAM17H_ZNVER2), P_PROC_AVX2}, + {"znver3", PROCESSOR_ZNVER3, CPU_ZNVER3, + PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 + | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 + | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2 + | PTA_BMI | PTA_BMI2 | PTA_F16C | PTA_FMA | PTA_PRFCHW + | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE + | PTA_RDRND | PTA_MOVBE | PTA_MWAITX | PTA_ADX | PTA_RDSEED + | PTA_CLZERO | PTA_CLFLUSHOPT | PTA_XSAVEC | PTA_XSAVES + | PTA_SHA | PTA_LZCNT | PTA_POPCNT | PTA_CLWB | PTA_RDPID + | PTA_WBNOINVD | PTA_VAES | PTA_VPCLMULQDQ | PTA_PKU, + M_CPU_SUBTYPE (AMDFAM19H_ZNVER3), P_PROC_AVX2}, {"btver1", PROCESSOR_BTVER1, CPU_GENERIC, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A | PTA_ABM | PTA_CX16 | PTA_PRFCHW @@ -2030,6 +2042,8 @@ const pta processor_alias_table[] = M_CPU_TYPE (AMDFAM15H), P_NONE}, {"amdfam17h", PROCESSOR_GENERIC, CPU_GENERIC, 0, M_CPU_TYPE (AMDFAM17H), P_NONE}, + {"amdfam19h", PROCESSOR_GENERIC, CPU_GENERIC, 0, + M_CPU_TYPE (AMDFAM19H), P_NONE}, {"shanghai", PROCESSOR_GENERIC, CPU_GENERIC, 0, M_CPU_TYPE (AMDFAM10H_SHANGHAI), P_NONE}, {"istanbul", PROCESSOR_GENERIC, CPU_GENERIC, 0, diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index af02be5..849e95a 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -55,6 +55,7 @@ enum processor_types INTEL_GOLDMONT, INTEL_GOLDMONT_PLUS, INTEL_TREMONT, + AMDFAM19H, CPU_TYPE_MAX, BUILTIN_CPU_TYPE_MAX = CPU_TYPE_MAX }; @@ -86,6 +87,7 @@ enum processor_subtypes INTEL_COREI7_COOPERLAKE, INTEL_COREI7_SAPPHIRERAPIDS, INTEL_COREI7_ALDERLAKE, + AMDFAM19H_ZNVER3, CPU_SUBTYPE_MAX }; diff --git a/gcc/config.gcc b/gcc/config.gcc index 7b138d1..9c76044 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -668,7 +668,7 @@ c7 esther" # 64-bit x86 processors supported by --with-arch=. Each processor # MUST be separated by exactly one space. x86_64_archs="amdfam10 athlon64 athlon64-sse3 barcelona bdver1 bdver2 \ -bdver3 bdver4 znver1 znver2 btver1 btver2 k8 k8-sse3 opteron \ +bdver3 bdver4 znver1 znver2 znver3 btver1 btver2 k8 k8-sse3 opteron \ opteron-sse3 nocona core2 corei7 corei7-avx core-avx-i core-avx2 atom \ slm nehalem westmere sandybridge ivybridge haswell broadwell bonnell \ silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \ @@ -3678,6 +3678,10 @@ case ${target} in arch=znver2 cpu=znver2 ;; + znver3-*) + arch=znver3 + cpu=znver3 + ;; bdver4-*) arch=bdver4 cpu=bdver4 @@ -3799,6 +3803,10 @@ case ${target} in arch=znver2 cpu=znver2 ;; + znver3-*) + arch=znver3 + cpu=znver3 + ;; bdver4-*) arch=bdver4 cpu=bdver4 diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index ecdad57..2bfa037 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -455,6 +455,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) processor = PROCESSOR_GEODE; else if (has_feature (FEATURE_MOVBE) && family == 22) processor = PROCESSOR_BTVER2; + else if (has_feature (FEATURE_VAES)) + processor = PROCESSOR_ZNVER3; else if (has_feature (FEATURE_CLWB)) processor = PROCESSOR_ZNVER2; else if (has_feature (FEATURE_CLZERO)) @@ -753,6 +755,9 @@ const char *host_detect_local_cpu (int argc, const char **argv) case PROCESSOR_ZNVER2: cpu = "znver2"; break; + case PROCESSOR_ZNVER3: + cpu = "znver3"; + break; case PROCESSOR_BTVER1: cpu = "btver1"; break; diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 87b3a2b..6d690e0 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -128,6 +128,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__znver2"); def_or_undef (parse_in, "__znver2__"); break; + case PROCESSOR_ZNVER3: + def_or_undef (parse_in, "__znver3"); + def_or_undef (parse_in, "__znver3__"); + break; case PROCESSOR_BTVER1: def_or_undef (parse_in, "__btver1"); def_or_undef (parse_in, "__btver1__"); @@ -315,6 +319,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, case PROCESSOR_ZNVER2: def_or_undef (parse_in, "__tune_znver2__"); break; + case PROCESSOR_ZNVER3: + def_or_undef (parse_in, "__tune_znver3__"); + break; case PROCESSOR_BTVER1: def_or_undef (parse_in, "__tune_btver1__"); break; diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index dc07697..40714c8 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -147,11 +147,12 @@ along with GCC; see the file COPYING3. If not see #define m_BDVER4 (HOST_WIDE_INT_1U< + +int __attribute__ ((target("default"))) +foo () +{ + return 0; +} + +int __attribute__ ((target("arch=amdfam10"))) foo () { + return 1; +} + +int __attribute__ ((target("arch=btver1"))) foo () { + return 2; +} + +int __attribute__ ((target("arch=btver2"))) foo () { + return 3; +} + +int __attribute__ ((target("arch=bdver1"))) foo () { + return 4; +} + +int __attribute__ ((target("arch=bdver2"))) foo () { + return 5; +} + +int __attribute__ ((target("arch=bdver3"))) foo () { + return 6; +} + +int __attribute__ ((target("arch=znver1"))) foo () { + return 7; +} + +int __attribute__ ((target("arch=znver2"))) foo () { + return 8; +} + +int __attribute__ ((target("arch=znver3"))) foo () { + return 9; +} + + +int main () +{ + int val = foo (); + + if (__builtin_cpu_is ("amdfam10h")) + assert (val == 1); + else if (__builtin_cpu_is ("btver1")) + assert (val == 2); + else if (__builtin_cpu_is ("btver2")) + assert (val == 3); + else if (__builtin_cpu_is ("bdver1")) + assert (val == 4); + else if (__builtin_cpu_is ("bdver2")) + assert (val == 5); + else if (__builtin_cpu_is ("bdver3")) + assert (val == 6); + else if (__builtin_cpu_is ("znver1")) + assert (val == 7); + else if (__builtin_cpu_is ("znver2")) + assert (val == 8); + else if (__builtin_cpu_is ("znver3")) + assert (val == 9); + else + assert (val == 0); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index 395a21c..5d4800f 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -193,6 +193,9 @@ extern void test_arch_barcelona (void) __attribute__((__target__("arch=barcelon extern void test_arch_bdver1 (void) __attribute__((__target__("arch=bdver1"))); extern void test_arch_bdver2 (void) __attribute__((__target__("arch=bdver2"))); extern void test_arch_bdver3 (void) __attribute__((__target__("arch=bdver3"))); +extern void test_arch_znver1 (void) __attribute__((__target__("arch=znver1"))); +extern void test_arch_znver2 (void) __attribute__((__target__("arch=znver2"))); +extern void test_arch_znver3 (void) __attribute__((__target__("arch=znver3"))); extern void test_tune_nocona (void) __attribute__((__target__("tune=nocona"))); extern void test_tune_core2 (void) __attribute__((__target__("tune=core2"))); @@ -212,6 +215,9 @@ extern void test_tune_bdver1 (void) __attribute__((__target__("tune=bdver1"))); extern void test_tune_bdver2 (void) __attribute__((__target__("tune=bdver2"))); extern void test_tune_bdver3 (void) __attribute__((__target__("tune=bdver3"))); extern void test_tune_generic (void) __attribute__((__target__("tune=generic"))); +extern void test_tune_znver1 (void) __attribute__((__target__("tune=znver1"))); +extern void test_tune_znver2 (void) __attribute__((__target__("tune=znver2"))); +extern void test_tune_znver3 (void) __attribute__((__target__("tune=znver3"))); extern void test_fpmath_sse (void) __attribute__((__target__("sse2,fpmath=sse"))); extern void test_fpmath_387 (void) __attribute__((__target__("sse2,fpmath=387"))); -- cgit v1.1 From 1352bc88a0525743c952197fb2db6e4f8c091cde Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Wed, 18 Nov 2020 10:06:03 +0000 Subject: Darwin : Update libtool and dependencies for Darwin20 [PR97865] The change in major version (and the increment from Darwin19 to 20) caused libtool tests to fail which resulted in incorrect build settings for shared libraries. We take this opportunity to sort out the shared undefined symbols state rather than propagating the current unsound behaviour into a new rev. This change means that we default to the case that missing symbols are considered an error, and if one wants to allow this intentionally, the confiuration for that case should be set appropriately. Three existing cases need undefined dynamic lookup: libitm, where there is already a configuration mechanism to add the flags. libcc1, where we add simple configuration to add the flags for Darwin. libsanitizer, where we can add to the existing extra flags. libcc1/ChangeLog: PR target/97865 * Makefile.am: Add dynamic_lookup to LD flags for Darwin. * configure.ac: Test for Darwin host and set a flag. * Makefile.in: Regenerate. * configure: Regenerate. libitm/ChangeLog: PR target/97865 * configure.tgt: Add dynamic_lookup to XLDFLAGS for Darwin. * configure: Regenerate. libsanitizer/ChangeLog: PR target/97865 * configure.tgt: Add dynamic_lookup to EXTRA_CXXFLAGS for Darwin. * configure: Regenerate. ChangeLog: PR target/97865 * libtool.m4: Update handling of Darwin platform link flags for Darwin20. gcc/ChangeLog: PR target/97865 * configure: Regenerate. libatomic/ChangeLog: PR target/97865 * configure: Regenerate. libbacktrace/ChangeLog: PR target/97865 * configure: Regenerate. libffi/ChangeLog: PR target/97865 * configure: Regenerate. libgfortran/ChangeLog: PR target/97865 * configure: Regenerate. libgomp/ChangeLog: PR target/97865 * configure: Regenerate. libhsail-rt/ChangeLog: PR target/97865 * configure: Regenerate. libobjc/ChangeLog: PR target/97865 * configure: Regenerate. libphobos/ChangeLog: PR target/97865 * configure: Regenerate. libquadmath/ChangeLog: PR target/97865 * configure: Regenerate. libssp/ChangeLog: PR target/97865 * configure: Regenerate. libstdc++-v3/ChangeLog: PR target/97865 * configure: Regenerate. libvtv/ChangeLog: PR target/97865 * configure: Regenerate. zlib/ChangeLog: PR target/97865 * configure: Regenerate. --- gcc/configure | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'gcc') diff --git a/gcc/configure b/gcc/configure index 785d656..9a27e45 100755 --- a/gcc/configure +++ b/gcc/configure @@ -15654,23 +15654,25 @@ _LT_EOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) + # Allow for Darwin 4-7 (macOS 10.0-10.3) although these are not expect to + # build without first building modern cctools / linker. + case $host_cpu-$host_os in + *-rhapsody* | *-darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) + *-darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + *-darwin*) + # darwin 5.x (macOS 10.1) onwards we only need to adjust when the + # deployment target is forced to an earlier version. + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in + UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) + ;; 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + *) + ;; + esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then @@ -19184,7 +19186,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19187 "configure" +#line 19189 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19290,7 +19292,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19293 "configure" +#line 19295 "configure" #include "confdefs.h" #if HAVE_DLFCN_H -- cgit v1.1 From 7ae210d5db5eb96989b2f639e65678b5597e61f0 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Sat, 5 Dec 2020 14:14:19 +0000 Subject: Fortran: flag formal argument before resolving an array spec [PR98016]. 2020-12-05 Paul Thomas gcc/fortran PR fortran/98016 * resolve.c (resolve_symbol): Set formal_arg_flag before resolving an array spec and restore value afterwards. gcc/testsuite/ PR fortran/98016 * gfortran.dg/pr98016.f90: New test. --- gcc/fortran/resolve.c | 4 ++++ gcc/testsuite/gfortran.dg/pr98016.f90 | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr98016.f90 (limited to 'gcc') diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index b6d21ad..0a8f907 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -15394,8 +15394,12 @@ resolve_symbol (gfc_symbol *sym) else if (mp_flag && sym->attr.flavor == FL_PROCEDURE && sym->attr.function) { bool saved_specification_expr = specification_expr; + bool saved_formal_arg_flag = formal_arg_flag; + specification_expr = true; + formal_arg_flag = true; gfc_resolve_array_spec (sym->result->as, false); + formal_arg_flag = saved_formal_arg_flag; specification_expr = saved_specification_expr; } diff --git a/gcc/testsuite/gfortran.dg/pr98016.f90 b/gcc/testsuite/gfortran.dg/pr98016.f90 new file mode 100644 index 0000000..71df67e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr98016.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! +! Fix for PR98016 - Used to fail with Error: Variable ‘n’ cannot appear in the +! expression at (1) for line 16. Workaround was to declare y to be real. +! +! Posted by Juergen Reuter +! +program is_it_valid + dimension y(3) + n=3 + y=func(1.0) + print *, y + stop +contains + function func(x) result (y) + dimension y(n) + y=x + end function +end -- cgit v1.1 From 4eb8f93d026eaa1de9b4820337069f3ce3465cd0 Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Sat, 5 Dec 2020 18:45:27 +0300 Subject: modulo-sched: Carefully process loop counter initialization [PR97421] Do not allow direct adjustment of pre-header initialization instruction for count register if is read in some instruction below in that basic block. gcc/ChangeLog: PR rtl-optimization/97421 * modulo-sched.c (generate_prolog_epilog): Remove forward declaration, adjust last argument name and type. (const_iteration_count): Add bool pointer parameter to return whether count register is read in pre-header after its initialization. (sms_schedule): Fix count register initialization adjustment procedure according to what const_iteration_count said. gcc/testsuite/ChangeLog: PR rtl-optimization/97421 * gcc.c-torture/execute/pr97421-1.c: New test. * gcc.c-torture/execute/pr97421-2.c: New test. * gcc.c-torture/execute/pr97421-3.c: New test. --- gcc/modulo-sched.c | 71 ++++++++++++++----------- gcc/testsuite/gcc.c-torture/execute/pr97421-1.c | 23 ++++++++ gcc/testsuite/gcc.c-torture/execute/pr97421-2.c | 18 +++++++ gcc/testsuite/gcc.c-torture/execute/pr97421-3.c | 22 ++++++++ 4 files changed, 103 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr97421-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr97421-2.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr97421-3.c (limited to 'gcc') diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index 6f699a8..4568674 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -210,8 +210,6 @@ static int sms_order_nodes (ddg_ptr, int, int *, int *); static void set_node_sched_params (ddg_ptr); static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *); static void permute_partial_schedule (partial_schedule_ptr, rtx_insn *); -static void generate_prolog_epilog (partial_schedule_ptr, class loop *, - rtx, rtx); static int calculate_stage_count (partial_schedule_ptr, int); static void calculate_must_precede_follow (ddg_node_ptr, int, int, int, int, sbitmap, sbitmap, sbitmap); @@ -391,30 +389,40 @@ doloop_register_get (rtx_insn *head, rtx_insn *tail) this constant. Otherwise return 0. */ static rtx_insn * const_iteration_count (rtx count_reg, basic_block pre_header, - int64_t * count) + int64_t *count, bool* adjust_inplace) { rtx_insn *insn; rtx_insn *head, *tail; + *adjust_inplace = false; + bool read_after = false; + if (! pre_header) return NULL; get_ebb_head_tail (pre_header, pre_header, &head, &tail); for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn)) - if (NONDEBUG_INSN_P (insn) && single_set (insn) && - rtx_equal_p (count_reg, SET_DEST (single_set (insn)))) + if (single_set (insn) && rtx_equal_p (count_reg, + SET_DEST (single_set (insn)))) { rtx pat = single_set (insn); if (CONST_INT_P (SET_SRC (pat))) { *count = INTVAL (SET_SRC (pat)); + *adjust_inplace = !read_after; return insn; } return NULL; } + else if (NONDEBUG_INSN_P (insn) && reg_mentioned_p (count_reg, insn)) + { + read_after = true; + if (reg_set_p (count_reg, insn)) + break; + } return NULL; } @@ -1126,7 +1134,7 @@ duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage, /* Generate the instructions (including reg_moves) for prolog & epilog. */ static void generate_prolog_epilog (partial_schedule_ptr ps, class loop *loop, - rtx count_reg, rtx count_init) + rtx count_reg, bool adjust_init) { int i; int last_stage = PS_STAGE_COUNT (ps) - 1; @@ -1135,12 +1143,12 @@ generate_prolog_epilog (partial_schedule_ptr ps, class loop *loop, /* Generate the prolog, inserting its insns on the loop-entry edge. */ start_sequence (); - if (!count_init) + if (adjust_init) { /* Generate instructions at the beginning of the prolog to - adjust the loop count by STAGE_COUNT. If loop count is constant - (count_init), this constant is adjusted by STAGE_COUNT in - generate_prolog_epilog function. */ + adjust the loop count by STAGE_COUNT. If loop count is constant + and it not used anywhere in prologue, this constant is adjusted by + STAGE_COUNT outside of generate_prolog_epilog function. */ rtx sub_reg = NULL_RTX; sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS, count_reg, @@ -1528,7 +1536,8 @@ sms_schedule (void) rtx_insn *count_init; int mii, rec_mii, stage_count, min_cycle; int64_t loop_count = 0; - bool opt_sc_p; + bool opt_sc_p, adjust_inplace = false; + basic_block pre_header; if (! (g = g_arr[loop->num])) continue; @@ -1569,19 +1578,13 @@ sms_schedule (void) } - /* In case of th loop have doloop register it gets special - handling. */ - count_init = NULL; - if ((count_reg = doloop_register_get (head, tail))) - { - basic_block pre_header; - - pre_header = loop_preheader_edge (loop)->src; - count_init = const_iteration_count (count_reg, pre_header, - &loop_count); - } + count_reg = doloop_register_get (head, tail); gcc_assert (count_reg); + pre_header = loop_preheader_edge (loop)->src; + count_init = const_iteration_count (count_reg, pre_header, &loop_count, + &adjust_inplace); + if (dump_file && count_init) { fprintf (dump_file, "SMS const-doloop "); @@ -1701,9 +1704,20 @@ sms_schedule (void) print_partial_schedule (ps, dump_file); } - /* case the BCT count is not known , Do loop-versioning */ - if (count_reg && ! count_init) + if (count_init) + { + if (adjust_inplace) + { + /* When possible, set new iteration count of loop kernel in + place. Otherwise, generate_prolog_epilog creates an insn + to adjust. */ + SET_SRC (single_set (count_init)) = GEN_INT (loop_count + - stage_count + 1); + } + } + else { + /* case the BCT count is not known , Do loop-versioning */ rtx comp_rtx = gen_rtx_GT (VOIDmode, count_reg, gen_int_mode (stage_count, GET_MODE (count_reg))); @@ -1713,12 +1727,7 @@ sms_schedule (void) loop_version (loop, comp_rtx, &condition_bb, prob, prob.invert (), prob, prob.invert (), true); - } - - /* Set new iteration count of loop kernel. */ - if (count_reg && count_init) - SET_SRC (single_set (count_init)) = GEN_INT (loop_count - - stage_count + 1); + } /* Now apply the scheduled kernel to the RTL of the loop. */ permute_partial_schedule (ps, g->closing_branch->first_note); @@ -1735,7 +1744,7 @@ sms_schedule (void) if (dump_file) print_node_sched_params (dump_file, g->num_nodes, ps); /* Generate prolog and epilog. */ - generate_prolog_epilog (ps, loop, count_reg, count_init); + generate_prolog_epilog (ps, loop, count_reg, !adjust_inplace); break; } diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97421-1.c b/gcc/testsuite/gcc.c-torture/execute/pr97421-1.c new file mode 100644 index 0000000..e32fb12 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr97421-1.c @@ -0,0 +1,23 @@ +/* PR rtl-optimization/97421 */ +/* { dg-additional-options "-fmodulo-sched" } */ + +int a, b, d, e; +int *volatile c = &a; + +__attribute__((noinline)) +void f(void) +{ + for (int g = 2; g >= 0; g--) { + d = 0; + for (b = 0; b <= 2; b++) + ; + e = *c; + } +} + +int main(void) +{ + f(); + if (b != 3) + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97421-2.c b/gcc/testsuite/gcc.c-torture/execute/pr97421-2.c new file mode 100644 index 0000000..142bcbc --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr97421-2.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/97421 */ +/* { dg-additional-options "-fmodulo-sched -fno-dce -fno-strict-aliasing" } */ + +static int a, b, c; +int *d = &c; +int **e = &d; +int ***f = &e; +int main() +{ + int h; + for (a = 2; a; a--) + for (h = 0; h <= 2; h++) + for (b = 0; b <= 2; b++) + ***f = 6; + + if (b != 3) + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97421-3.c b/gcc/testsuite/gcc.c-torture/execute/pr97421-3.c new file mode 100644 index 0000000..3f1485a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr97421-3.c @@ -0,0 +1,22 @@ +/* PR rtl-optimization/97421 */ +/* { dg-additional-options "-fmodulo-sched" } */ + +int a, b, c; +short d; +void e(void) { + unsigned f = 0; + for (; f <= 2; f++) { + int g[1]; + int h = (long)g; + c = 0; + for (; c < 10; c++) + g[0] = a = 0; + for (; a <= 2; a++) + b = d; + } +} +int main(void) { + e(); + if (a != 3) + __builtin_abort(); +} -- cgit v1.1 From a27d5f9a73978f20cfef1796a94f6a1a82438146 Mon Sep 17 00:00:00 2001 From: Matt Thomas Date: Sat, 5 Dec 2020 18:26:23 +0000 Subject: PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address Fix an ICE with the handling of RTL expressions like: (subreg:QI (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:67 i ] [67]) (const_int 4 [0x4])) (reg/v/f:SI 7 %r7 [orig:59 doacross ] [59])) (const_int 40 [0x28])) [1 MEM[(unsigned int *)doacross_63 + 40B + i_106 * 4]+0 S4 A32]) 0) that causes the compilation of libgomp to fail: during RTL pass: reload .../libgomp/ordered.c: In function 'GOMP_doacross_wait': .../libgomp/ordered.c:507:1: internal compiler error: in change_address_1, at emit-rtl.c:2275 507 | } | ^ 0x10a3462b change_address_1 .../gcc/emit-rtl.c:2275 0x10a353a7 adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>) .../gcc/emit-rtl.c:2409 0x10ae2993 alter_subreg(rtx_def**, bool) .../gcc/final.c:3368 0x10ae25cf cleanup_subreg_operands(rtx_insn*) .../gcc/final.c:3322 0x110922a3 reload(rtx_insn*, int) .../gcc/reload1.c:1232 0x10de2bf7 do_reload .../gcc/ira.c:5812 0x10de3377 execute .../gcc/ira.c:5986 in a `vax-netbsdelf' build, where an attempt is made to change the mode of the contained memory reference to the mode of the containing SUBREG. Such RTL expressions are produced by the VAX shift and rotate patterns (`ashift', `ashiftrt', `rotate', `rotatert') where the count operand always has the QI mode regardless of the mode, either SI or DI, of the datum shifted or rotated. Such a mode change cannot work where the memory reference uses the indexed addressing mode, where a multiplier is implied that in the VAX ISA depends on the width of the memory access requested and therefore changing the machine mode would change the address calculation as well. Avoid the attempt then by forcing the reload of any SUBREGs containing a mode-dependent memory reference, also fixing these regressions: FAIL: gcc.c-torture/compile/pr46883.c -Os (internal compiler error) FAIL: gcc.c-torture/compile/pr46883.c -Os (test for excess errors) FAIL: gcc.c-torture/execute/20120808-1.c -O2 (internal compiler error) FAIL: gcc.c-torture/execute/20120808-1.c -O2 (test for excess errors) FAIL: gcc.c-torture/execute/20120808-1.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error) FAIL: gcc.c-torture/execute/20120808-1.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) FAIL: gcc.c-torture/execute/20120808-1.c -O3 -g (internal compiler error) FAIL: gcc.c-torture/execute/20120808-1.c -O3 -g (test for excess errors) FAIL: gcc.c-torture/execute/20120808-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error) FAIL: gcc.c-torture/execute/20120808-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors) FAIL: gcc.c-torture/execute/20120808-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) FAIL: gcc.c-torture/execute/20120808-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) FAIL: gcc.dg/20050629-1.c (internal compiler error) FAIL: gcc.dg/20050629-1.c (test for excess errors) FAIL: c-c++-common/torture/pr53505.c -Os (internal compiler error) FAIL: c-c++-common/torture/pr53505.c -Os (test for excess errors) FAIL: gfortran.dg/coarray_failed_images_1.f08 -Os (internal compiler error) FAIL: gfortran.dg/coarray_stopped_images_1.f08 -Os (internal compiler error) With test case #0 included it causes a reload with: (insn 15 14 16 4 (set (reg:SI 31) (ashift:SI (const_int 1 [0x1]) (subreg:QI (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) 0))) "pr58901-0.c":15:12 94 {ashlsi3} (expr_list:REG_DEAD (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) (nil))) as follows: Reloads for insn # 15 Reload 0: reload_in (SI) = (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) ALL_REGS, RELOAD_FOR_INPUT (opnum = 2) reload_in_reg: (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) reload_reg_rtx: (reg:SI 5 %r5) resulting in: (insn 37 14 15 4 (set (reg:SI 5 %r5) (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:25 i ] [25]) (const_int 4 [0x4])) (reg/v/f:SI 4 %r4 [orig:29 s ] [29])) (const_int 4 [0x4])) [1 MEM[(int *)s_8(D) + 4B + _5 * 4]+0 S4 A32])) "pr58901-0.c":15:12 12 {movsi_2} (nil)) (insn 15 37 16 4 (set (reg:SI 2 %r2 [31]) (ashift:SI (const_int 1 [0x1]) (reg:QI 5 %r5))) "pr58901-0.c":15:12 94 {ashlsi3} (nil)) and assembly like: .L3: movl 4(%r4)[%r1],%r5 ashl %r5,$1,%r2 xorl2 %r2,%r0 incl %r1 cmpl %r1,%r3 jneq .L3 produced for the loop, providing optimization has been enabled. Likewise with test case #1 the reload of: (insn 17 16 18 4 (set (reg:SI 34) (and:SI (subreg:SI (reg/v:DI 27 [ t ]) 4) (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int} (expr_list:REG_DEAD (reg/v:DI 27 [ t ]) (nil))) is as follows: Reloads for insn # 17 Reload 0: reload_in (DI) = (reg/v:DI 27 [ t ]) reload_out (SI) = (reg:SI 2 %r2 [34]) ALL_REGS, RELOAD_OTHER (opnum = 0) reload_in_reg: (reg/v:DI 27 [ t ]) reload_out_reg: (reg:SI 2 %r2 [34]) reload_reg_rtx: (reg:DI 4 %r4) resulting in: (insn 40 16 17 4 (set (reg:DI 4 %r4) (mem/c:DI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:26 i ] [26]) (const_int 8 [0x8])) (reg/v/f:SI 3 %r3 [orig:30 s ] [30])) [1 MEM[(const struct s *)s_13(D) + _7 * 8]+0 S8 A32])) "pr58901-1.c":18:20 11 {movdi} (nil)) (insn 17 40 41 4 (set (reg:SI 4 %r4) (and:SI (reg:SI 5 %r5 [+4 ]) (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int} (nil)) and assembly like: .L3: movq (%r3)[%r1],%r4 bicl3 $-2,%r5,%r4 addl2 %r4,%r0 jaoblss %r0,%r1,.L3 First posted at: . 2020-12-05 Matt Thomas Maciej W. Rozycki gcc/ PR target/58901 * reload.c (push_reload): Also reload the inner expression of a SUBREG for pseudos associated with a mode-dependent memory reference. (find_reloads): Force a reload likewise. 2020-12-05 Maciej W. Rozycki gcc/testsuite/ PR target/58901 * gcc.c-torture/compile/pr58901-0.c: New test. * gcc.c-torture/compile/pr58901-1.c: New test. --- gcc/reload.c | 104 ++++++++++++++++-------- gcc/testsuite/gcc.c-torture/compile/pr58901-0.c | 17 ++++ gcc/testsuite/gcc.c-torture/compile/pr58901-1.c | 21 +++++ 3 files changed, 106 insertions(+), 36 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr58901-0.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr58901-1.c (limited to 'gcc') diff --git a/gcc/reload.c b/gcc/reload.c index a63cc02..b99b72c 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -1043,53 +1043,72 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, Also reload the inner expression if it does not require a secondary reload but the SUBREG does. - Finally, reload the inner expression if it is a register that is in + Also reload the inner expression if it is a register that is in the class whose registers cannot be referenced in a different size and M1 is not the same size as M2. If subreg_lowpart_p is false, we cannot reload just the inside since we might end up with the wrong register class. But if it is inside a STRICT_LOW_PART, we have - no choice, so we hope we do get the right register class there. */ + no choice, so we hope we do get the right register class there. + + Finally, reload the inner expression if it is a pseudo that will + become a MEM and the MEM has a mode-dependent address, as in that + case we obviously cannot change the mode of the MEM to that of the + containing SUBREG as that would change the interpretation of the + address. */ scalar_int_mode inner_mode; if (in != 0 && GET_CODE (in) == SUBREG - && (subreg_lowpart_p (in) || strict_low) && targetm.can_change_mode_class (GET_MODE (SUBREG_REG (in)), inmode, rclass) && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (in))] - && (CONSTANT_P (SUBREG_REG (in)) - || GET_CODE (SUBREG_REG (in)) == PLUS - || strict_low - || (((REG_P (SUBREG_REG (in)) - && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER) - || MEM_P (SUBREG_REG (in))) - && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in))) - || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD) - && is_a (GET_MODE (SUBREG_REG (in)), - &inner_mode) - && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD - && paradoxical_subreg_p (inmode, inner_mode) - && LOAD_EXTEND_OP (inner_mode) != UNKNOWN) - || (WORD_REGISTER_OPERATIONS - && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in))) - && (known_equal_after_align_down - (GET_MODE_SIZE (inmode) - 1, - GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1, - UNITS_PER_WORD))))) - || (REG_P (SUBREG_REG (in)) - && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER - /* The case where out is nonzero - is handled differently in the following statement. */ - && (out == 0 || subreg_lowpart_p (in)) - && (complex_word_subreg_p (inmode, SUBREG_REG (in)) - || !targetm.hard_regno_mode_ok (subreg_regno (in), inmode))) - || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS - && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)), - SUBREG_REG (in)) - == NO_REGS)) + && (strict_low + || (subreg_lowpart_p (in) + && (CONSTANT_P (SUBREG_REG (in)) + || GET_CODE (SUBREG_REG (in)) == PLUS + || (((REG_P (SUBREG_REG (in)) + && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER) + || MEM_P (SUBREG_REG (in))) + && (paradoxical_subreg_p (inmode, + GET_MODE (SUBREG_REG (in))) + || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD) + && is_a (GET_MODE (SUBREG_REG + (in)), + &inner_mode) + && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD + && paradoxical_subreg_p (inmode, inner_mode) + && LOAD_EXTEND_OP (inner_mode) != UNKNOWN) + || (WORD_REGISTER_OPERATIONS + && partial_subreg_p (inmode, + GET_MODE (SUBREG_REG (in))) + && (known_equal_after_align_down + (GET_MODE_SIZE (inmode) - 1, + GET_MODE_SIZE (GET_MODE (SUBREG_REG + (in))) - 1, + UNITS_PER_WORD))))) + || (REG_P (SUBREG_REG (in)) + && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER + /* The case where out is nonzero + is handled differently in the following statement. */ + && (out == 0 || subreg_lowpart_p (in)) + && (complex_word_subreg_p (inmode, SUBREG_REG (in)) + || !targetm.hard_regno_mode_ok (subreg_regno (in), + inmode))) + || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS + && (secondary_reload_class (1, rclass, + GET_MODE (SUBREG_REG (in)), + SUBREG_REG (in)) + == NO_REGS)) + || (REG_P (SUBREG_REG (in)) + && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER + && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)), + GET_MODE (SUBREG_REG (in)), + inmode)))) || (REG_P (SUBREG_REG (in)) - && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER - && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)), - GET_MODE (SUBREG_REG (in)), inmode)))) + && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER + && reg_equiv_mem (REGNO (SUBREG_REG (in))) + && (mode_dependent_address_p + (XEXP (reg_equiv_mem (REGNO (SUBREG_REG (in))), 0), + MEM_ADDR_SPACE (reg_equiv_mem (REGNO (SUBREG_REG (in))))))))) { #ifdef LIMIT_RELOAD_CLASS in_subreg_loc = inloc; @@ -3157,6 +3176,19 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known, && paradoxical_subreg_p (operand_mode[i], inner_mode) && LOAD_EXTEND_OP (inner_mode) != UNKNOWN))) + /* We must force a reload of a SUBREG's inner expression + if it is a pseudo that will become a MEM and the MEM + has a mode-dependent address, as in that case we + obviously cannot change the mode of the MEM to that + of the containing SUBREG as that would change the + interpretation of the address. */ + || (REG_P (operand) + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_equiv_mem (REGNO (operand)) + && (mode_dependent_address_p + (XEXP (reg_equiv_mem (REGNO (operand)), 0), + (MEM_ADDR_SPACE + (reg_equiv_mem (REGNO (operand))))))) ) force_reload = 1; } diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c b/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c new file mode 100644 index 0000000..d98e29e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c @@ -0,0 +1,17 @@ +typedef int __attribute__ ((mode (SI))) int_t; + +struct s +{ + int_t n; + int_t c[]; +}; + +int_t +ashlsi (int_t x, const struct s *s) +{ + int_t i; + + for (i = 0; i < s->n; i++) + x ^= 1 << s->c[i]; + return x; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c b/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c new file mode 100644 index 0000000..e01dba0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c @@ -0,0 +1,21 @@ +typedef signed int __attribute__ ((mode (SI))) int_t; + +struct s +{ + int_t n; + int_t m : 1; + int_t l : 31; +}; + +int_t +movdi (int_t x, const struct s *s) +{ + int_t i; + + for (i = 0; i < x; i++) + { + const struct s t = s[i]; + x += t.m ? 1 : 0; + } + return x; +} -- cgit v1.1 From 91ae8fbc5aa02bd889492d3c04a7fcb95026a77e Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: VAX: Remove `c' operand format specifier overload The `c' operand format specifier is handled directly by the middle end in `output_asm_insn': %cN means require operand N to be a constant and print the constant expression with no punctuation. however it resorts to the target for constants that are not valid addresses: else if (letter == 'c') { if (CONSTANT_ADDRESS_P (operands[opnum])) output_addr_const (asm_out_file, operands[opnum]); else output_operand (operands[opnum], 'c'); } The VAX backend expects the fallback never to happen and overloads `c' with the branch condition code. This is confusing however and it is not like we are short of letters, so instead make the branch condition code use `k', and then for consistency make `K' the reverse branch condition code format specifier. This is safe to do as we provide no means to use a computed branch condition code in user `asm'. gcc/ * config/vax/vax.c (print_operand): Replace `c' and `C' with `k' and `K' respectively. * config/vax/vax.md (*branch, *branch_reversed): Update accordingly. --- gcc/config/vax/vax.c | 4 ++-- gcc/config/vax/vax.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index da4e6cb..0b3b76e 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -509,9 +509,9 @@ print_operand (FILE *file, rtx x, int code) fputc (ASM_DOUBLE_CHAR, file); else if (code == '|') fputs (REGISTER_PREFIX, file); - else if (code == 'c') + else if (code == 'k') fputs (cond_name (x), file); - else if (code == 'C') + else if (code == 'K') fputs (rev_cond_name (x), file); else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0) fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x)); diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 4897ce4..e3018a0 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -1111,7 +1111,7 @@ (label_ref (match_operand 1 "" "")) (pc)))] "" - "j%c0 %l1") + "j%k0 %l1") ;; Recognize reversed jumps. (define_insn "*branch_reversed" @@ -1122,7 +1122,7 @@ (pc) (label_ref (match_operand 1 "" ""))))] "" - "j%C0 %l1") ; %C0 negates condition + "j%K0 %l1") ; %K0 negates condition ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is -- cgit v1.1 From 85f5a7d6ac9380fb9a07a8c900aa2e21d83d6805 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: VAX: Define LEGITIMATE_PIC_OPERAND_P The VAX ELF psABI does not permit the use of all hardware operand modes for PIC symbol references due to the need to use PC-relative addressing for symbols that end up local and the need to make references indirect symbols that end up global. Therefore symbols referred as immediates may only be used with the move and push address (MOVA and PUSHA) instructions and their PC-relative displacement address mode, as there is no genuine PC-relative immediate available that all the other instructions would have to use. Furthermore global symbol references must not have an offset applied, which has to be added with a separate instruction, because there is no support now for GOT entries for external `symbol+offset' references, so any indirect GOT references made by the static linker from the original direct symbol references must not have an addend applied. Consequently no addend is allowed even if a given external symbol turns out local, for whatever reason, at the static link time. Define the LEGITIMATE_PIC_OPERAND_P macro then, a corresponding function and predicate to exclude the relevant expressions as required, and then a constraint so that reloads are produced where needed, and use the new facilities in the machine description, folding corresponding duplicated patterns for local and external symbols together. Rewrite predicates to make use of the new function, rename them to match their sense and also remove ones no longer used. All this fixing an ICE like this: during RTL pass: postreload .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c: In function 'testE': .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:89:1: internal compiler error: in reload_combine_note_use, at postreload.c:1559 .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:96:65: note: in expansion of macro 'T' 0x10fe84cb reload_combine_note_use .../gcc/postreload.c:1559 0x10fe8857 reload_combine_note_use .../gcc/postreload.c:1621 0x10fe8303 reload_combine_note_use .../gcc/postreload.c:1517 0x10fe7c7b reload_combine .../gcc/postreload.c:1408 0x10fe3417 reload_cse_regs .../gcc/postreload.c:67 0x10feaf9f execute .../gcc/postreload.c:2358 due to the presence of a pseudo register post-reload: (insn 435 228 229 13 (set (reg:SI 1 %r1) (mem/c:SI (reg/f:SI 341) [25 sE+12 S4 A8])) ".../gcc/testsuite/gcc.c-torture/execute/20040709-2.c":96:65 12 {movsi_2} (nil)) (due to the use of an offset `sE+12' symbol reference) and removing these regressions: FAIL: gcc.c-torture/execute/20040709-2.c -O2 (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O2 (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -g (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O3 -g (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -Os (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -Os (test for excess errors) FAIL: gcc.c-torture/execute/20040709-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error) FAIL: gcc.c-torture/execute/20040709-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -O2 (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -O2 (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -O3 -g (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -O3 -g (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -Os (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -Os (test for excess errors) FAIL: gcc.c-torture/execute/20040709-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error) FAIL: gcc.c-torture/execute/20040709-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors) FAIL: gcc.dg/torture/pr52028.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) FAIL: gcc.dg/torture/pr52028.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) gcc/ * config/vax/constraints.md (A): New constraint. * config/vax/predicates.md (external_symbolic_operand) (external_const_operand): Remove predicates. (local_symbolic_operand): Rename to... (pic_symbolic_operand): ... this, and rework. (external_memory_operand): Rename to... (non_pic_external_memory_operand): ... this, and rework. (illegal_blk_memory_operand, illegal_addsub_di_memory_operand): Update accordingly. * config/vax/vax-protos.h (vax_acceptable_pic_operand_p): New prototype. * config/vax/vax.c (vax_acceptable_pic_operand_p): New function. (vax_output_int_add): Update according to predicate rework. * config/vax/vax.h (LEGITIMATE_PIC_OPERAND_P): New macro. * config/vax/vax.md (pushlclsymreg, pushextsymreg): Fold together, and rename to... (*pushsymreg): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. (movlclsymreg, movextsymreg): Fold together, and rename to... (*movsymreg): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. (pushextsym, pushlclsym): Fold together, and rename to... (*pushsym): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. (movextsym, movlclsym): Fold together, and rename to... (*movsym): ... this. Use the `pic_symbolic_operand' predicate and the `A' constraint for the displacement operand. --- gcc/config/vax/constraints.md | 4 ++++ gcc/config/vax/predicates.md | 34 ++++++++------------------- gcc/config/vax/vax-protos.h | 1 + gcc/config/vax/vax.c | 39 +++++++++++++++++++++++++++++-- gcc/config/vax/vax.h | 5 ++++ gcc/config/vax/vax.md | 54 +++++++++++-------------------------------- 6 files changed, 70 insertions(+), 67 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/constraints.md b/gcc/config/vax/constraints.md index b8262b6..d4eddb8 100644 --- a/gcc/config/vax/constraints.md +++ b/gcc/config/vax/constraints.md @@ -112,6 +112,10 @@ (and (match_operand:DI 0 "memory_operand") (not (match_operand:DI 0 "illegal_addsub_di_memory_operand" "")))) +(define_constraint "A" + "@internal An integer constant suitable for address load operations." + (match_test ("CONSTANT_P (op) && pic_symbolic_operand (op, mode)"))) + (define_constraint "T" "@internal satisfies CONSTANT_P and, if pic is enabled, is not a SYMBOL_REF, LABEL_REF, or CONST." (and (match_test ("CONSTANT_P (op)")) diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md index 7eefc60..93e91e4 100644 --- a/gcc/config/vax/predicates.md +++ b/gcc/config/vax/predicates.md @@ -23,33 +23,17 @@ (define_predicate "symbolic_operand" (match_code "const,symbol_ref,label_ref")) -(define_predicate "local_symbolic_operand" - (match_code "const,symbol_ref,label_ref") -{ - if (GET_CODE (op) == LABEL_REF) - return 1; - if (GET_CODE (op) == SYMBOL_REF) - return !flag_pic || SYMBOL_REF_LOCAL_P (op); - if (GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF) - return 1; - return !flag_pic || SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0)); -}) - -(define_predicate "external_symbolic_operand" - (and (match_code "symbol_ref") - (not (match_operand 0 "local_symbolic_operand" "")))) - -(define_predicate "external_const_operand" - (and (match_code "const") - (match_test "GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF - && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0))"))) +(define_predicate "pic_symbolic_operand" + (and (match_code "const,symbol_ref,label_ref") + (match_test "!flag_pic + || vax_acceptable_pic_operand_p (op, false, true)"))) (define_predicate "nonsymbolic_operand" (and (ior (match_test "!flag_pic") (not (match_operand 0 "symbolic_operand"))) (match_operand 0 "general_operand" ""))) -(define_predicate "external_memory_operand" +(define_predicate "non_pic_external_memory_operand" (match_code "mem") { rtx addr = XEXP (op, 0); @@ -61,8 +45,8 @@ addr = XEXP (addr, 0); if (GET_CODE (addr) == PLUS) addr = XEXP (addr, 1); - return external_symbolic_operand (addr, SImode) - || external_const_operand (addr, SImode); + return (symbolic_operand (addr, SImode) + && !vax_acceptable_pic_operand_p (addr, true, true)); }) (define_predicate "indirect_memory_operand" @@ -87,7 +71,7 @@ (define_predicate "illegal_blk_memory_operand" (and (match_code "mem") (ior (and (match_test "flag_pic") - (match_operand 0 "external_memory_operand" "")) + (match_operand 0 "non_pic_external_memory_operand" "")) (ior (match_operand 0 "indexed_memory_operand" "") (ior (match_operand 0 "indirect_memory_operand" "") (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))))) @@ -95,7 +79,7 @@ (define_predicate "illegal_addsub_di_memory_operand" (and (match_code "mem") (ior (and (match_test "flag_pic") - (match_operand 0 "external_memory_operand" "")) + (match_operand 0 "non_pic_external_memory_operand" "")) (ior (match_operand 0 "indexed_memory_operand" "") (ior (match_operand 0 "indirect_memory_operand" "") (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))))) diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index cda2544..454d35e 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -21,6 +21,7 @@ extern bool legitimate_constant_address_p (rtx); extern void vax_expand_prologue (void); #ifdef RTX_CODE +extern bool vax_acceptable_pic_operand_p (rtx, bool, bool); extern const char *cond_name (rtx); extern bool adjacent_operands_p (rtx, rtx, machine_mode); extern const char *rev_cond_name (rtx); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 0b3b76e..37f5dad 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1033,6 +1033,39 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, return true; } +/* With ELF we do not support GOT entries for external `symbol+offset' + references, so do not accept external symbol references if an offset + is to be added. Do not accept external symbol references at all if + LOCAL_P is set. This is for cases where making a reference indirect + would make it invalid. Do not accept any kind of symbols if SYMBOL_P + is clear. This is for situations where the a reference is used as an + immediate value for operations other than address loads (MOVA/PUSHA), + as those operations do not support PC-relative immediates. */ + +bool +vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED, + bool local_p ATTRIBUTE_UNUSED, + bool symbol_p ATTRIBUTE_UNUSED) +{ +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) + { + x = XEXP (XEXP (x, 0), 0); + local_p = true; + } + switch (GET_CODE (x)) + { + case SYMBOL_REF: + return symbol_p && !(local_p && !SYMBOL_REF_LOCAL_P (x)); + case LABEL_REF: + return symbol_p && !(local_p && LABEL_REF_NONLOCAL_P (x)); + default: + break; + } +#endif + return true; +} + /* Output code to add DELTA to the first argument, and then jump to FUNCTION. Used for C++ multiple inheritance. .mask ^m #conservative entry mask @@ -1370,8 +1403,10 @@ vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode) { gcc_assert (rtx_equal_p (operands[0], operands[1])); #ifdef NO_EXTERNAL_INDIRECT_ADDRESS - gcc_assert (!flag_pic || !external_memory_operand (low[2], SImode)); - gcc_assert (!flag_pic || !external_memory_operand (low[0], SImode)); + gcc_assert (!flag_pic + || !non_pic_external_memory_operand (low[2], SImode)); + gcc_assert (!flag_pic + || !non_pic_external_memory_operand (low[0], SImode)); #endif /* No reason to add a 0 to the low part and thus no carry, so just diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index c1d0171..146b0a6 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -442,6 +442,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; of a shift count. */ /* #define SHIFT_COUNT_TRUNCATED */ +/* We need to reject symbol references in PIC code except for address + loads, handled elsewhere. */ +#define LEGITIMATE_PIC_OPERAND_P(x) \ + vax_acceptable_pic_operand_p ((x), false, false) + /* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */ diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index e3018a0..e6b217f 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -338,34 +338,6 @@ add2 %1,%0 add3 %1,%2,%0") -(define_insn "pushlclsymreg" - [(set (match_operand:SI 0 "push_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "local_symbolic_operand" "i")))] - "flag_pic" - "pushab %a2[%1]") - -(define_insn "pushextsymreg" - [(set (match_operand:SI 0 "push_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "external_symbolic_operand" "i")))] - "flag_pic" - "pushab %a2[%1]") - -(define_insn "movlclsymreg" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "local_symbolic_operand" "i")))] - "flag_pic" - "movab %a2[%1],%0") - -(define_insn "movextsymreg" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "external_symbolic_operand" "i")))] - "flag_pic" - "movab %a2[%1],%0") - (define_insn "add3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") @@ -1525,29 +1497,31 @@ "" "casel %0,$0,%1") -(define_insn "pushextsym" +(define_insn "*pushsym" [(set (match_operand:SI 0 "push_operand" "=g") - (match_operand:SI 1 "external_symbolic_operand" "i"))] + (match_operand:SI 1 "pic_symbolic_operand" "A"))] "" "pushab %a1") -(define_insn "movextsym" +(define_insn "*movsym" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "external_symbolic_operand" "i"))] + (match_operand:SI 1 "pic_symbolic_operand" "A"))] "" "movab %a1,%0") -(define_insn "pushlclsym" +(define_insn "*pushsymreg" [(set (match_operand:SI 0 "push_operand" "=g") - (match_operand:SI 1 "local_symbolic_operand" "i"))] - "" - "pushab %a1") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A")))] + "flag_pic" + "pushab %a2[%1]") -(define_insn "movlclsym" +(define_insn "*movsymreg" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "local_symbolic_operand" "i"))] - "" - "movab %a1,%0") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A")))] + "flag_pic" + "movab %a2[%1],%0") ;;- load or push effective address ;; These come after the move and add/sub patterns -- cgit v1.1 From 7920fe3d81ece3a23360ce0d8899f1568a9037c8 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: VAX/testsuite: Run target testing over all the usual optimization levels It makes sense to use what other targets do and run all the VAX test cases over all the usual optimization levels, so make `vax.exp' use our `gcc-dg-runtest' rather than the generic `dg-runtest' test driver. This breaks `pr56875.c' however, which is optimized away at levels above `-O0' as a result of how it has been written for calculations to make no effect: FAIL: gcc.target/vax/pr56875.c -O1 scan-assembler ashq .*,\\$0xffffffffffffffff, FAIL: gcc.target/vax/pr56875.c -O2 scan-assembler ashq .*,\\$0xffffffffffffffff, FAIL: gcc.target/vax/pr56875.c -O3 -g scan-assembler ashq .*,\\$0xffffffffffffffff, FAIL: gcc.target/vax/pr56875.c -Os scan-assembler ashq .*,\\$0xffffffffffffffff, FAIL: gcc.target/vax/pr56875.c -O2 -flto -fno-use-linker-plugin -flto-partition=none scan-assembler ashq .*,\\$0xffffffffffffffff, FAIL: gcc.target/vax/pr56875.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects scan-assembler ashq .*,\\$0xffffffffffffffff, Rather than keeping it at `-O0' update the test case for its code to do make effect while retaining its sense. Also reformat it according to our requirements. gcc/testsuite/ * gcc.target/vax/vax.exp: Use `gcc-dg-runtest' rather than `dg-runtest'. * gcc.target/vax/pr56875.c (dg-options): Make empty. (a): Rewrite for calculations to make effect. Reformat. --- gcc/testsuite/gcc.target/vax/pr56875.c | 11 ++++------- gcc/testsuite/gcc.target/vax/vax.exp | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/vax/pr56875.c b/gcc/testsuite/gcc.target/vax/pr56875.c index f409afe..191e05e 100644 --- a/gcc/testsuite/gcc.target/vax/pr56875.c +++ b/gcc/testsuite/gcc.target/vax/pr56875.c @@ -1,13 +1,10 @@ /* { dg-do compile } */ -/* { dg-options "-O0" } */ +/* { dg-options "" } */ /* { dg-final { scan-assembler "ashq .*,\\\$0xffffffffffffffff," } } */ /* { dg-final { scan-assembler-not "ashq .*,\\\$-1," } } */ -void -a (void) +unsigned long long +a (unsigned long i) { - unsigned long i = 1; - unsigned long long v; - - v = ~ (unsigned long long) 0 << i; + return ~(unsigned long long) 0 << i; } diff --git a/gcc/testsuite/gcc.target/vax/vax.exp b/gcc/testsuite/gcc.target/vax/vax.exp index 4f48055..678e900 100644 --- a/gcc/testsuite/gcc.target/vax/vax.exp +++ b/gcc/testsuite/gcc.target/vax/vax.exp @@ -34,7 +34,7 @@ if ![info exists DEFAULT_CFLAGS] then { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ "" $DEFAULT_CFLAGS # All done. -- cgit v1.1 From dfb21f37fde4f9e11e9b3b6b6ea6dc9d5fbed644 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: VAX: Rationalize expression and address costs Expression costs are required to be given in terms of COSTS_N_INSNS (n), which is defined to stand for the count of single fast instructions, and actually returns `n * 4'. The VAX backend however instead operates on naked numbers, causing an anomaly for the integer const zero rtx, where the cost given is 4 as opposed to 1 for integers in the [1:63] range, as well as -1 for comparisons. This is because the value of 0 returned by `vax_rtx_costs' is converted to COSTS_N_INSNS (1) in `pattern_cost': return cost > 0 ? cost : COSTS_N_INSNS (1); Consequently, where feasible, 1 or -1 are preferred over 0 by the middle end causing code pessimization, e.g. rather than producing this: subl2 $4,%sp movl 4(%ap),%r0 jgtr .L2 addl2 $2,%r0 .L2: ret or this: subl2 $4,%sp addl3 4(%ap),8(%ap),%r0 jlss .L6 addl2 $2,%r0 .L6: ret code is produced like this: subl2 $4,%sp movl 4(%ap),%r0 cmpl %r0,$1 jgeq .L2 addl2 $2,%r0 .L2: ret or this: subl2 $4,%sp addl3 4(%ap),8(%ap),%r0 cmpl %r0,$-1 jleq .L6 addl2 $2,%r0 .L6: ret from this: int compare_mov (int x) { if (x > 0) return x; else return x + 2; } and this: int compare_add (int x, int y) { int z; z = x + y; if (z < 0) return z; else return z + 2; } respectively, which is slower and larger both at a time. Furthermore once the backend is converted to MODE_CC this anomaly makes it usually impossible to remove redundant comparisons in the comparison elimination pass, because most VAX instructions set the condition codes as per the relation of the instruction's result to 0 and not -1. The middle end has some other assumptions as to rtx costs being given in terms of COSTS_N_INSNS, so wrap all the VAX rtx costs then as they stand into COSTS_N_INSNS invocations, effectively scaling the costs by 4 while preserving their relative values, except for the integer const zero rtx given the value of `COSTS_N_INSNS (1) / 2', half of a fast instruction (this can be further halved if needed in the future). Adjust address costs likewise so that they remain proportional to the new absolute values of rtx costs. Code size stats are as follows, collected from 17639 executables built in `check-c' GCC testing: samples average median -------------------------------------- regressions 1420 0.400% 0.195% unchanged 13811 0.000% 0.000% progressions 2408 -0.504% -0.201% -------------------------------------- total 17639 -0.037% 0.000% with a small number of outliers only (over 5% size change): old new change %change filename ---------------------------------------------------- 4991 5249 258 5.1693 981001-1.exe 2637 2777 140 5.3090 interchange-6.exe 2187 2307 120 5.4869 sprintf.x7 3969 4197 228 5.7445 pr28982a.exe 8264 8816 552 6.6795 vector-compare-1.exe 5199 5575 376 7.2321 pr28982b.exe 2113 2411 298 14.1031 20030323-1.exe 2113 2411 298 14.1031 20030323-1.exe 2113 2411 298 14.1031 20030323-1.exe so it seems we are looking good, and we have complementing reductions to compensate: old new change %change filename ---------------------------------------------------- 2919 2631 -288 -9.8663 pr57521.exe 3427 3167 -260 -7.5868 sabd_1.exe 2985 2765 -220 -7.3701 ssad-run.exe 2985 2765 -220 -7.3701 ssad-run.exe 2985 2765 -220 -7.3701 usad-run.exe 2985 2765 -220 -7.3701 usad-run.exe 4509 4253 -256 -5.6775 vshuf-v2sf.exe 4541 4285 -256 -5.6375 vshuf-v2si.exe 4673 4417 -256 -5.4782 vshuf-v2df.exe 2993 2841 -152 -5.0785 abs-2.x4 2993 2841 -152 -5.0785 abs-3.x4 This actually causes `loop-8.c' to regress: FAIL: gcc.dg/loop-8.c scan-rtl-dump-times loop2_invariant "Decided" 1 FAIL: gcc.dg/loop-8.c scan-rtl-dump-not loop2_invariant "without introducing a new temporary register" but upon a closer inspection this is a red herring. Old code looks as follows: .file "loop-8.c" .text .align 1 .globl f .type f, @function f: .word 0 subl2 $4,%sp movl 4(%ap),%r2 movl 8(%ap),%r3 movl $42,(%r2) clrl %r0 movl $42,%r1 movl %r1,%r4 jbr .L2 .L5: movl %r4,%r1 .L2: movl %r1,(%r3)[%r0] incl %r0 cmpl %r0,$100 jeql .L6 movl $42,(%r2)[%r0] bicl3 $-2,%r0,%r1 jeql .L5 movl %r0,%r1 jbr .L2 .L6: ret .size f, .-f while new one is like below: .file "loop-8.c" .text .align 1 .globl f .type f, @function f: .word 0 subl2 $4,%sp movl 4(%ap),%r2 movl $42,(%r2)+ movl 8(%ap),%r1 clrl %r0 movl $42,%r3 movzbl $100,%r4 movl %r3,%r5 jbr .L2 .L5: movl %r5,%r3 .L2: movl %r3,(%r1)+ incl %r0 cmpl %r0,%r4 jeql .L6 movl $42,(%r2)+ bicl3 $-2,%r0,%r3 jeql .L5 movl %r0,%r3 jbr .L2 .L6: ret .size f, .-f and is clearly better: not only it is smaller, but it also uses the post-increment rather than indexed addressing mode in the loop, of which the former comes for free in terms of both performance and code size while the latter causes an extra byte per operand to be produced for the index register and also incurs an execution penalty for the extra address calculation. Exclude the case from VAX testing then, as already done for some other targets and discussed with commit d242fdaec186 ("gcc.dg/loop-8.c: Skip for mmix."). gcc/ * config/vax/vax.c (vax_address_cost): Express the cost in terms of COSTS_N_INSNS. (vax_rtx_costs): Likewise. gcc/testsuite/ * gcc.dg/loop-8.c: Exclude for `vax-*-*'. * gcc.target/vax/compare-add-zero.c: New test. * gcc.target/vax/compare-mov-zero.c: New test. --- gcc/config/vax/vax.c | 110 ++++++++++++------------ gcc/testsuite/gcc.dg/loop-8.c | 2 +- gcc/testsuite/gcc.target/vax/compare-add-zero.c | 27 ++++++ gcc/testsuite/gcc.target/vax/compare-mov-zero.c | 24 ++++++ 4 files changed, 109 insertions(+), 54 deletions(-) create mode 100644 gcc/testsuite/gcc.target/vax/compare-add-zero.c create mode 100644 gcc/testsuite/gcc.target/vax/compare-mov-zero.c (limited to 'gcc') diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 37f5dad..b6c2210 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -748,7 +748,7 @@ vax_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED) { - return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x))); + return COSTS_N_INSNS (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x))); } /* Cost of an expression on a VAX. This version has costs tuned for the @@ -778,12 +778,13 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST_INT: if (INTVAL (x) == 0) { - *total = 0; + *total = COSTS_N_INSNS (1) / 2; return true; } if (outer_code == AND) { - *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2; + *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077 + ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2)); return true; } if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077 @@ -792,7 +793,7 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, || ((outer_code == PLUS || outer_code == MINUS) && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)) { - *total = 1; + *total = COSTS_N_INSNS (1); return true; } /* FALLTHRU */ @@ -800,48 +801,48 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST: case LABEL_REF: case SYMBOL_REF: - *total = 3; + *total = COSTS_N_INSNS (3); return true; case CONST_DOUBLE: if (GET_MODE_CLASS (mode) == MODE_FLOAT) - *total = vax_float_literal (x) ? 5 : 8; + *total = vax_float_literal (x) ? COSTS_N_INSNS (5) : COSTS_N_INSNS (8); else *total = ((CONST_DOUBLE_HIGH (x) == 0 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64) || (outer_code == PLUS && CONST_DOUBLE_HIGH (x) == -1 - && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)) - ? 2 : 5; + && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64) + ? COSTS_N_INSNS (2) : COSTS_N_INSNS (5)); return true; case POST_INC: - *total = 2; - return true; /* Implies register operand. */ + *total = COSTS_N_INSNS (2); + return true; /* Implies register operand. */ case PRE_DEC: - *total = 3; - return true; /* Implies register operand. */ + *total = COSTS_N_INSNS (3); + return true; /* Implies register operand. */ case MULT: switch (mode) { case E_DFmode: - *total = 16; /* 4 on VAX 9000 */ + *total = COSTS_N_INSNS (16); /* 4 on VAX 9000 */ break; case E_SFmode: - *total = 9; /* 4 on VAX 9000, 12 on VAX 2 */ + *total = COSTS_N_INSNS (9); /* 4 on VAX 9000, 12 on VAX 2 */ break; case E_DImode: - *total = 16; /* 6 on VAX 9000, 28 on VAX 2 */ + *total = COSTS_N_INSNS (16); /* 6 on VAX 9000, 28 on VAX 2 */ break; case E_SImode: case E_HImode: case E_QImode: - *total = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */ + *total = COSTS_N_INSNS (10); /* 3-4 on VAX 9000, 20-28 on VAX 2 */ break; default: - *total = MAX_COST; /* Mode is not supported. */ + *total = MAX_COST; /* Mode is not supported. */ return true; } break; @@ -849,63 +850,65 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case UDIV: if (mode != SImode) { - *total = MAX_COST; /* Mode is not supported. */ + *total = MAX_COST; /* Mode is not supported. */ return true; } - *total = 17; + *total = COSTS_N_INSNS (17); break; case DIV: if (mode == DImode) - *total = 30; /* Highly variable. */ + *total = COSTS_N_INSNS (30); /* Highly variable. */ else if (mode == DFmode) /* divide takes 28 cycles if the result is not zero, 13 otherwise */ - *total = 24; + *total = COSTS_N_INSNS (24); else - *total = 11; /* 25 on VAX 2 */ + *total = COSTS_N_INSNS (11); /* 25 on VAX 2 */ break; case MOD: - *total = 23; + *total = COSTS_N_INSNS (23); break; case UMOD: if (mode != SImode) { - *total = MAX_COST; /* Mode is not supported. */ + *total = MAX_COST; /* Mode is not supported. */ return true; } - *total = 29; + *total = COSTS_N_INSNS (29); break; case FLOAT: - *total = (6 /* 4 on VAX 9000 */ - + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode)); + *total = COSTS_N_INSNS (6 /* 4 on VAX 9000 */ + + (mode == DFmode) + + (GET_MODE (XEXP (x, 0)) != SImode)); break; case FIX: - *total = 7; /* 17 on VAX 2 */ + *total = COSTS_N_INSNS (7); /* 17 on VAX 2 */ break; case ASHIFT: case LSHIFTRT: case ASHIFTRT: if (mode == DImode) - *total = 12; + *total = COSTS_N_INSNS (12); else - *total = 10; /* 6 on VAX 9000 */ + *total = COSTS_N_INSNS (10); /* 6 on VAX 9000 */ break; case ROTATE: case ROTATERT: - *total = 6; /* 5 on VAX 2, 4 on VAX 9000 */ + *total = COSTS_N_INSNS (6); /* 5 on VAX 2, 4 on VAX 9000 */ if (CONST_INT_P (XEXP (x, 1))) fmt = "e"; /* all constant rotate counts are short */ break; case PLUS: case MINUS: - *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */ + *total = (mode == DFmode /* 6/8 on VAX 9000, 16/15 on VAX 2 */ + ? COSTS_N_INSNS (13) : COSTS_N_INSNS (8)); /* Small integer operands can use subl2 and addl2. */ if ((CONST_INT_P (XEXP (x, 1))) && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127) @@ -914,16 +917,16 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case IOR: case XOR: - *total = 3; + *total = COSTS_N_INSNS (3); break; case AND: /* AND is special because the first operand is complemented. */ - *total = 3; + *total = COSTS_N_INSNS (3); if (CONST_INT_P (XEXP (x, 0))) { if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63) - *total = 4; + *total = COSTS_N_INSNS (4); fmt = "e"; i = 1; } @@ -931,38 +934,38 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case NEG: if (mode == DFmode) - *total = 9; + *total = COSTS_N_INSNS (9); else if (mode == SFmode) - *total = 6; + *total = COSTS_N_INSNS (6); else if (mode == DImode) - *total = 4; + *total = COSTS_N_INSNS (4); else - *total = 2; + *total = COSTS_N_INSNS (2); break; case NOT: - *total = 2; + *total = COSTS_N_INSNS (2); break; case ZERO_EXTRACT: case SIGN_EXTRACT: - *total = 15; + *total = COSTS_N_INSNS (15); break; case MEM: if (mode == DImode || mode == DFmode) - *total = 5; /* 7 on VAX 2 */ + *total = COSTS_N_INSNS (5); /* 7 on VAX 2 */ else - *total = 3; /* 4 on VAX 2 */ + *total = COSTS_N_INSNS (3); /* 4 on VAX 2 */ x = XEXP (x, 0); if (!REG_P (x) && GET_CODE (x) != POST_INC) - *total += vax_address_cost_1 (x); + *total += COSTS_N_INSNS (vax_address_cost_1 (x)); return true; case FLOAT_EXTEND: case FLOAT_TRUNCATE: case TRUNCATE: - *total = 3; /* FIXME: Costs need to be checked */ + *total = COSTS_N_INSNS (3); /* FIXME: Costs need to be checked */ break; default: @@ -993,12 +996,12 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST_INT: if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63 && mode != QImode) - *total += 1; /* 2 on VAX 2 */ + *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */ break; case CONST: case LABEL_REF: case SYMBOL_REF: - *total += 1; /* 2 on VAX 2 */ + *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */ break; case CONST_DOUBLE: if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) @@ -1006,27 +1009,28 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, /* Registers are faster than floating point constants -- even those constants which can be encoded in a single byte. */ if (vax_float_literal (op)) - *total += 1; + *total += COSTS_N_INSNS (1); else - *total += (GET_MODE (x) == DFmode) ? 3 : 2; + *total += (GET_MODE (x) == DFmode + ? COSTS_N_INSNS (3) : COSTS_N_INSNS (2)); } else { if (CONST_DOUBLE_HIGH (op) != 0 || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63) - *total += 2; + *total += COSTS_N_INSNS (2); } break; case MEM: - *total += 1; /* 2 on VAX 2 */ + *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */ if (!REG_P (XEXP (op, 0))) - *total += vax_address_cost_1 (XEXP (op, 0)); + *total += COSTS_N_INSNS (vax_address_cost_1 (XEXP (op, 0))); break; case REG: case SUBREG: break; default: - *total += 1; + *total += COSTS_N_INSNS (1); break; } } diff --git a/gcc/testsuite/gcc.dg/loop-8.c b/gcc/testsuite/gcc.dg/loop-8.c index af317d8..90ea1c4 100644 --- a/gcc/testsuite/gcc.dg/loop-8.c +++ b/gcc/testsuite/gcc.dg/loop-8.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1 -fdump-rtl-loop2_invariant" } */ -/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-*" } } */ +/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-* vax-*-*" } } */ /* Load immediate on condition is available from z13 on and prevents moving the load out of the loop, so always run this test with -march=zEC12 that does not have load immediate on condition. */ diff --git a/gcc/testsuite/gcc.target/vax/compare-add-zero.c b/gcc/testsuite/gcc.target/vax/compare-add-zero.c new file mode 100644 index 0000000..97d4c53 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/compare-add-zero.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int +compare_add (int x, int y) +{ + int z; + + z = x + y; + if (z < 0) + return z; + else + return z + 2; +} + +/* Expect assembly like: + + addl3 4(%ap),8(%ap),%r0 + jlss .L1 + addl2 $2,%r0 +.L1: + +A reverse branch may be used at some optimization levels. */ + +/* Make sure the comparison is made against 0 rather than -1. */ +/* { dg-final { scan-assembler-not "\tj(gtr|leq) " } } */ +/* { dg-final { scan-assembler "\tj(geq|lss) " } } */ diff --git a/gcc/testsuite/gcc.target/vax/compare-mov-zero.c b/gcc/testsuite/gcc.target/vax/compare-mov-zero.c new file mode 100644 index 0000000..c802049 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/compare-mov-zero.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int +compare_mov (int x) +{ + if (x > 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 + jgtr .L2 + addl2 $2,%r0 +.L2: + +A reverse branch may be used at some optimization levels. */ + +/* Make sure the comparison is made against 0 rather than 1. */ +/* { dg-final { scan-assembler-not "\tj(geq|lss) " } } */ +/* { dg-final { scan-assembler "\tj(gtr|leq) " } } */ -- cgit v1.1 From 8c18e22afb061329766be3532a06a85ccc492d9c Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: VAX: Correct fatal issues with the `ffs' builtin The `builtins.md' machine description fragment is not included anywhere and is therefore dead code, which has become bitrotten due to non-use. If actually enabled, it does not build due to the use of an unknown `t' constraint: .../gcc/config/vax/builtins.md:42:1: error: undefined machine-specific constraint at this point: "t" .../gcc/config/vax/builtins.md:42:1: note: in operand 1 which came from commit becb93d02cc1 ("builtins.md (ffssi2_internal): Correct constraint."), which was not applied as posted and reviewed; `T' was meant to be used instead. Once this has been fixed this code still fails building: .../gcc/config/vax/builtins.md: In function 'rtx_def* gen_ffssi2(rtx, rtx)': .../gcc/config/vax/builtins.md:35:19: error: 'gen_bne' was not declared in this scope; did you mean 'gen_use'? 35 | emit_jump_insn (gen_bne (label)); | ^~~~~~~ | gen_use make[2]: *** [Makefile:1122: insn-emit.o] Error 1 Finally the FFS machine instruction sets the Z condition code according to the comparison of the value held in the source operand against zero rather than the value held in the target operand. If the source operand is found hold zero, then the target operand is set to the width of the source operand, 32 for SImode (FFS supports arbitrary widths). Correct the build issues then and update RTL to match the operation of the machine instruction. A test case will be added separately. gcc/ * config/vax/builtins.md (ffssi2): Make preparation statements actually buildable. (ffssi2_internal): Fix input constraints; make the RTL pattern match reality for `cc0'. --- gcc/config/vax/builtins.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index ac0e027..6bce7a8 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -31,8 +31,12 @@ " { rtx label = gen_label_rtx (); + rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label); + rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); + rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx); + emit_insn (gen_ffssi2_internal (operands[0], operands[1])); - emit_jump_insn (gen_bne (label)); + emit_jump_insn (gen_rtx_SET (pc_rtx, target)); emit_insn (gen_negsi2 (operands[0], const1_rtx)); emit_label (label); emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx)); @@ -41,8 +45,10 @@ (define_insn "ffssi2_internal" [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") - (ffs:SI (match_operand:SI 1 "general_operand" "nrQt"))) - (set (cc0) (match_dup 0))] + (ffs:SI (match_operand:SI 1 "general_operand" "nrQT"))) + (set (cc0) + (compare (match_dup 1) + (const_int 0)))] "" "ffs $0,$32,%1,%0") -- cgit v1.1 From da749b98cf9d87ebed92de08ff45f8a0d7fc9d1a Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: RTL: Also support HOST_WIDE_INT with int iterators Add wide integer aka 'w' rtx format support to int iterators so that machine description can iterate over `const_int' expressions. This is made by expanding standard integer aka 'i' format support, observing that any standard integer already present in any of our existing RTL code will also fit into HOST_WIDE_INT, so there is no need for a separate handler. Any truncation of the number parsed is made by the caller. An assumption is made however that no place relies on capping out of range values to INT_MAX. Now the 'p' format is handled explicitly rather than being implied by rtx being a SUBREG, so actually assert that it is, just to play safe. gcc/ * read-rtl.c: Add a page-feed separator at the start of iterator code. (struct iterator_group): Change the return type to HOST_WIDE_INT for the `find_builtin' member. Likewise the second parameter type for the `apply_iterator' member. (atoll) [!HAVE_ATOQ]: Reorder. (find_mode, find_code): Change the return type to HOST_WIDE_INT. (apply_mode_iterator, apply_code_iterator) (apply_subst_iterator): Change the second parameter type to HOST_WIDE_INT. (find_int): Handle input suitable for HOST_WIDE_INT output. (apply_int_iterator): Rewrite in terms of explicit format interpretation. (rtx_reader::read_rtx_operand) <'w'>: Fold into... <'i', 'n', 'p'>: ... this. * doc/md.texi (Int Iterators): Document 'w' rtx format support. --- gcc/doc/md.texi | 10 ++-- gcc/read-rtl.c | 165 ++++++++++++++++++++++++++++++-------------------------- 2 files changed, 93 insertions(+), 82 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index da8c9a2..573a340 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -11223,11 +11223,11 @@ The construct: @end smallexample defines a pseudo integer constant @var{name} that can be instantiated as -@var{inti} if condition @var{condi} is true. Each @var{int} -must have the same rtx format. @xref{RTL Classes}. Int iterators can appear -in only those rtx fields that have 'i' as the specifier. This means that -each @var{int} has to be a constant defined using define_constant or -define_c_enum. +@var{inti} if condition @var{condi} is true. Each @var{int} must have the +same rtx format. @xref{RTL Classes}. Int iterators can appear in only +those rtx fields that have 'i', 'n', 'w', or 'p' as the specifier. This +means that each @var{int} has to be a constant defined using define_constant +or define_c_enum. As with mode and code iterators, each pattern that uses @var{name} will be expanded @var{n} times, once with all uses of @var{name} replaced by diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 3ec83a60..403f254 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -77,12 +77,12 @@ struct iterator_group { /* Treat the given string as the name of a standard mode, etc., and return its integer value. */ - int (*find_builtin) (const char *); + HOST_WIDE_INT (*find_builtin) (const char *); /* Make the given rtx use the iterator value given by the third argument. If the iterator applies to operands, the second argument gives the operand index, otherwise it is ignored. */ - void (*apply_iterator) (rtx, unsigned int, int); + void (*apply_iterator) (rtx, unsigned int, HOST_WIDE_INT); /* Return the C token for the given standard mode, code, etc. */ const char *(*get_c_token) (int); @@ -139,7 +139,7 @@ static void one_time_initialization (void); /* Global singleton. */ rtx_reader *rtx_reader_ptr = NULL; - + /* The mode and code iterator structures. */ static struct iterator_group modes, codes, ints, substs; @@ -152,9 +152,49 @@ static vec iterator_uses; /* The list of all attribute uses in the current rtx. */ static vec attribute_uses; +/* Provide a version of a function to read a long long if the system does + not provide one. */ +#if (HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG \ + && !HAVE_DECL_ATOLL \ + && !defined (HAVE_ATOQ)) +HOST_WIDE_INT atoll (const char *); + +HOST_WIDE_INT +atoll (const char *p) +{ + int neg = 0; + HOST_WIDE_INT tmp_wide; + + while (ISSPACE (*p)) + p++; + if (*p == '-') + neg = 1, p++; + else if (*p == '+') + p++; + + tmp_wide = 0; + while (ISDIGIT (*p)) + { + HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0'); + if (new_wide < tmp_wide) + { + /* Return INT_MAX equiv on overflow. */ + tmp_wide = HOST_WIDE_INT_M1U >> 1; + break; + } + tmp_wide = new_wide; + p++; + } + + if (neg) + tmp_wide = -tmp_wide; + return tmp_wide; +} +#endif + /* Implementations of the iterator_group callbacks for modes. */ -static int +static HOST_WIDE_INT find_mode (const char *name) { int i; @@ -167,7 +207,7 @@ find_mode (const char *name) } static void -apply_mode_iterator (rtx x, unsigned int, int mode) +apply_mode_iterator (rtx x, unsigned int, HOST_WIDE_INT mode) { PUT_MODE (x, (machine_mode) mode); } @@ -215,7 +255,7 @@ maybe_find_code (const char *name) /* Implementations of the iterator_group callbacks for codes. */ -static int +static HOST_WIDE_INT find_code (const char *name) { rtx_code code = maybe_find_code (name); @@ -225,7 +265,7 @@ find_code (const char *name) } static void -apply_code_iterator (rtx x, unsigned int, int code) +apply_code_iterator (rtx x, unsigned int, HOST_WIDE_INT code) { PUT_CODE (x, (enum rtx_code) code); } @@ -245,20 +285,52 @@ get_code_token (int code) we have to accept any int as valid. No cross-checking can be done. */ -static int +static HOST_WIDE_INT find_int (const char *name) { + HOST_WIDE_INT tmp; + validate_const_int (name); - return atoi (name); +#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT + tmp = atoi (name); +#else +#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + tmp = atol (name); +#else + /* Prefer atoll over atoq, since the former is in the ISO C99 standard. + But prefer not to use our hand-rolled function above either. */ +#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ) + tmp = atoll (name); +#else + tmp = atoq (name); +#endif +#endif +#endif + return tmp; } static void -apply_int_iterator (rtx x, unsigned int index, int value) +apply_int_iterator (rtx x, unsigned int index, HOST_WIDE_INT value) { - if (GET_CODE (x) == SUBREG) - SUBREG_BYTE (x) = value; - else - XINT (x, index) = value; + RTX_CODE code = GET_CODE (x); + const char *format_ptr = GET_RTX_FORMAT (code); + + switch (format_ptr[index]) + { + case 'i': + case 'n': + XINT (x, index) = value; + break; + case 'w': + XWINT (x, index) = value; + break; + case 'p': + gcc_assert (code == SUBREG); + SUBREG_BYTE (x) = value; + break; + default: + gcc_unreachable (); + } } static const char * @@ -279,7 +351,7 @@ get_int_token (int value) applied. If such attribute has already been added, then no the routine has no effect. */ static void -apply_subst_iterator (rtx rt, unsigned int, int value) +apply_subst_iterator (rtx rt, unsigned int, HOST_WIDE_INT value) { rtx new_attr; rtvec attrs_vec, new_attrs_vec; @@ -1003,44 +1075,6 @@ initialize_iterators (void) } } -/* Provide a version of a function to read a long long if the system does - not provide one. */ -#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !HAVE_DECL_ATOLL && !defined(HAVE_ATOQ) -HOST_WIDE_INT atoll (const char *); - -HOST_WIDE_INT -atoll (const char *p) -{ - int neg = 0; - HOST_WIDE_INT tmp_wide; - - while (ISSPACE (*p)) - p++; - if (*p == '-') - neg = 1, p++; - else if (*p == '+') - p++; - - tmp_wide = 0; - while (ISDIGIT (*p)) - { - HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0'); - if (new_wide < tmp_wide) - { - /* Return INT_MAX equiv on overflow. */ - tmp_wide = HOST_WIDE_INT_M1U >> 1; - break; - } - tmp_wide = new_wide; - p++; - } - - if (neg) - tmp_wide = -tmp_wide; - return tmp_wide; -} -#endif - #ifdef GENERATOR_FILE /* Process a define_conditions directive, starting with the optional @@ -1939,32 +1973,9 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx) } break; - case 'w': - { - HOST_WIDE_INT tmp_wide; - read_name (&name); - validate_const_int (name.string); -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - tmp_wide = atoi (name.string); -#else -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG - tmp_wide = atol (name.string); -#else - /* Prefer atoll over atoq, since the former is in the ISO C99 standard. - But prefer not to use our hand-rolled function above either. */ -#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ) - tmp_wide = atoll (name.string); -#else - tmp_wide = atoq (name.string); -#endif -#endif -#endif - XWINT (return_rtx, idx) = tmp_wide; - } - break; - case 'i': case 'n': + case 'w': case 'p': { /* Can be an iterator or an integer constant. */ -- cgit v1.1 From 94f336768e199bc268c30446a63b49a53b02f648 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: ifcvt: Add missing call to `onlyjump_p' Do not convert a conditional jump into conditional execution (and remove the jump as a consequence) if the jump has side effects. gcc/ * ifcvt.c (dead_or_predicable) [!IFCVT_MODIFY_TESTS]: Bail out if `!onlyjump_p'. --- gcc/ifcvt.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc') diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index a9ea7b1..0bd05dc 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -5127,6 +5127,11 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, rtx cond; + /* If the conditional jump is more than just a conditional jump, + then we cannot do conditional execution conversion on this block. */ + if (!onlyjump_p (jump)) + goto nce; + cond = cond_exec_get_condition (jump); if (! cond) return FALSE; @@ -5154,6 +5159,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, earliest = jump; } + nce: #endif /* If we allocated new pseudos (e.g. in the conditional move -- cgit v1.1 From a2bd4e52cf710924107b08daaf3d09d7798c8022 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: loop-iv: Add missing calls to `onlyjump_p' Ignore jumps that have side effects in loop processing as pasting the body of a loop multiple times within is semantically equivalent to jump deletion (between the iterations unrolled) even if we do not physically delete the jump RTL insn. gcc/ * loop-iv.c (simplify_using_initial_values): Only process jumps that match `onlyjump_p'. (check_simple_exit): Likewise. --- gcc/loop-iv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 9f266e2..9d401d2 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1936,7 +1936,7 @@ simplify_using_initial_values (class loop *loop, enum rtx_code op, rtx *expr) while (1) { insn = BB_END (e->src); - if (any_condjump_p (insn)) + if (any_condjump_p (insn) && onlyjump_p (insn)) { rtx cond = get_condition (BB_END (e->src), NULL, false, true); @@ -2887,7 +2887,7 @@ check_simple_exit (class loop *loop, edge e, class niter_desc *desc) return; /* It must end in a simple conditional jump. */ - if (!any_condjump_p (BB_END (exit_bb))) + if (!any_condjump_p (BB_END (exit_bb)) || !onlyjump_p (BB_END (exit_bb))) return; ein = EDGE_SUCC (exit_bb, 0); -- cgit v1.1 From 4ec78ef4837eab9b7ce3f20d7f7b39c8a2f1e41c Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: sel-sched-ir: Add missing call to `onlyjump_p' Do not try to remove a conditional jump if it has side effects. gcc/ * sel-sched-ir.c (maybe_tidy_empty_bb): Only try to remove a conditional jump if `onlyjump_p'. --- gcc/sel-sched-ir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index c8e086e..2bcd398 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -3793,7 +3793,8 @@ maybe_tidy_empty_bb (basic_block bb) else if (single_succ_p (pred_bb) && any_condjump_p (BB_END (pred_bb))) { /* If possible, try to remove the unneeded conditional jump. */ - if (INSN_SCHED_TIMES (BB_END (pred_bb)) == 0 + if (onlyjump_p (BB_END (pred_bb)) + && INSN_SCHED_TIMES (BB_END (pred_bb)) == 0 && !IN_CURRENT_FENCE_P (BB_END (pred_bb))) { if (!sel_remove_insn (BB_END (pred_bb), false, false)) -- cgit v1.1 From 64880a7c49e2f60d1ccabf6798f5b0ea8234edc1 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:24 +0000 Subject: cfgrtl: Add missing call to `onlyjump_p' If any unconditional jumps within a block have side effects then the block cannot be considered empty. gcc/ * cfgrtl.c (rtl_block_empty_p): Return false if `!onlyjump_p' too. --- gcc/cfgrtl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 5e909e2..4d02495 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -4862,7 +4862,8 @@ rtl_block_empty_p (basic_block bb) return true; FOR_BB_INSNS (bb, insn) - if (NONDEBUG_INSN_P (insn) && !any_uncondjump_p (insn)) + if (NONDEBUG_INSN_P (insn) + && (!any_uncondjump_p (insn) || !onlyjump_p (insn))) return false; return true; -- cgit v1.1 From 4b70b2e07a589c4d50e14fa597eb164375a10a20 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: loop-doloop: Add missing call to `onlyjump_p' Keep any jump that has side effects as those must not be removed. gcc/ * loop-doloop.c (add_test): Only remove the jump if `onlyjump_p'. --- gcc/loop-doloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 02282d4..661e502 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -378,7 +378,7 @@ add_test (rtx cond, edge *e, basic_block dest) bb = split_edge_and_insert (*e, seq); *e = single_succ_edge (bb); - if (any_uncondjump_p (jump)) + if (any_uncondjump_p (jump) && onlyjump_p (jump)) { /* The condition is always true. */ delete_insn (jump); -- cgit v1.1 From 630c9a4d54de7c084e146afe82c6e89a9f2cf3d7 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE VAX has interlocked branch instructions used for atomic operations and we want to have them wrapped in UNSPEC_VOLATILE so as not to have code carried across. This however breaks with jump optimization and leads to an ICE in the build of libbacktrace like: .../libbacktrace/mmap.c:190:1: internal compiler error: in fixup_reorder_chain, at cfgrtl.c:3934 190 | } | ^ 0x1087d46b fixup_reorder_chain .../gcc/cfgrtl.c:3934 0x1087f29f cfg_layout_finalize() .../gcc/cfgrtl.c:4447 0x1087c74f execute .../gcc/cfgrtl.c:3662 on RTL like: (jump_insn 18 17 150 4 (unspec_volatile [ (set (pc) (if_then_else (eq (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1 S4 A32]) (const_int 1 [0x1]) (const_int 0 [0])) (const_int 1 [0x1])) (label_ref 20) (pc))) (set (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1 S4 A32]) (const_int 1 [0x1]) (const_int 0 [0])) (const_int 1 [0x1])) ] 101) ".../libbacktrace/mmap.c":135:14 158 {jbbssisi} (nil) -> 20) when those branches are enabled with a follow-up change. Also showing with: FAIL: gcc.dg/pr61756.c (internal compiler error) Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency, also in UNSPEC. The presence of UNSPEC_VOLATILE will prevent such branches from being removed as they won't be accepted by `onlyjump_p', we just need to let them through. gcc/ * jump.c (pc_set): Also accept a jump wrapped in UNSPEC or UNSPEC_VOLATILE. (any_uncondjump_p, any_condjump_p): Update comment accordingly. --- gcc/jump.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/jump.c b/gcc/jump.c index 34a8f20..c508467 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -850,9 +850,17 @@ pc_set (const rtx_insn *insn) pat = PATTERN (insn); /* The set is allowed to appear either as the insn pattern or - the first set in a PARALLEL. */ - if (GET_CODE (pat) == PARALLEL) - pat = XVECEXP (pat, 0, 0); + the first set in a PARALLEL, UNSPEC or UNSPEC_VOLATILE. */ + switch (GET_CODE (pat)) + { + case PARALLEL: + case UNSPEC: + case UNSPEC_VOLATILE: + pat = XVECEXP (pat, 0, 0); + break; + default: + break; + } if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC) return pat; @@ -860,7 +868,9 @@ pc_set (const rtx_insn *insn) } /* Return true when insn is an unconditional direct jump, - possibly bundled inside a PARALLEL. */ + possibly bundled inside a PARALLEL, UNSPEC or UNSPEC_VOLATILE. + The instruction may have various other effects so before removing the jump + you must verify onlyjump_p. */ int any_uncondjump_p (const rtx_insn *insn) @@ -876,9 +886,9 @@ any_uncondjump_p (const rtx_insn *insn) } /* Return true when insn is a conditional jump. This function works for - instructions containing PC sets in PARALLELs. The instruction may have - various other effects so before removing the jump you must verify - onlyjump_p. + instructions containing PC sets in PARALLELs, UNSPECs or UNSPEC_VOLATILEs. + The instruction may have various other effects so before removing the jump + you must verify onlyjump_p. Note that unlike condjump_p it returns false for unconditional jumps. */ -- cgit v1.1 From 47d524a636a00be5a7a2c65b1c7dc5beaa9bc1e7 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Use a mode iterator to produce individual interlocked branches Regardless of the machine mode all the interlocked branches of the same kind, one of the two provided by the ISA, use the same RTL patterns and machine instructions, except for the memory operand's constraint. Remove code duplication then and make use of a mode iterator combined with an attribute to expand the same insn patterns with the constraint suitably substituted from a single template. No functional change. gcc/ * config/vax/builtins.md (bb_mem): New mode attribute. (jbbssiqi, jbbssihi, jbbssisi): Fold insns into... (jbbssi): ... this. (jbbcciqi, jbbccihi, jbbccisi): Likewise... (jbbcci): ... this. --- gcc/config/vax/builtins.md | 96 ++++++++-------------------------------------- 1 file changed, 15 insertions(+), 81 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index 6bce7a8..473b44f 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -24,6 +24,8 @@ ] ) +(define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")]) + (define_expand "ffssi2" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ffs:SI (match_operand:SI 1 "general_operand" "")))] @@ -73,58 +75,24 @@ DONE; }") -(define_insn "jbbssiqi" - [(parallel - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "g") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 1))])] - "" - "jbssi %1,%0,%l2") - -(define_insn "jbbssihi" +(define_insn "jbbssi" [(parallel [(set (pc) (if_then_else - (ne (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:HI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 1))])] - "" - "jbssi %1,%0,%l2") - -(define_insn "jbbssisi" - [(parallel - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) + (eq (zero_extract:SI + (match_operand:VAXint 0 "memory_operand" "") + (const_int 1) + (match_operand:SI 1 "general_operand" "nrmT")) + (const_int 1)) (label_ref (match_operand 2 "" "")) (pc))) - (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0") (const_int 1) (match_dup 1)) (const_int 1))])] "" "jbssi %1,%0,%l2") - (define_expand "sync_lock_release" [(set (match_operand:VAXint 0 "memory_operand" "+m") (unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n") @@ -145,54 +113,20 @@ DONE; }") -(define_insn "jbbcciqi" - [(parallel - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "g") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 0))])] - "" - "jbcci %1,%0,%l2") - -(define_insn "jbbccihi" +(define_insn "jbbcci" [(parallel [(set (pc) (if_then_else - (eq (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) + (eq (zero_extract:SI + (match_operand:VAXint 0 "memory_operand" "") + (const_int 1) + (match_operand:SI 1 "general_operand" "nrmT")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) - (set (zero_extract:SI (match_operand:HI 3 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0") (const_int 1) (match_dup 1)) (const_int 0))])] "" "jbcci %1,%0,%l2") - -(define_insn "jbbccisi" - [(parallel - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 0))])] - "" - "jbcci %1,%0,%l2") - -- cgit v1.1 From 2500add25bd3258a66cc7ae199ab7eae53cc3202 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Use an int iterator to produce individual interlocked branches With mode-specific interlocked branch insns already folded into iterated templates now fold the two templates into one too, observing that the only difference between them is the value of the bit branched on, which is of course reflected both in the RTL expression and the instruction produced. Use an int iterator to iterate over the bit value, making use of the newly-added wide integer support, and substituting patterns as necessary to produce equivalent individual insns. No functional change. gcc/ * config/vax/builtins.md (bit): New int iterator. (ccss): New int attribute. (jbbssi, jbbcci): Fold insns into... (jbbi): ... this. --- gcc/config/vax/builtins.md | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index 473b44f..8bbcd60 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -26,6 +26,9 @@ (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")]) +(define_int_iterator bit [0 1]) +(define_int_attr ccss [(0 "cc") (1 "ss")]) + (define_expand "ffssi2" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ffs:SI (match_operand:SI 1 "general_operand" "")))] @@ -75,24 +78,6 @@ DONE; }") -(define_insn "jbbssi" - [(parallel - [(set (pc) - (if_then_else - (eq (zero_extract:SI - (match_operand:VAXint 0 "memory_operand" "") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrmT")) - (const_int 1)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 1))])] - "" - "jbssi %1,%0,%l2") - (define_expand "sync_lock_release" [(set (match_operand:VAXint 0 "memory_operand" "+m") (unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n") @@ -113,7 +98,7 @@ DONE; }") -(define_insn "jbbcci" +(define_insn "jbbi" [(parallel [(set (pc) (if_then_else @@ -121,12 +106,12 @@ (match_operand:VAXint 0 "memory_operand" "") (const_int 1) (match_operand:SI 1 "general_operand" "nrmT")) - (const_int 0)) + (const_int bit)) (label_ref (match_operand 2 "" "")) (pc))) (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0") (const_int 1) (match_dup 1)) - (const_int 0))])] + (const_int bit))])] "" - "jbcci %1,%0,%l2") + "jbi %1,%0,%l2") -- cgit v1.1 From fbe575958c2ec322ac1703a14737a95e6036c4e0 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: 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 `jbbi' insn, so as to address the ICE. Also remove useless operations from the `sync_lock_test_and_set' and `sync_lock_release' expanders as those always either complete or fail and therefore never fall through to using their template other than to match operands. Wrap `jbbi' 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): Remove `set' and `unspec' operations, match operands only. Reformat. (sync_lock_release): Likewise. Remove cruft. (jbbi): Wrap into `unspec_volatile', use `any_memory_operand' predicate. --- gcc/config/vax/builtins.md | 36 +++++++++++++++++------------------- gcc/config/vax/predicates.md | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index 8bbcd60..7e27854 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -19,8 +19,7 @@ (define_constants [ - (VUNSPEC_LOCK 100) ; sync lock and test - (VUNSPEC_UNLOCK 101) ; sync lock release + (VUNSPEC_LOCK 100) ; sync lock operations ] ) @@ -58,10 +57,9 @@ "ffs $0,$32,%1,%0") (define_expand "sync_lock_test_and_set" - [(set (match_operand:VAXint 0 "nonimmediate_operand" "=&g") - (unspec:VAXint [(match_operand:VAXint 1 "memory_operand" "+m") - (match_operand:VAXint 2 "const_int_operand" "n") - ] VUNSPEC_LOCK))] + [(match_operand:VAXint 0 "nonimmediate_operand" "=&g") + (match_operand:VAXint 1 "memory_operand" "+m") + (match_operand:VAXint 2 "const_int_operand" "n")] "" " { @@ -72,46 +70,46 @@ label = gen_label_rtx (); emit_move_insn (operands[0], const1_rtx); - emit_jump_insn (gen_jbbssi (operands[1], const0_rtx, label, operands[1])); + emit_jump_insn (gen_jbbssi (operands[1], const0_rtx, label, + operands[1])); emit_move_insn (operands[0], const0_rtx); emit_label (label); DONE; }") (define_expand "sync_lock_release" - [(set (match_operand:VAXint 0 "memory_operand" "+m") - (unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n") - ] VUNSPEC_UNLOCK))] + [(match_operand:VAXint 0 "memory_operand" "+m") + (match_operand:VAXint 1 "const_int_operand" "n")] "" " { rtx label; + if (operands[1] != const0_rtx) FAIL; -#if 1 + label = gen_label_rtx (); - emit_jump_insn (gen_jbbcci (operands[0], const0_rtx, label, operands[0])); + emit_jump_insn (gen_jbbcci (operands[0], const0_rtx, label, + operands[0])); emit_label (label); -#else - emit_move_insn (operands[0], const0_rtx); -#endif DONE; }") (define_insn "jbbi" - [(parallel + [(unspec_volatile [(set (pc) (if_then_else (eq (zero_extract:SI - (match_operand:VAXint 0 "memory_operand" "") + (match_operand:VAXint 0 "any_memory_operand" "") (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 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:VAXint 3 "any_memory_operand" "+0") (const_int 1) (match_dup 1)) - (const_int bit))])] + (const_int bit))] + VUNSPEC_LOCK)] "" "jbi %1,%0,%l2") diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md index 93e91e4..7c97b36 100644 --- a/gcc/config/vax/predicates.md +++ b/gcc/config/vax/predicates.md @@ -93,3 +93,19 @@ (and (match_code "const_int,const_double,subreg,reg,mem") (and (match_operand:DI 0 "general_operand" "") (not (match_operand:DI 0 "illegal_addsub_di_memory_operand"))))) + +;; Return 1 if the operand is in volatile memory. Note that during the +;; RTL generation phase, `memory_operand' does not return TRUE for +;; volatile memory references. So this function allows us to recognize +;; volatile references where it's safe. +(define_predicate "volatile_mem_operand" + (and (match_code "mem") + (match_test "MEM_VOLATILE_P (op)") + (if_then_else (match_test "reload_completed") + (match_operand 0 "memory_operand") + (match_test "memory_address_p (mode, XEXP (op, 0))")))) + +;; Return 1 if the operand is a volatile or non-volatile memory operand. +(define_predicate "any_memory_operand" + (ior (match_operand 0 "memory_operand") + (match_operand 0 "volatile_mem_operand"))) -- cgit v1.1 From ea84baeb190a2aa396360d9d94ce8b6207172186 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Actually enable `builtins.md' now that it is fully functional Test cases will follow. gcc/ * config/vax/vax.md: Include `builtins.md'. --- gcc/config/vax/vax.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index e6b217f..66f03df 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -1634,3 +1634,5 @@ emit_barrier (); DONE; }) + +(include "builtins.md") -- cgit v1.1 From 65eee57a8cccc77a1bfd5ad5cde53460ad564124 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Add a test for the SImode `ffs' operation gcc/testsuite/ * gcc.target/vax/ffssi.c: New test. --- gcc/testsuite/gcc.target/vax/ffssi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.target/vax/ffssi.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/vax/ffssi.c b/gcc/testsuite/gcc.target/vax/ffssi.c new file mode 100644 index 0000000..3e7a3c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/ffssi.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +int +ffssi (int x) +{ + return __builtin_ffs (x); +} + +/* Expect assembly like: + + ffs $0,$32,%r1,%r0 + jneq .L2 + mnegl $1,%r0 +.L2: + incl %r0 + + */ + +/* { dg-final { scan-assembler "\tffs \\\$0,\\\$32," } } */ -- cgit v1.1 From da076a8b12c17b10cfe2e6a9c5ea84aa0a0f5ebf Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release' Based on gcc.dg/pr61756.c. gcc/testsuite/ * gcc.target/vax/bbcci.c: New test. * gcc.target/vax/bbssi.c: New test. --- gcc/testsuite/gcc.target/vax/bbcci.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.target/vax/bbssi.c | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 gcc/testsuite/gcc.target/vax/bbcci.c create mode 100644 gcc/testsuite/gcc.target/vax/bbssi.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/vax/bbcci.c b/gcc/testsuite/gcc.target/vax/bbcci.c new file mode 100644 index 0000000..f58d3a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/bbcci.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +#include + +extern volatile atomic_flag guard; + +void +try_atomic_flag_clear (void) +{ + atomic_flag_clear (&guard); +} + +/* Expect assembly like: + + jbcci $0,guard,.L2 +.L2: + + */ + +/* { dg-final { scan-assembler "\tjbcci \\\$0,guard," } } */ diff --git a/gcc/testsuite/gcc.target/vax/bbssi.c b/gcc/testsuite/gcc.target/vax/bbssi.c new file mode 100644 index 0000000..65111e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/bbssi.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +#include + +extern volatile atomic_flag guard; + +void +try_atomic_flag_test_and_set (void) +{ + atomic_flag_test_and_set (&guard); +} + +/* Expect assembly like: + + jbssi $0,guard,.L1 +.L1: + + */ + +/* { dg-final { scan-assembler "\tjbssi \\\$0,guard," } } */ -- cgit v1.1 From a17ab4b6add6a7b7cedbef39af442ca99f7cb3f8 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Provide the `ctz' operation Our `ffssi2_internal' pattern and the machine FFS instruction, which technically is a bit-field operation, match the `ctz' operation exactly, with the result produced for the bit-field source operand of zero equal to its width as specified with another machine instruction operand, not directly expressed in RTL and currently hardcoded in the assembly code produced. In our terms this is the bit size of the machine mode used, and although it's SImode now let's be flexible for an upcoming change. The operation also sets the Z condition code according to the value of the source operand. gcc/ * config/vax/builtins.md (ffssi2_internal): Rename insn to... (ctzsi2): ... this. Update the RTL operation. (ffssi2): Update accordingly. * config/vax/vax.c (vax_notice_update_cc): Handle CTZ. * config/vax/vax.h (CTZ_DEFINED_VALUE_AT_ZERO): New macro. gcc/testsuite/ * gcc.target/vax/ctzsi.c: New test. --- gcc/config/vax/builtins.md | 6 +++--- gcc/config/vax/vax.c | 3 +++ gcc/config/vax/vax.h | 4 ++++ gcc/testsuite/gcc.target/vax/ctzsi.c | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/vax/ctzsi.c (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index 7e27854..e8cefe7 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -39,7 +39,7 @@ rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx); - emit_insn (gen_ffssi2_internal (operands[0], operands[1])); + emit_insn (gen_ctzsi2 (operands[0], operands[1])); emit_jump_insn (gen_rtx_SET (pc_rtx, target)); emit_insn (gen_negsi2 (operands[0], const1_rtx)); emit_label (label); @@ -47,9 +47,9 @@ DONE; }") -(define_insn "ffssi2_internal" +(define_insn "ctzsi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") - (ffs:SI (match_operand:SI 1 "general_operand" "nrQT"))) + (ctz:SI (match_operand:SI 1 "general_operand" "nrQT"))) (set (cc0) (compare (match_dup 1) (const_int 0)))] diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index b6c2210..69a05b3 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1135,6 +1135,9 @@ vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED) case REG: cc_status.flags = CC_NO_OVERFLOW; break; + case CTZ: + cc_status.flags = CC_NOT_NEGATIVE; + break; default: break; } diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index 146b0a6..43182ff 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -683,3 +683,7 @@ VAX operand formatting codes: by the proper FDE definition. */ #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM) +/* Upon failure to find the bit the FFS hardware instruction returns + the position of the bit immediately following the field specified. */ +#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ + ((VALUE) = GET_MODE_BITSIZE (MODE), 2) diff --git a/gcc/testsuite/gcc.target/vax/ctzsi.c b/gcc/testsuite/gcc.target/vax/ctzsi.c new file mode 100644 index 0000000..8be4271 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/ctzsi.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +int +ctzsi (unsigned int x) +{ + return __builtin_ctz (x); +} + +/* Expect assembly like: + + ffs $0,$32,4(%ap),%r0 + + */ + +/* { dg-final { scan-assembler "\tffs \\\$0,\\\$32," } } */ -- cgit v1.1 From 273ffa3a6fef82738dd86522374fae69ab0e2651 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Also provide QImode and HImode `ctz' and `ffs' operations The FFS machine instruction provides for arbitrary input bit-field widths so take advantage of this and convert `ffssi2' and `ctzsi2' to templates for all the three of QI, HI, SI machine modes. Test cases will be added separately. gcc/ * config/vax/builtins.md (width): New mode attribute. (ffssi2): Rework expander into... (ffs2): ... this. (ctzsi2): Rework insn into... (ctz2): ... this. --- gcc/config/vax/builtins.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index e8cefe7..b7ed976 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -23,14 +23,15 @@ ] ) +(define_mode_attr width [(QI "8") (HI "16") (SI "32")]) (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")]) (define_int_iterator bit [0 1]) (define_int_attr ccss [(0 "cc") (1 "ss")]) -(define_expand "ffssi2" +(define_expand "ffs2" [(set (match_operand:SI 0 "nonimmediate_operand" "") - (ffs:SI (match_operand:SI 1 "general_operand" "")))] + (ffs:SI (match_operand:VAXint 1 "general_operand" "")))] "" " { @@ -39,22 +40,22 @@ rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx); - emit_insn (gen_ctzsi2 (operands[0], operands[1])); + emit_insn (gen_ctz2 (operands[0], operands[1])); emit_jump_insn (gen_rtx_SET (pc_rtx, target)); - emit_insn (gen_negsi2 (operands[0], const1_rtx)); + emit_insn (gen_neg2 (operands[0], const1_rtx)); emit_label (label); - emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx)); + emit_insn (gen_add3 (operands[0], operands[0], const1_rtx)); DONE; }") -(define_insn "ctzsi2" +(define_insn "ctz2" [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") - (ctz:SI (match_operand:SI 1 "general_operand" "nrQT"))) + (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT"))) (set (cc0) (compare (match_dup 1) (const_int 0)))] "" - "ffs $0,$32,%1,%0") + "ffs $0,$,%1,%0") (define_expand "sync_lock_test_and_set" [(match_operand:VAXint 0 "nonimmediate_operand" "=&g") -- cgit v1.1 From b9240a4abcd1e194dbd80460a9a7632e63fb7f49 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:25 +0000 Subject: VAX: Actually produce QImode and HImode `ctz' operations The middle end does not refer to `ctzqi2'/`ctzhi2' or `ffsqi2'/`ffshi2' patterns by name where `__builtin_ctz' or `__builtin_ffs' respectively is invoked for an argument of the QImode or HImode type, and instead it extends the data type before passing it to `ctzsi2' or `ffssi2'. Avoid the redundant operation and use a peephole2 to convert it to the right RTL expression that will collapse the two operations into a single machine instruction instead unless we need the extended intermediate result for another purpose. gcc/ * config/vax/builtins.md: Add a peephole2 for QImode and HImode `ctz' operations. (any_extend): New code iterator. gcc/testsuite/ * gcc.target/vax/ctzhi.c: New test. * gcc.target/vax/ctzqi.c: New test. * gcc.target/vax/ffshi.c: New test. * gcc.target/vax/ffsqi.c: New test. --- gcc/config/vax/builtins.md | 22 ++++++++++++++++++++++ gcc/testsuite/gcc.target/vax/ctzhi.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.target/vax/ctzqi.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.target/vax/ffshi.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/vax/ffsqi.c | 24 ++++++++++++++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 gcc/testsuite/gcc.target/vax/ctzhi.c create mode 100644 gcc/testsuite/gcc.target/vax/ctzqi.c create mode 100644 gcc/testsuite/gcc.target/vax/ffshi.c create mode 100644 gcc/testsuite/gcc.target/vax/ffsqi.c (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index b7ed976..e96ac3f 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -29,6 +29,8 @@ (define_int_iterator bit [0 1]) (define_int_attr ccss [(0 "cc") (1 "ss")]) +(define_code_iterator any_extend [sign_extend zero_extend]) + (define_expand "ffs2" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ffs:SI (match_operand:VAXint 1 "general_operand" "")))] @@ -57,6 +59,26 @@ "" "ffs $0,$,%1,%0") +;; Our FFS hardware instruction supports any field width, +;; so handle narrower inputs directly as well. +(define_peephole2 + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) + (parallel + [(set (match_operand:SI 2 "nonimmediate_operand") + (ctz:SI (match_dup 0))) + (set (cc0) + (compare (match_dup 2) + (const_int 0)))])] + "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])" + [(parallel + [(set (match_dup 2) + (ctz:SI (match_dup 1))) + (set (cc0) + (compare (match_dup 1) + (const_int 0)))])] + "") + (define_expand "sync_lock_test_and_set" [(match_operand:VAXint 0 "nonimmediate_operand" "=&g") (match_operand:VAXint 1 "memory_operand" "+m") diff --git a/gcc/testsuite/gcc.target/vax/ctzhi.c b/gcc/testsuite/gcc.target/vax/ctzhi.c new file mode 100644 index 0000000..fcc9f06 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/ctzhi.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (HI))) int_t; + +int +ctzhi (int_t *x) +{ + return __builtin_ctz (*x); +} + +/* Expect assembly like: + + ffs $0,$16,*4(%ap),%r0 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler "\tffs \\\$0,\\\$16," } } */ diff --git a/gcc/testsuite/gcc.target/vax/ctzqi.c b/gcc/testsuite/gcc.target/vax/ctzqi.c new file mode 100644 index 0000000..067334b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/ctzqi.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (QI))) int_t; + +int +ctzqi (int_t *x) +{ + return __builtin_ctz (*x); +} + +/* Expect assembly like: + + ffs $0,$8,*4(%ap),%r0 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler "\tffs \\\$0,\\\$8," } } */ diff --git a/gcc/testsuite/gcc.target/vax/ffshi.c b/gcc/testsuite/gcc.target/vax/ffshi.c new file mode 100644 index 0000000..db592fb --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/ffshi.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +int +ffshi (int_t *x) +{ + return __builtin_ffs (*x); +} + +/* Expect assembly like: + + ffs $0,$16,*4(%ap),%r0 + jneq .L2 + mnegl $1,%r0 +.L2: + incl %r0 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler "\tffs \\\$0,\\\$16," } } */ diff --git a/gcc/testsuite/gcc.target/vax/ffsqi.c b/gcc/testsuite/gcc.target/vax/ffsqi.c new file mode 100644 index 0000000..ebcd946 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/ffsqi.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +int +ffsqi (int_t *x) +{ + return __builtin_ffs (*x); +} + +/* Expect assembly like: + + ffs $0,$8,*4(%ap),%r0 + jneq .L2 + mnegl $1,%r0 +.L2: + incl %r0 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler "\tffs \\\$0,\\\$8," } } */ -- cgit v1.1 From 2c45dc7928697c047c1ef5de710e9b0fd108de57 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Add a test for the `cpymemhi' instruction gcc/testsuite/ * gcc.target/vax/cpymem.c: New test. --- gcc/testsuite/gcc.target/vax/cpymem.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.target/vax/cpymem.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/vax/cpymem.c b/gcc/testsuite/gcc.target/vax/cpymem.c new file mode 100644 index 0000000..91805a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cpymem.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +#include + +void * +memcpy8 (void *to, const void *from, size_t size) +{ + unsigned char s8 = size; + return __builtin_memcpy (to, from, s8); +} + +/* Expect assembly like: + + movl 4(%ap),%r6 + movzbl 12(%ap),%r7 + movl 8(%ap),%r8 + movc3 %r7,(%r8),(%r6) + movl %r6,%r0 + + */ + +/* { dg-final { scan-assembler "\tmovc3 " } } */ -- cgit v1.1 From e93fbce844dd055da73e730ecc639ff797ba4518 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Add the `movmemhi' instruction The MOVC3 machine instruction has `memmove' semantics[1]: "The operation of the instruction is such that overlap of the source and destination strings does not affect the result." so use it to provide the `movmemhi' instruction as well. References: [1] DEC STD 032-0 "VAX Architecture Standard", Digital Equipment Corporation, A-DS-EL-00032-00-0 Rev J, December 15, 1989, Section 3.10 "Character-String Instructions", p. 3-162 gcc/ * config/vax/vax.md (cpymemhi1): Rename insn to... (movmemhi1): ... this. (cpymemhi): Update accordingly. Remove constraints. (movmemhi): New expander. gcc/testsuite/ * gcc.target/vax/movmem.c: New test. --- gcc/config/vax/vax.md | 24 ++++++++++++++++++------ gcc/testsuite/gcc.target/vax/movmem.c | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/vax/movmem.c (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 66f03df..f8e1c2e 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -206,16 +206,28 @@ }") ;; This is here to accept 4 arguments and pass the first 3 along -;; to the cpymemhi1 pattern that really does the work. +;; to the movmemhi1 pattern that really does the work. (define_expand "cpymemhi" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) - (use (match_operand:HI 2 "general_operand" "g")) + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:HI 2 "general_operand" "")) + (match_operand 3 "" "")] + "" + " +{ + emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2])); + DONE; +}") + +(define_expand "movmemhi" + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:HI 2 "general_operand" "")) (match_operand 3 "" "")] "" " { - emit_insn (gen_cpymemhi1 (operands[0], operands[1], operands[2])); + emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2])); DONE; }") @@ -224,7 +236,7 @@ ;; that anything generated as this insn will be recognized as one ;; and that it won't successfully combine with anything. -(define_insn "cpymemhi1" +(define_insn "movmemhi1" [(set (match_operand:BLK 0 "memory_operand" "=o") (match_operand:BLK 1 "memory_operand" "o")) (use (match_operand:HI 2 "general_operand" "g")) diff --git a/gcc/testsuite/gcc.target/vax/movmem.c b/gcc/testsuite/gcc.target/vax/movmem.c new file mode 100644 index 0000000..b907d8a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/movmem.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +#include + +void * +memmove8 (void *to, const void *from, size_t size) +{ + unsigned char s8 = size; + return __builtin_memmove (to, from, s8); +} + +/* Expect assembly like: + + movl 4(%ap),%r6 + movzbl 12(%ap),%r7 + movl 8(%ap),%r8 + movc3 %r7,(%r8),(%r6) + movl %r6,%r0 + + */ + +/* { dg-final { scan-assembler "\tmovc3 " } } */ -- cgit v1.1 From 4c293413ca53ffa890e369af33db94264493d140 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns It makes no sense for insn operand predicates, as long as they accept a register operand, to be more restrictive than the set of the associated constraints, because expand will choose the insn based on the relevant operand being a pseudo register then and reload keep it happily as a memory reference if a constraint permits it. So the restriction posed by such a predicate will be happily ignored, and moreover if a splitter is added, such as required for MODE_CC support, the new instructions will reject the original operands supplied, causing an ICE. An actual example will be given with a subsequent change. Remove such inconsistencies we have with the EXTV/EXTZV/INSV insns then, observing that a bit-field located in memory is byte-addressed by the respective machine instructions and therefore SImode may only be used with a register or an offsettable memory operand (i.e. not an indexed, pre-decremented, or post-incremented one), which has already been taken into account with the constraints currently used, except for `*insv_2'. The QI machine mode may be used for the bit-field location with any kind of memory operand, but we got the constraint wrong, although harmlessly in reality, with `*insv'. Fix that for consistency though. Also give the insns names, for easier reference here and elsewhere. gcc/ * config/vax/vax.md (*insv_aligned, *extzv_aligned) (*extv_aligned, *extv_non_const, *extzv_non_const): Name insns. Fix location predicate. (*extzv): Name insn. (*insv): Likewise. Fix location constraint. (*insv_2): Likewise, and the predicate. --- gcc/config/vax/vax.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index f8e1c2e..de90848 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -757,8 +757,8 @@ ;; These handle aligned 8-bit and 16-bit fields, ;; which can usually be done with move instructions. -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro") +(define_insn "*insv_aligned" + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") (match_operand:QI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (match_operand:SI 3 "general_operand" "g"))] @@ -786,9 +786,9 @@ return \"movw %3,%0\"; }") -(define_insn "" +(define_insn "*extzv_aligned" [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") - (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) @@ -814,9 +814,9 @@ return \"movzwl %1,%0\"; }") -(define_insn "" +(define_insn "*extv_aligned" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) @@ -842,7 +842,7 @@ return \"cvtwl %1,%0\"; }") -;; Register-only SImode cases of bit-field insns. +;; Register and non-offsettable-memory SImode cases of bit-field insns. (define_insn "" [(set (cc0) @@ -869,9 +869,9 @@ ;; by a bicl or sign extension. Because we might end up choosing ext[z]v ;; anyway, we can't allow immediate values for the primary source operand. -(define_insn "" +(define_insn "*extv_non_const" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" @@ -886,9 +886,9 @@ return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; }") -(define_insn "" +(define_insn "*extzv_non_const" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" @@ -962,7 +962,7 @@ "" "") -(define_insn "" +(define_insn "*extzv" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") @@ -1015,8 +1015,8 @@ "" "") -(define_insn "" - [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g") +(define_insn "*insv" + [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT"))] @@ -1046,8 +1046,8 @@ return \"insv %3,%2,%1,%0\"; }") -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") +(define_insn "*insv_2" + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT"))] -- cgit v1.1 From 8a8de7507e1cfa2e7a16940a1ad93eb339258042 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns The INSV machine instruction is the only computational operation in the VAX ISA that keeps condition codes intact. In preparation to MODE_CC transition keep patterns apart then that make or do not make use of said instruction. For consistency update EXTV and EXTZV instruction uses accordingly. In expand SUBREGs will be presented as operands, so handle that possibility in the insn condition. This actually yields better code by avoiding EXTV/EXTZV instructions in pseudo-aligned register cases previously resorting to those instructions: @@ -42,7 +42,7 @@ ins8: subl2 $4,%sp # 21 [c=32] addsi3 movl 4(%ap),%r0 # 2 [c=16] movsi_2 movl 8(%ap),%r1 # 17 [c=16] movsi_2 - insv %r1,$8,$8,%r0 # 9 [c=4] *insv_aligned + insv %r1,$8,$8,%r0 # 9 [c=4] *insv_2 ret # 25 [c=0] return .size ins8, .-ins8 .align 1 @@ -60,12 +60,12 @@ ext8: .globl extz8 .type extz8, @function extz8: - .word 0 # 19 [c=0] procedure_entry_mask - subl2 $4,%sp # 20 [c=32] addsi3 + .word 0 # 18 [c=0] procedure_entry_mask + subl2 $4,%sp # 19 [c=32] addsi3 movl 4(%ap),%r0 # 2 [c=16] movsi_2 - extzv $8,$8,%r0,%r1 # 13 [c=60] *extzv_aligned - movl %r1,%r0 # 18 [c=4] movsi_2 - ret # 24 [c=0] return + rotl $24,%r0,%r0 # 13 [c=60] *extzv_non_const + movzbl %r0,%r0 + ret # 23 [c=0] return .size extz8, .-extz8 .align 1 .globl ins16 @@ -75,7 +75,7 @@ ins16: subl2 $4,%sp # 21 [c=32] addsi3 movl 4(%ap),%r0 # 2 [c=16] movsi_2 movl 8(%ap),%r1 # 17 [c=16] movsi_2 - insv %r1,$16,$16,%r0 # 9 [c=4] *insv_aligned + insv %r1,$16,$16,%r0 # 9 [c=4] *insv_2 ret # 25 [c=0] return .size ins16, .-ins16 .align 1 @@ -94,8 +94,9 @@ ext16: extz16: .word 0 # 18 [c=0] procedure_entry_mask subl2 $4,%sp # 19 [c=32] addsi3 - movl 4(%ap),%r1 # 2 [c=16] movsi_2 - extzv $16,$16,%r1,%r0 # 7 [c=60] *extzv_aligned + movl 4(%ap),%r0 # 2 [c=16] movsi_2 + rotl $16,%r0,%r0 # 7 [c=60] *extzv_non_const + movzwl %r0,%r0 movzwl %r0,%r0 # 13 [c=4] zero_extendhisi2 ret # 23 [c=0] return .size extz16, .-extz16 demonstrated with this program: typedef struct { int f0:1; int f1:7; int f8:8; int f16:16; } bit_t; typedef struct { unsigned int f0:1; unsigned int f1:7; unsigned int f8:8; unsigned int f16:16; } ubit_t; typedef union { bit_t b; int i; } bit_u; typedef union { ubit_t b; unsigned int i; } ubit_u; int ins1 (bit_u x, int y) { asm volatile ("" : "+r" (x), "+r" (y)); x.b.f1 = y; return x.i; } int ext1 (bit_u x) { asm volatile ("" : "+r" (x)); return x.b.f1; } unsigned int extz1 (ubit_u x) { asm volatile ("" : "+r" (x)); return x.b.f1; } int ins8 (bit_u x, int y) { asm volatile ("" : "+r" (x), "+r" (y)); x.b.f8 = y; return x.i; } int ext8 (bit_u x) { asm volatile ("" : "+r" (x)); return x.b.f8; } unsigned int extz8 (ubit_u x) { asm volatile ("" : "+r" (x)); return x.b.f8; } int ins16 (bit_u x, int y) { asm volatile ("" : "+r" (x), "+r" (y)); x.b.f16 = y; return x.i; } int ext16 (bit_u x) { asm volatile ("" : "+r" (x)); return x.b.f16; } unsigned int extz16 (ubit_u x) { asm volatile ("" : "+r" (x)); return x.b.f16; } It also papers over a regression: FAIL: gcc.dg/pr83623.c (internal compiler error) FAIL: gcc.dg/pr83623.c (test for excess errors) from an ICE like: during RTL pass: final .../gcc/testsuite/gcc.dg/pr83623.c: In function 'foo': .../gcc/testsuite/gcc.dg/pr83623.c:13:1: internal compiler error: in change_address_1, at emit-rtl.c:2275 0x10a056e3 change_address_1 .../gcc/emit-rtl.c:2275 0x10a0645f adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>) .../gcc/emit-rtl.c:2409 0x11cb588f output_97 .../gcc/config/vax/vax.md:808 0x10aafb2f get_insn_template(int, rtx_insn*) .../gcc/final.c:2070 0x10ab2b3f final_scan_insn_1 .../gcc/final.c:3039 0x10ab313b final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*) .../gcc/final.c:3152 0x10aaf887 final_1 .../gcc/final.c:2020 0x10ab703b rest_of_handle_final .../gcc/final.c:4658 0x10ab757b execute .../gcc/final.c:4736 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See for instructions. compiler exited with status 1 FAIL: gcc.dg/pr83623.c (internal compiler error) triggered by an RTL instruction like: (insn 17 14 145 (set (reg:SI 1 %r1) (zero_extract:SI (mem/c:SI (symbol_ref:SI ("x") ) [1 x+0 S4 A128]) (const_int 16 [0x10]) (const_int 16 [0x10]))) ".../gcc/testsuite/gcc.dg/pr83623.c":12:9 97 {*extzv_aligned} (nil)) (where the address cannot be adjusted by 2 for PIC code as requested here as it would create an offset external symbol reference) otherwise caused by the patterns modified here, addressed next. This indicates a further rework is warranted here, but at least problems at hand have been fixed. gcc/ * config/vax/vax.md (*insv_aligned, *extzv_aligned) (*extv_aligned): Reject register bit-field locations that are not aligned to the least significant bit; update output statement accordingly. --- gcc/config/vax/vax.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index de90848..80f09d9 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -754,8 +754,8 @@ ;; Special cases of bit-field insns which we should ;; recognize in preference to the general case. -;; These handle aligned 8-bit and 16-bit fields, -;; which can usually be done with move instructions. +;; These handle aligned 8-bit and 16-bit fields +;; that can be done with move or convert instructions. (define_insn "*insv_aligned" [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") @@ -766,19 +766,19 @@ && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 && (!MEM_P (operands[0]) || ! mode_dependent_address_p (XEXP (operands[0], 0), - MEM_ADDR_SPACE (operands[0])))" + MEM_ADDR_SPACE (operands[0]))) + && (!(REG_P (operands[0]) + || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0])))) + || INTVAL (operands[2]) == 0)" "* { - if (REG_P (operands[0])) - { - if (INTVAL (operands[2]) != 0) - return \"insv %3,%2,%1,%0\"; - } - else + if (!REG_P (operands[0])) operands[0] = adjust_address (operands[0], INTVAL (operands[1]) == 8 ? QImode : HImode, INTVAL (operands[2]) / 8); + else + gcc_assert (INTVAL (operands[2]) == 0); CC_STATUS_INIT; if (INTVAL (operands[1]) == 8) @@ -795,19 +795,19 @@ && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (!MEM_P (operands[1]) || ! mode_dependent_address_p (XEXP (operands[1], 0), - MEM_ADDR_SPACE (operands[1])))" + MEM_ADDR_SPACE (operands[1]))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0)" "* { - if (REG_P (operands[1])) - { - if (INTVAL (operands[3]) != 0) - return \"extzv %3,%2,%1,%0\"; - } - else + if (!REG_P (operands[1])) operands[1] = adjust_address (operands[1], INTVAL (operands[2]) == 8 ? QImode : HImode, INTVAL (operands[3]) / 8); + else + gcc_assert (INTVAL (operands[3]) == 0); if (INTVAL (operands[2]) == 8) return \"movzbl %1,%0\"; @@ -823,19 +823,19 @@ && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (!MEM_P (operands[1]) || ! mode_dependent_address_p (XEXP (operands[1], 0), - MEM_ADDR_SPACE (operands[1])))" + MEM_ADDR_SPACE (operands[1]))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0)" "* { - if (REG_P (operands[1])) - { - if (INTVAL (operands[3]) != 0) - return \"extv %3,%2,%1,%0\"; - } - else + if (!REG_P (operands[1])) operands[1] = adjust_address (operands[1], INTVAL (operands[2]) == 8 ? QImode : HImode, INTVAL (operands[3]) / 8); + else + gcc_assert (INTVAL (operands[3]) == 0); if (INTVAL (operands[2]) == 8) return \"cvtbl %1,%0\"; -- cgit v1.1 From b3f3bba3fa08a3d6b254071c10abd941d57bf0b9 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Ensure PIC mode address is adjustable with aligned bit-field insns With the `*insv_aligned', `*extzv_aligned' and `*extv_aligned' insns we are going to adjust the bit-field location if it is in memory, so only allow such location addresses that can be offset, excluding external symbol references in the PIC mode in particular. This fixes an ICE like: during RTL pass: final In file included from .../gcc/testsuite/gcc.dg/torture/vshuf-v16qi.c:11: .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc: In function 'test_13': .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:27:1: internal compiler error: in change_address_1, at emit-rtl.c:2275 .../gcc/testsuite/gcc.dg/torture/vshuf-16.inc:16:1: note: in expansion of macro 'T' .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:28:1: note: in expansion of macro 'TESTS' 0x10a34b33 change_address_1 .../gcc/emit-rtl.c:2275 0x10a358af adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>) .../gcc/emit-rtl.c:2409 0x11d2505f output_97 .../gcc/config/vax/vax.md:806 0x10adec4b get_insn_template(int, rtx_insn*) .../gcc/final.c:2070 0x10ae1c5b final_scan_insn_1 .../gcc/final.c:3039 0x10ae2257 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*) .../gcc/final.c:3152 0x10ade9a3 final_1 .../gcc/final.c:2020 0x10ae6157 rest_of_handle_final .../gcc/final.c:4658 0x10ae6697 execute .../gcc/final.c:4736 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See for instructions. compiler exited with status 1 FAIL: gcc.dg/torture/vshuf-v16qi.c -O2 (internal compiler error) triggered by an RTL instruction like: (insn 97 96 98 (set (reg:SI 5 %r5 [88]) (zero_extract:SI (mem/c:SI (symbol_ref:SI ("b") ) [0 b+0 S4 A128]) (const_int 8 [0x8]) (const_int 24 [0x18]))) ".../gcc/testsuite/gcc.dg/torture/vshuf-main.inc":28:1 97 {*extzv_aligned} (nil)) and removes these regressions: FAIL: gcc.dg/torture/vshuf-v16qi.c -O2 (internal compiler error) FAIL: gcc.dg/torture/vshuf-v16qi.c -O2 (test for excess errors) FAIL: gcc.dg/torture/vshuf-v4hi.c -O2 (internal compiler error) FAIL: gcc.dg/torture/vshuf-v4hi.c -O2 (test for excess errors) FAIL: gcc.dg/torture/vshuf-v8hi.c -O2 (internal compiler error) FAIL: gcc.dg/torture/vshuf-v8hi.c -O2 (test for excess errors) FAIL: gcc.dg/torture/vshuf-v8qi.c -O2 (internal compiler error) FAIL: gcc.dg/torture/vshuf-v8qi.c -O2 (test for excess errors) However expand typically presents pseudo-registers rather than memory references to these insns, so a further rework is required to make a better use of the code variant they are supposed to produce. This at least fixes the problem at hand. gcc/ * config/vax/vax.md (*insv_aligned, *extzv_aligned) (*extv_aligned): Also make sure the memory address of a bit-field location can be adjusted in the PIC mode. --- gcc/config/vax/vax.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 80f09d9..f90ae89 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -762,11 +762,14 @@ (match_operand:QI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (match_operand:SI 3 "general_operand" "g"))] - "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) + "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 && (!MEM_P (operands[0]) - || ! mode_dependent_address_p (XEXP (operands[0], 0), - MEM_ADDR_SPACE (operands[0]))) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[0], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[0], 0), + MEM_ADDR_SPACE (operands[0])))) && (!(REG_P (operands[0]) || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0])))) || INTVAL (operands[2]) == 0)" @@ -794,8 +797,11 @@ "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (!MEM_P (operands[1]) - || ! mode_dependent_address_p (XEXP (operands[1], 0), - MEM_ADDR_SPACE (operands[1]))) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) && (!(REG_P (operands[1]) || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) || INTVAL (operands[3]) == 0)" @@ -822,8 +828,11 @@ "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (!MEM_P (operands[1]) - || ! mode_dependent_address_p (XEXP (operands[1], 0), - MEM_ADDR_SPACE (operands[1]))) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) && (!(REG_P (operands[1]) || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) || INTVAL (operands[3]) == 0)" -- cgit v1.1 From 0a9ea215f7400612f6dae2c77351e503798ea599 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Make `extv' an expander matching the remaining bit-field operations We have matching insns defined for `sign_extract' and `zero_extract' expressions, so make the three named patterns for bit-field operations consistent and make `extv' an expander rather than an insn taking a SImode, a QImode, and a SImode general operand for the LOC, SIZE, and POS operands respectively, like with the `extzv' and `insv' patterns, matching the machine instructions and giving the middle end more choice as to which actual insn to choose in a given situation. Given this program: typedef struct { int f0:1; int f1:7; int f8:8; int f16:16; } bit_t; typedef struct { unsigned int f0:1; unsigned int f1:7; unsigned int f8:8; unsigned int f16:16; } ubit_t; typedef union { bit_t b; int i; } bit_u; typedef union { ubit_t b; unsigned int i; } ubit_u; int ins1 (bit_u x, int y) { asm volatile ("" : "+r" (x), "+r" (y)); x.b.f1 = y; return x.i; } int ext1 (bit_u x) { asm volatile ("" : "+r" (x)); return x.b.f1; } unsigned int extz1 (ubit_u x) { asm volatile ("" : "+r" (x)); return x.b.f1; } int ins8 (bit_u x, int y) { asm volatile ("" : "+r" (x), "+r" (y)); x.b.f8 = y; return x.i; } int ext8 (bit_u x) { asm volatile ("" : "+r" (x)); return x.b.f8; } unsigned int extz8 (ubit_u x) { asm volatile ("" : "+r" (x)); return x.b.f8; } int ins16 (bit_u x, int y) { asm volatile ("" : "+r" (x), "+r" (y)); x.b.f16 = y; return x.i; } int ext16 (bit_u x) { asm volatile ("" : "+r" (x)); return x.b.f16; } unsigned int extz16 (ubit_u x) { asm volatile ("" : "+r" (x)); return x.b.f16; } this results in the following code change: @@ -16,12 +16,12 @@ ins1: .globl ext1 .type ext1, @function ext1: - .word 0 # 19 [c=0] procedure_entry_mask - subl2 $4,%sp # 20 [c=32] addsi3 + .word 0 # 18 [c=0] procedure_entry_mask + subl2 $4,%sp # 19 [c=32] addsi3 movl 4(%ap),%r0 # 2 [c=16] movsi_2 - cvtbl %r0,%r0 # 7 [c=4] extendqisi2 - ashl $-1,%r0,%r0 # 14 [c=40] *vax.md:624 - ret # 24 [c=0] return + extv $1,$7,%r0,%r0 # 7 [c=60] *extv_non_const + cvtbl %r0,%r0 # 13 [c=4] extendqisi2 + ret # 23 [c=0] return .size ext1, .-ext1 .align 1 .globl extz1 @@ -49,12 +49,12 @@ ins8: .globl ext8 .type ext8, @function ext8: - .word 0 # 20 [c=0] procedure_entry_mask - subl2 $4,%sp # 21 [c=32] addsi3 + .word 0 # 18 [c=0] procedure_entry_mask + subl2 $4,%sp # 19 [c=32] addsi3 movl 4(%ap),%r0 # 2 [c=16] movsi_2 - cvtwl %r0,%r0 # 7 [c=4] extendhisi2 - ashl $-8,%r0,%r0 # 15 [c=40] *vax.md:624 - ret # 25 [c=0] return + rotl $24,%r0,%r0 # 13 [c=60] *extv_non_const + cvtbl %r0,%r0 + ret # 23 [c=0] return .size ext8, .-ext8 .align 1 .globl extz8 If there is a performance degradation with the replacement sequences, then it can and should be sorted within `extv_non_const'. gcc/ * config/vax/vax.md (extv): Rename insn to... (*extv): ... this. (extv): New expander. --- gcc/config/vax/vax.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index f90ae89..d8774cd 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -941,7 +941,15 @@ "" "cmpzv %2,%1,%0,%3") -(define_insn "extv" +(define_expand "extv" + [(set (match_operand:SI 0 "general_operand" "") + (sign_extract:SI (match_operand:SI 1 "general_operand" "") + (match_operand:QI 2 "general_operand" "") + (match_operand:SI 3 "general_operand" "")))] + "" + "") + +(define_insn "*extv" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") -- cgit v1.1 From d38f8441bed01127358d46196aea2a2f55d0c949 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Fix predicates and constraints for bit-field comparison insns It makes no sense for insn operand predicates, as long as they accept a register operand, to be more restrictive than the set of the associated constraints, because expand will choose the insn based on the relevant operand being a pseudo register then and reload keep it happily as a memory reference if a constraint permits it. So the restriction posed by such a predicate will be happily ignored, and moreover if a splitter is added, such as required for MODE_CC support, the new instructions will reject the original operands supplied, causing an ICE. An actual example will be given with a subsequent change. Therefore, similarly to EXTV/EXTZV/INSV insns, remove inconsistencies with predicates and constraints of bit-field comparison insns, observing that a bit-field located in memory is byte-addressed by the respective machine instructions and therefore SImode may only be used with a register or an offsettable memory operand (i.e. not an indexed, pre-decremented, or post-incremented one). Also give the insns names, for easier reference here and elsewhere. gcc/ * config/vax/vax.md (*cmpv_2): Name insn. (*cmpv, *cmpzv, *cmpzv_2): Likewise. Fix location predicate and constraint. --- gcc/config/vax/vax.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index d8774cd..34fdf67 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -853,20 +853,20 @@ ;; Register and non-offsettable-memory SImode cases of bit-field insns. -(define_insn "" +(define_insn "*cmpv" [(set (cc0) (compare - (sign_extract:SI (match_operand:SI 0 "register_operand" "r") + (sign_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] "" "cmpv %2,%1,%0,%3") -(define_insn "" +(define_insn "*cmpzv" [(set (cc0) (compare - (zero_extract:SI (match_operand:SI 0 "register_operand" "r") + (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] @@ -921,7 +921,7 @@ ;; nonimmediate_operand is used to make sure that mode-ambiguous cases ;; don't match these (and therefore match the cases above instead). -(define_insn "" +(define_insn "*cmpv_2" [(set (cc0) (compare (sign_extract:SI (match_operand:QI 0 "memory_operand" "m") @@ -931,10 +931,10 @@ "" "cmpv %2,%1,%0,%3") -(define_insn "" +(define_insn "*cmpzv_2" [(set (cc0) (compare - (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") + (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] -- cgit v1.1 From 2b39f5137a9db4939fd23d39de63257467986f80 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Fix predicates for widening multiply and multiply-add insns It makes no sense for insn operand predicates, as long as they accept a register operand, to be more restrictive than the set of the associated constraints, because expand will choose the insn based on the relevant operand being a pseudo register then and reload will keep it happily as an immediate if a constraint permits it. So the restriction posed by such a predicate will be happily ignored, and moreover if a splitter is added, such as required for MODE_CC support, the new instructions will reject the original operands supplied, causing an ICE like below: .../gcc/testsuite/gfortran.dg/graphite/PR67518.f90:44:0: Error: could not split insn (insn 90 662 663 (set (reg:DI 10 %r10 [orig:97 _235 ] [97]) (mult:DI (sign_extend:DI (mem/c:SI (plus:SI (reg/f:SI 13 %fp) (const_int -800 [0xfffffffffffffce0])) [14 %sfp+-800 S4 A32])) (sign_extend:DI (const_int -51 [0xffffffffffffffcd])))) 299 {mulsidi3} (expr_list:REG_EQUAL (mult:DI (sign_extend:DI (subreg:SI (mem/c:DI (plus:SI (reg/f:SI 13 %fp) (const_int -800 [0xfffffffffffffce0])) [14 %sfp+-800 S8 A32]) 0)) (const_int -51 [0xffffffffffffffcd])) (nil))) during RTL pass: final .../gcc/testsuite/gfortran.dg/graphite/PR67518.f90:44:0: internal compiler error: in final_scan_insn_1, at final.c:3073 Please submit a full bug report, with preprocessed source if appropriate. See for instructions. Change the predicates used with the widening multiply and multiply-add insns to allow immediates then, just as the constraints and the machine instructions produced permit. Also give the insns names, for easier reference here and elsewhere. gcc/ * config/vax/vax.md (mulsidi3): Fix the multiplicand predicates. (*maddsidi4, *maddsidi4_const): Likewise. Name insns. --- gcc/config/vax/vax.md | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 34fdf67..2f6643a 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -445,35 +445,32 @@ (define_insn "mulsidi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") - (mult:DI (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "nrmT")) - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))] + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))] "" "emul %1,%2,$0,%0") -(define_insn "" +(define_insn "*maddsidi4" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI - (mult:DI (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "nrmT")) - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "nrmT"))) - (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))] + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (sign_extend:DI (match_operand:SI 3 "general_operand" "g"))))] "" "emul %1,%2,%3,%0") ;; 'F' constraint means type CONST_DOUBLE -(define_insn "" +(define_insn "*maddsidi4_const" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI - (mult:DI (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "nrmT")) - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "nrmT"))) - (match_operand:DI 3 "immediate_operand" "F")))] + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (match_operand:DI 3 "immediate_operand" "F")))] "GET_CODE (operands[3]) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" + && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" "* { if (CONST_DOUBLE_HIGH (operands[3])) -- cgit v1.1 From 3c085897738b0da9c199eda2476c2563bdbdb292 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Correct issues with commented-out insns Correct issues with commented-out insns, which fail to build if enabled: .../gcc/config/vax/vax.md:503:1: repeated operand number 1 .../gcc/config/vax/vax.md:503:1: repeated operand number 2 and then when the issue with the repeated operands has been corrected: .../gcc/config/vax/vax.md:107:1: destination operand 0 allows non-lvalue .../gcc/config/vax/vax.md:503:1: destination operand 0 allows non-lvalue .../gcc/config/vax/vax.md:503:1: destination operand 3 allows non-lvalue .../gcc/config/vax/vax.md:744:1: destination operand 0 allows non-lvalue Fix the RTL with the repeated operands and change the relevant output operand predicates not to allow immediates. Also emit MOVO rather than MOVH assembly instruction with the `movti' insn so that the condition codes are set according to the integer rather than floating-point interpretation of the datum moved, as expected with the operation associated with the pattern. Finally give `*amulsi4' a name, for easier reference here and elsewhere. We may eventually want to have some of these insns enabled at `-Os'. gcc/ * config/vax/vax.md (movti): Fix output predicate. Emit `movo' rather than `movh'. (divmoddisi4): Fix output predicates, correct RTL. (*amulsi4): Name insn. Fix output predicate. --- gcc/config/vax/vax.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 2f6643a..4b0c26d 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -105,10 +105,10 @@ ;; Some VAXen don't support this instruction. ;;(define_insn "movti" -;; [(set (match_operand:TI 0 "general_operand" "=g") +;; [(set (match_operand:TI 0 "nonimmediate_operand" "=g") ;; (match_operand:TI 1 "general_operand" "g"))] ;; "" -;; "movh %1,%0") +;; "movo %1,%0") (define_insn "movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") @@ -501,12 +501,12 @@ ;This is left out because it is very slow; ;we are better off programming around the "lack" of this insn. ;(define_insn "divmoddisi4" -; [(set (match_operand:SI 0 "general_operand" "=g") +; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") ; (div:SI (match_operand:DI 1 "general_operand" "g") ; (match_operand:SI 2 "general_operand" "g"))) -; (set (match_operand:SI 3 "general_operand" "=g") -; (mod:SI (match_operand:DI 1 "general_operand" "g") -; (match_operand:SI 2 "general_operand" "g")))] +; (set (match_operand:SI 3 "nonimmediate_operand" "=g") +; (mod:SI (match_dup 1) +; (match_dup 2)))] ; "" ; "ediv %2,%1,%0,%3") @@ -741,8 +741,8 @@ "rotl %2,%1,%0") ;This insn is probably slower than a multiply and an add. -;(define_insn "" -; [(set (match_operand:SI 0 "general_operand" "=g") +;(define_insn "*amulsi4" +; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") ; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") ; (match_operand:SI 2 "general_operand" "g")) ; (match_operand:SI 3 "general_operand" "g")))] -- cgit v1.1 From 1be9edfa826f2c7c7a999ff02defab97d468d277 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent Use a double colon to introduce the comments like elsewhere throughout the VAX machine description. gcc/ * config/vax/vax.md (divmoddisi4, *amulsi4): Make the comment notation consistent with the rest of the file. --- gcc/config/vax/vax.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 4b0c26d..1bb4e30 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -498,17 +498,17 @@ div2 %2,%0 div3 %2,%1,%0") -;This is left out because it is very slow; -;we are better off programming around the "lack" of this insn. -;(define_insn "divmoddisi4" -; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") -; (div:SI (match_operand:DI 1 "general_operand" "g") -; (match_operand:SI 2 "general_operand" "g"))) -; (set (match_operand:SI 3 "nonimmediate_operand" "=g") -; (mod:SI (match_dup 1) -; (match_dup 2)))] -; "" -; "ediv %2,%1,%0,%3") +;; This is left out because it is very slow; +;; we are better off programming around the "lack" of this insn. +;;(define_insn "divmoddisi4" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (div:SI (match_operand:DI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g"))) +;; (set (match_operand:SI 3 "nonimmediate_operand" "=g") +;; (mod:SI (match_dup 1) +;; (match_dup 2)))] +;; "" +;; "ediv %2,%1,%0,%3") ;; Bit-and on the VAX is done with a clear-bits insn. (define_expand "and3" @@ -740,14 +740,14 @@ "" "rotl %2,%1,%0") -;This insn is probably slower than a multiply and an add. -;(define_insn "*amulsi4" -; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") -; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") -; (match_operand:SI 2 "general_operand" "g")) -; (match_operand:SI 3 "general_operand" "g")))] -; "" -; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") +;; This insn is probably slower than a multiply and an add. +;;(define_insn "*amulsi4" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g")) +;; (match_operand:SI 3 "general_operand" "g")))] +;; "" +;; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") ;; Special cases of bit-field insns which we should ;; recognize in preference to the general case. -- cgit v1.1 From 20ab43b5cad6ac69a70b01489be0adf98bd421ba Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: RTL: Add `const_double_zero' syntactic rtx The use of a constant double zero is required for post-reload compare elimination to be able to discard redundant floating-point comparisons, for example with a VAX RTL instruction stream like: (insn 34 4 3 2 (parallel [ (set (reg/v:DF 0 %r0 [orig:24 x ] [24]) (mem/c:DF (plus:SI (reg/f:SI 12 %ap) (const_int 4 [0x4])) [1 x+0 S8 A32])) (clobber (reg:CC 16 %psl)) ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 37 {*movdf} (nil)) (note 3 34 35 2 NOTE_INSN_FUNCTION_BEG) (insn 35 3 36 2 (set (reg:CCZ 16 %psl) (compare:CCZ (reg/v:DF 0 %r0 [orig:24 x ] [24]) (const_double:DF 0.0 [0x0.0p+0]))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 21 {*cmpdf_ccz} (nil)) (jump_insn 36 35 9 2 (set (pc) (if_then_else (eq (reg:CCZ 16 %psl) (const_int 0 [0])) (label_ref 11) (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz} (int_list:REG_BR_PROB 536870916 (nil)) -> 11) that we want to transform into: (insn 34 4 3 2 (parallel [ (set (reg:CCZ 16 %psl) (compare:CCZ (mem/c:DF (plus:SI (reg/f:SI 12 %ap) (const_int 4 [0x4])) [1 x+0 S8 A32]) (const_double:DF 0.0 [0x0.0p+0]))) (set (reg/v:DF 0 %r0 [orig:24 x ] [24]) (mem/c:DF (plus:SI (reg/f:SI 12 %ap) (const_int 4 [0x4])) [1 x+0 S8 A32])) ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 40 {*movdf_ccz} (nil)) (note 3 34 36 2 NOTE_INSN_FUNCTION_BEG) (jump_insn 36 3 9 2 (set (pc) (if_then_else (eq (reg:CCZ 16 %psl) (const_int 0 [0])) (label_ref 11) (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz} (int_list:REG_BR_PROB 536870916 (nil)) -> 11) with the upcoming MODE_CC representation. For this we need to express the `const_double:DF 0.0 [0x0.0p+0]' rtx as recorded above in the relevant pattern(s) in machine description. The way we represent double constants, as a host-dependent number of wide integers, however means that we currently have no portable way to encode a double zero constant in machine description. Define a syntactic rtx alias then to represent `(const_double 0 0 ...)' as if the suitable number of zeros have been supplied according to the host-specific definition of CONST_DOUBLE_FORMAT. gcc/ * read-rtl.c (rtx_reader::read_rtx_code): Handle syntactic `const_double_zero' rtx. * doc/rtl.texi (Constant Expression Types): Document it. --- gcc/doc/rtl.texi | 18 ++++++++++++++++++ gcc/read-rtl.c | 10 ++++++++++ 2 files changed, 28 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 4f9b990..7c12991 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -1711,6 +1711,24 @@ machine's or host machine's floating point format. To convert them to the precise bit pattern used by the target machine, use the macro @code{REAL_VALUE_TO_TARGET_DOUBLE} and friends (@pxref{Data Output}). +@findex const_double_zero +The host dependency for the number of integers used to store a double +value makes it problematic for machine descriptions to use expressions +of code @code{const_double} and therefore a syntactic alias has been +provided: + +@smallexample +(const_double_zero) +@end smallexample + +standing for: + +@smallexample +(const_double 0 0 @dots{}) +@end smallexample + +for matching the floating-point value zero, possibly the only useful one. + @findex CONST_WIDE_INT @item (const_wide_int:@var{m} @var{nunits} @var{elt0} @dots{}) This contains an array of @code{HOST_WIDE_INT}s that is large enough diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 403f254..2922af5 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -1651,6 +1651,16 @@ rtx_reader::read_rtx_code (const char *code_name) return return_rtx; } + /* Handle "const_double_zero". */ + if (strcmp (code_name, "const_double_zero") == 0) + { + code = CONST_DOUBLE; + return_rtx = rtx_alloc (code); + memset (return_rtx, 0, RTX_CODE_SIZE (code)); + PUT_CODE (return_rtx, code); + return return_rtx; + } + /* If we end up with an insn expression then we free this space below. */ return_rtx = rtx_alloc_for_name (code_name); code = GET_CODE (return_rtx); -- cgit v1.1 From c60d0736dff72af730261483945b1a7cfd2a0021 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:27 +0000 Subject: PDP11: Use `const_double_zero' to express double zero constant We do not define a comparison operation between floating-point and integer data, including integer zero constant. Consequently the RTL instruction stream presented to the post-reload comparison elimination pass will include, where applicable, floating-point comparison insns against `const_double:DF 0.0 [0x0.0p+0]' rather than `const_int 0 [0]', meaning that the latter expression will not match when used in machine description. Use `const_double_zero' then for the relevant patterns to match the intended RTL instructions. gcc/ * config/pdp11/pdp11.md (fcc_cc, fcc_ccnz): Use `const_double_zero' to express double zero constant. --- gcc/config/pdp11/pdp11.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index 7a4d50f..cdef49f 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -105,7 +105,7 @@ (clobber (reg FCC_REGNUM))] "" [(set (reg:CC FCC_REGNUM) - (compare:CC (match_dup 1) (const_int 0))) + (compare:CC (match_dup 1) (const_double_zero))) (set (match_dup 0) (match_dup 1))]) (define_subst "fcc_ccnz" @@ -113,7 +113,7 @@ (clobber (reg FCC_REGNUM))] "" [(set (reg:CCNZ FCC_REGNUM) - (compare:CCNZ (match_dup 1) (const_int 0))) + (compare:CCNZ (match_dup 1) (const_double_zero))) (set (match_dup 0) (match_dup 1))]) (define_subst_attr "cc_cc" "cc_cc" "_nocc" "_cc") -- cgit v1.1 From 76a553587f3181605c57801c37b0d3e94ce3aca5 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:27 +0000 Subject: VAX: Fix the LTO compiler downgrading code to non-PIC model Fix a testsuite failure: /tmp/ccL65Mmt.s: Assembler messages: /tmp/ccL65Mmt.s:36: Warning: Symbol n used as immediate operand in PIC mode. FAIL: gcc.dg/lto/pr55660 c_lto_pr55660_0.o-c_lto_pr55660_1.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin where non-PIC code is substituted by the LTO compiler at the link stage for what used to be PIC code in the original compilation. This happens because in the de-facto VAX ELF psABI we rely on code being PIC for GOT support in dynamic executables and arrange that by having `-fPIC' passed to the compiler by default by means of a specs recipe. That is however canceled where the LTO wrapper is used, by an internal arrangement in the LTO compiler that clears the PIC flag whenever the `-flinker-output=exec' option has been used. This has been deliberately introduced with commit 1ff9ed6fb282 ("re PR lto/67548 (LTO drops weak binding with "ld -r")")[1]: "In the log of PR67548 HJ actually pointed out that we do have API at linker plugin side which says what type of output is done. This is cool because we can also use it to drop -fpic when building static binary. This is common in Firefox, where some objects are built with -fpic and linked to both binaries and libraries." with this code: case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */ flag_pic = 0; flag_pie = 0; flag_shlib = 0; break; Consequently code like: .L6: addl3 -8(%fp),$n,%r0 pushl %r0 calls $1,foo addl2 %r0,-12(%fp) incl -8(%fp) .L5: is produced by the LTO compiler, where a reference to `n' is used that is invalid in PIC code, because it uses the immediate addressing mode, denoted by the `$' prefix. For that not to happen we must never pass `-flinker-output=exec' to the LTO compiler unless non-PIC code has been explicitly requested. Using `-flinker-output=dyn' except for relocatable output would seem the simplest approach, as it does not fiddle with any of the internal code model settings beyond what the command-line options have arranged and therefore lets them remain the same as with the original compilation, but it breaks as well causing PR lto/69866 to retrigger, as that code seems sensitive to `flag_shlib': lto1: internal compiler error: in add_symbol_to_partition_1, at lto/lto-partition.c:152 0x105be1cb add_symbol_to_partition_1 .../gcc/lto/lto-partition.c:152 0x105be443 add_symbol_to_partition_1 .../gcc/lto/lto-partition.c:194 0x105be80f add_symbol_to_partition .../gcc/lto/lto-partition.c:270 0x105bee6f add_sorted_nodes .../gcc/lto/lto-partition.c:395 0x105c0903 lto_balanced_map(int, int) .../gcc/lto/lto-partition.c:815 0x105aa91f do_whole_program_analysis .../gcc/lto/lto.c:499 0x105aac97 lto_main() .../gcc/lto/lto.c:637 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See for instructions. lto-wrapper: fatal error: .../gcc/xgcc returned 1 exit status compilation terminated. .../usr/bin/vax-netbsdelf-ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status compiler exited with status 1 FAIL: gcc.dg/lto/pr69866 c_lto_pr69866_0.o-c_lto_pr69866_1.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) Substitute `-flinker-output=pie' for `-flinker-output=exec' in the specs then unless `-no-pie' has also been used, preserving the original intent of emitting PIC code by default for executables while keeping the linker arrangement unchanged. The LTO compiler uses the `cc1' spec, so keep `cc1plus' unmodified. This makes code like: .L6: movab n,%r0 addl2 -8(%fp),%r0 pushl %r0 calls $1,foo addl2 %r0,-12(%fp) incl -8(%fp) .L5: be produced instead corresponding to the fragment quoted above, which is valid PIC code as it uses the PC-relative addressing mode denoted by the absence of a prefix to `n' (which can be redirected to GOT as required, by changing the addressing mode to PC-relative indirect in the operand specifier). Ideally we would instead default to the PIE model for executables, but that triggers a BFD bug where for a change the LTO wrapper is not used: .../usr/bin/vax-netbsdelf-ld: /tmp/ccV2sWQt.ltrans0.ltrans.o: warning: GOT addend of 3 to `n' does not match previous GOT addend of 0 FAIL: gcc.dg/lto/pr55660 c_lto_pr55660_0.o-c_lto_pr55660_1.o link, -O2 -flto -flto-partition=1to1 -fno-use-linker-plugin which is due to assembly code like: main: .word 0 subl2 $4,%sp movab n,%r0 movab n+3,%r2 clrl %r3 movb $98,%r1 .L4: and consequently object code like: 00000000
: 0: 00 00 .word 0x0000 # Entry mask: < > 2: c2 04 5e subl2 $0x4,sp 5: 9e ef 00 00 movab b ,r0 9: 00 00 50 7: R_VAX_GOT32 n c: 9e ef 00 00 movab 12 ,r2 10: 00 00 52 e: R_VAX_GOT32 n+0x3 13: d4 53 clrf r3 15: 90 8f 62 51 movb $0x62,r1 being produced. This would be problematic for external `n', because we do not support multiple GOT entries for the same symbol referred to with different offsets in a single link unit. In this case however the LTO compiler correctly observes that `n' is defined by the executable and not preemptible and therefore no GOT entry will be made for it. Indeed a valid executable is produced: 00010548
: 10548: 00 00 .word 0x0000 # Entry mask: < > 1054a: c2 04 5e subl2 $0x4,sp 1054d: 9e ef dd 14 movab 11a30 ,r0 10551: 00 00 50 10554: 9e ef d9 14 movab 11a33 <__bss_start>,r2 10558: 00 00 52 1055b: d4 53 clrf r3 1055d: 90 8f 62 51 movb $0x62,r1 despite the warning, but it would be rather bad to have users annoyed with this message from BFD, however harmless, especially as it triggers outside LTO compilations as well. Therefore this change is the best we can do until binutils have been fixed. References: [1] Jan Hubicka, "Getting LTO incremental linking work", gcc/ * config/vax/elf.h (VAX_CC1_SPEC, VAX_CC1PLUS_SPEC): New macros. * config/vax/netbsd-elf.h (CC1_SPEC): Use VAX_CC1_SPEC rather than VAX_CC1_AND_CC1PLUS_SPEC. (CC1PLUS_SPEC): Use VAX_CC1PLUS_SPEC rather than VAX_CC1_AND_CC1PLUS_SPEC. --- gcc/config/vax/elf.h | 10 ++++++++++ gcc/config/vax/netbsd-elf.h | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/elf.h b/gcc/config/vax/elf.h index 555ccef..530b2c0 100644 --- a/gcc/config/vax/elf.h +++ b/gcc/config/vax/elf.h @@ -89,6 +89,16 @@ along with GCC; see the file COPYING3. If not see %{!fpic: \ %{!fPIC:-fPIC}}}" +/* Don't let the LTO compiler switch the PIC options off. */ +#define VAX_CC1_SPEC \ + VAX_CC1_AND_CC1PLUS_SPEC \ + " %{flinker-output=exec" \ + ":%{no-pie:-flinker-output=exec;:-flinker-output=pie};" \ + ":%{flinker-output=*}}" \ + "% Date: Sat, 5 Dec 2020 18:26:27 +0000 Subject: PR target/95294: VAX: Convert backend to MODE_CC representation In the VAX ISA INSV bit-field insert instruction is the only computational operation that keeps the condition codes, held in the PSL or Processor Status Longword register, intact. The instruction is flexible enough it could potentially be used for data moves post-reload, but then reportedly it is not the best choice performance-wise, and then we have no addition operation available that would keep the condition codes unchanged. Futhermore, as usually with a complex CISC ISA, for many operations we have several machine instructions or instruction sequences to choose from that set condition codes in a different manner. Use the approach then where the condition codes only get introduced by reload, by definining instruction splitters for RTL insns that change condition codes in some way, by default considering them clobbered. Then to prevent code generated from regressing too much provide insns that include a `compare' operation setting the condition codes in parallel to the main operation. The manner condition codes are set by each insn is supposed to be provided by the whatever the SELECT_CC_MODE macro expands to. Given that individual patterns provided for the same RTL basic operation may set the condion codes differently keeping the information away from the insn patterns themselves would cause a maintenance nightmare and would be bound to fail in a horrible way sooner or later. Therefore instead let the patterns themselves choose which condition modes they support, by having one or more subst iterators applied and then have individual comparison operators require the specific condition mode each according to the codes used by the operation. While subst iterators only support one alternative each, there is actually no problem with applying multiple ones to a single insn with the result as intended, and if the corresponding subst attribute supplies an empty NO-SUBST-VALUE, then no mess results even. Make use of this observation. Add appropriate subst iterators to all the computational patterns then, according to the condition codes they usably set, including DImode ones and a substitute DImode comparison instruction in the absence of a CMPQ machine instruction, however do not provide a `cbranchdi4' named pattern as without a further development it regresses code quality by resorting to the `__cmpdi2' libcall where a simpler operation would do, e.g. to check for negativity the TSTL machine instruction may be executed over the upper longword only. This is good material for further work. Do not apply subst iterators to the increment- or decrement-and-branch patterns at this time; these may yet have to be reviewed, in particular whether `*jsobneq_minus_one' is still relevant in the context of the recent integer constant cost review. Also add a couple of peepholes to help eliminating comparisons in some problematic cases, such as with the BIT instruction which is bitwise-AND for condition codes only that has no direct counterpart for the actual calculation, because the BIC instruction which does do bitwise-AND and produces a result implements the operation with a bitwise negation of its input `mask' operand. Or the FFS instruction which sets the Z condition code according to its `field' input operand rather than the result produced. Or the bit-field comparisons we don't have generic middle-end support for. Code size stats are as follows, obtained from 17640 and 9086 executables built in `check-c' and `check-c++' GCC testing respectively: check-c check-c++ samples average median samples average median --------------------------------------------------------------- regressions 1813 0.578% 0.198% 289 0.349% 0.175% unchanged 15160 0.000% 0.000% 8662 0.000% 0.000% progressions 667 -0.589% -0.194% 135 -0.944% -0.191% ---------------------------------------------------------------- total 17640 0.037% 0.000% 9086 -0.003% 0.000% Outliers: old new change %change filename ---------------------------------------------------- 2406 2950 +544 +22.610 20111208-1.exe 4314 5329 +1015 +23.528 pr39417.exe 2235 3055 +820 +36.689 990404-1.exe 2631 4213 +1582 +60.129 pr57521.exe 3063 5579 +2516 +82.142 20000422-1.exe and: old new change %change filename ---------------------------------------------------- 6317 4845 -1472 -23.302 vector-compare-1.exe 6313 4845 -1468 -23.254 vector-compare-1.exe 6474 5002 -1472 -22.737 vector-compare-1.exe 6470 5002 -1468 -22.689 vector-compare-1.exe We have some code quality regressions like: 10861: 9e ef d9 12 movab 11b40

,r0 10865: 00 00 50 10868: 90 a0 03 a0 movb 0x3(r0),0x2(r0) 1086c: 02 1086d: d1 60 8f 61 cmpl (r0),$0x64646261 10871: 62 64 64 10874: 13 07 beql 1087d to: 10861: 9e ef e1 12 movab 11b48

,r0 10865: 00 00 50 10868: 90 a0 03 a0 movb 0x3(r0),0x2(r0) 1086c: 02 1086d: d1 ef d5 12 cmpl 11b48

,$0x64646261 10871: 00 00 8f 61 10875: 62 64 64 10878: 13 07 beql 10881 (from `memmove-2.x2') due to the constant propagation passes eagerly replacing pseudo registers with direct symbol references where possible, which does not happen with CC0 even though the passes do run regardless. There are further code quality regressions due to earlier compilation stages trying to push expression evaluation earlier where possible so as to make data dependencies further apart from each other. This works well for computations and architectures that do not involve condition codes set as a side effect of calculations. However for integer negation that makes assembly code produced like: movb *8(%ap),%r0 mnegb %r0,%r1 tstb %r0 jeql .L2 the RTL equibvalent of which the comparison elimination pass cannot really do anything about, because the comparison is made on the source rather than the target operand of the negation (we could add a peephole for this, but this seems futile an effort, as one'd have to iterate over all the possible such cases), even though this is really equivalent to: movb *8(%ap),%r0 mnegb %r0,%r1 jeql .L2 or, if R0 is dead at the conclusion of the branch, even: mnegb *8(%ap),%r1 jeql .L2 Since the compiler insists on doing the comparison on the source of the negation it obviously has to load it into a temporary so as to avoid accessing the original memory location twice, hence the sequence of three instructions rather than just a single one. A similar phenomenon can be observed with the XOR operation and in other cases. In some cases a comparison does get eliminated, however useless moves into registers done in preparation to it remain, such as with: movb *8(%ap),%r2 movb *12(%ap),%r1 subb3 %r1,%r2,%r0 jlssu .L2 where R1 and R2 are both dead at conclusion and therefore: subb3 *12(%ap),*8(%ap),%r0 jlssu .L2 would obviously do, but there was to be a comparison before the branch: cmpb %r2,%r1 All this looks like material for future improvement. Test cases for comparison elimination and the peepholes will be supplied separately. gcc/ PR target/95294 * config/vax/elf.h (REGISTER_NAMES): Append `%psl'. * config/vax/vax-modes.def (CCN, CCNZ, CCZ): New modes. * config/vax/vax-protos.h (vax_select_cc_mode): New prototype. (vax_maybe_split_dimode_move): Likewise. (vax_notice_update_cc): Remove prototype. * config/vax/vax.c (TARGET_FLAGS_REGNUM): New macro. (TARGET_CC_MODES_COMPATIBLE): Likewise. (TARGET_MD_ASM_ADJUST): Likewise. (vax_select_cc_mode): New function (vax_cc_modes_compatible): Likewise. (vax_md_asm_adjust): Likewise. (vax_notice_update_cc): Remove function. (vax_output_int_move): Factor out code checking if a DImode move may have to be split... (vax_maybe_split_dimode_move): ... into this new function. * config/vax/vax.h (FIRST_PSEUDO_REGISTER): Bump up. (FIXED_REGISTERS): Append an entry for PSL. (CALL_USED_REGISTERS): Likewise. (NOTICE_UPDATE_CC, OUTPUT_JUMP): Remove macros. (SELECT_CC_MODE): New macro. (REGISTER_NAMES): Append `psl'. * config/vax/predicates.md (const_zero_operand) (vax_cc_comparison_operator, vax_ccn_comparison_operator) (vax_ccnz_comparison_operator, vax_ccz_comparison_operator): New predicates. * config/vax/builtins.md: Rewrite for MODE_CC representation. * config/vax/vax.md: Likewise. --- gcc/config/vax/builtins.md | 109 ++- gcc/config/vax/elf.h | 3 +- gcc/config/vax/predicates.md | 20 + gcc/config/vax/vax-modes.def | 11 + gcc/config/vax/vax-protos.h | 3 +- gcc/config/vax/vax.c | 203 +++-- gcc/config/vax/vax.h | 32 +- gcc/config/vax/vax.md | 1788 ++++++++++++++++++++++++++++++++++++++---- 8 files changed, 1904 insertions(+), 265 deletions(-) (limited to 'gcc') diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index e96ac3f..846d1f3 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -39,10 +39,10 @@ { rtx label = gen_label_rtx (); rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label); - rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); + rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx); rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx); - emit_insn (gen_ctz2 (operands[0], operands[1])); + emit_insn (gen_ctz2_ccz (operands[0], operands[1])); emit_jump_insn (gen_rtx_SET (pc_rtx, target)); emit_insn (gen_neg2 (operands[0], const1_rtx)); emit_label (label); @@ -50,33 +50,114 @@ DONE; }") -(define_insn "ctz2" +(define_insn_and_split "ctz2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") + (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ctz:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ctz2" [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT"))) - (set (cc0) - (compare (match_dup 1) - (const_int 0)))] + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "ffs $0,$,%1,%0") + +(define_insn_and_split "ctz2_ccz" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") + (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))] "" + "#" + "reload_completed" + [(parallel + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (ctz:SI (match_dup 1)))])] + "") + +(define_insn "*ctz2_ccz" + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT") + (const_int 0))) + (set (match_operand:SI 0 "nonimmediate_operand" "=rQ") + (ctz:SI (match_dup 1)))] + "reload_completed" "ffs $0,$,%1,%0") ;; Our FFS hardware instruction supports any field width, ;; so handle narrower inputs directly as well. (define_peephole2 - [(set (match_operand:SI 0 "register_operand") - (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) + [(parallel + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) (parallel [(set (match_operand:SI 2 "nonimmediate_operand") (ctz:SI (match_dup 0))) - (set (cc0) - (compare (match_dup 2) - (const_int 0)))])] + (clobber (reg:CC VAX_PSL_REGNUM))])] "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])" [(parallel [(set (match_dup 2) (ctz:SI (match_dup 1))) - (set (cc0) - (compare (match_dup 1) - (const_int 0)))])] + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +;; The FFS hardware instruction sets the Z condition code based on +;; the input field rather than the output operand, so the compare +;; elimination pass cannot handle it. Try to get rid of the extra +;; operation by hand. +;; +;; The "ctz2_ccz" patterns require their `operands[1]' not to +;; have a mode dependent address, so all we need to verify is that +;; the two operands are not the same, in which case it's the FFS +;; output rather than input that condition codes are checked for. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "nonimmediate_operand") + (ctz:SI (match_operand:VAXint 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0)))] + "!rtx_equal_p (operands[0], operands[1])" + [(parallel + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (ctz:SI (match_dup 1)))])] + "") + +;; This effectively combines the two peepholes above, +;; matching the sequence produced by `ffs2'. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (parallel + [(set (match_operand:SI 2 "nonimmediate_operand") + (ctz:SI (match_dup 0))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 0) + (const_int 0)))] + "!rtx_equal_p (operands[0], operands[2]) + && peep2_reg_dead_p (3, operands[0])" + [(parallel + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0))) + (set (match_dup 2) + (ctz:SI (match_dup 1)))])] "") (define_expand "sync_lock_test_and_set" diff --git a/gcc/config/vax/elf.h b/gcc/config/vax/elf.h index 530b2c0..f6485eca 100644 --- a/gcc/config/vax/elf.h +++ b/gcc/config/vax/elf.h @@ -26,7 +26,8 @@ along with GCC; see the file COPYING3. If not see #define REGISTER_PREFIX "%" #define REGISTER_NAMES \ { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ - "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", } + "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", \ + "%psl" } #undef SIZE_TYPE #define SIZE_TYPE "long unsigned int" diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md index 7c97b36..92caf83 100644 --- a/gcc/config/vax/predicates.md +++ b/gcc/config/vax/predicates.md @@ -17,6 +17,10 @@ ;; along with GCC; see the file COPYING3. If not see ;; . +;; Return true if OP is a constant zero operand. +(define_predicate "const_zero_operand" + (match_test "op == CONST0_RTX (mode)")) + ;; Special case of a symbolic operand that's used as a ;; operand. @@ -109,3 +113,19 @@ (define_predicate "any_memory_operand" (ior (match_operand 0 "memory_operand") (match_operand 0 "volatile_mem_operand"))) + +;; Return true if OP is a comparison operator that requires at least CCmode. +(define_predicate "vax_cc_comparison_operator" + (match_code "geu,gtu,leu,ltu")) + +;; Return true if OP is a comparison operator that requires at least CCNmode. +(define_predicate "vax_ccn_comparison_operator" + (match_code "ge,lt")) + +;; Return true if OP is a comparison operator that requires at least CCNZmode. +(define_predicate "vax_ccnz_comparison_operator" + (match_code "gt,le")) + +;; Return true if OP is a comparison operator that requires at least CCZmode. +(define_predicate "vax_ccz_comparison_operator" + (match_code "ne,eq")) diff --git a/gcc/config/vax/vax-modes.def b/gcc/config/vax/vax-modes.def index 5f1c994..2a7438e 100644 --- a/gcc/config/vax/vax-modes.def +++ b/gcc/config/vax/vax-modes.def @@ -20,3 +20,14 @@ along with GCC; see the file COPYING3. If not see /* We just need to reset the floating point formats. */ RESET_FLOAT_FORMAT (SF, vax_f_format); RESET_FLOAT_FORMAT (DF, vax_d_format); + +/* `DImode' addition and subtraction operations do their calculation + on the low and then the high longword with separate instructions, + and therefore only usably set N. */ +CC_MODE (CCN); +/* Non-arithmetic integer instructions such as MOV or XOR as well as + instructions that produce a floating-point result only usably set + N and Z. */ +CC_MODE (CCNZ); +/* The FFC and FFS instructions only usably set Z. */ +CC_MODE (CCZ); diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index 454d35e..aa949c5 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -22,13 +22,14 @@ extern void vax_expand_prologue (void); #ifdef RTX_CODE extern bool vax_acceptable_pic_operand_p (rtx, bool, bool); +extern machine_mode vax_select_cc_mode (enum rtx_code, rtx, rtx); extern const char *cond_name (rtx); extern bool adjacent_operands_p (rtx, rtx, machine_mode); extern const char *rev_cond_name (rtx); extern void print_operand_address (FILE *, rtx); extern void print_operand (FILE *, rtx, int); -extern void vax_notice_update_cc (rtx, rtx); extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code); +extern bool vax_maybe_split_dimode_move (rtx *); extern const char * vax_output_int_move (rtx, rtx *, machine_mode); extern const char * vax_output_int_add (rtx_insn *, rtx *, machine_mode); extern const char * vax_output_int_subtract (rtx_insn *, rtx *, machine_mode); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 69a05b3..54d83dc 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -54,6 +54,10 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, static int vax_address_cost_1 (rtx); static int vax_address_cost (rtx, machine_mode, addr_space_t, bool); static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool); +static machine_mode vax_cc_modes_compatible (machine_mode, machine_mode); +static rtx_insn *vax_md_asm_adjust (vec &, vec &, + vec &, + vec &, HARD_REG_SET &); static rtx vax_function_arg (cumulative_args_t, const function_arg_info &); static void vax_function_arg_advance (cumulative_args_t, const function_arg_info &); @@ -81,11 +85,23 @@ static HOST_WIDE_INT vax_starting_frame_offset (void); #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall +/* Enable compare elimination pass. */ +#undef TARGET_FLAGS_REGNUM +#define TARGET_FLAGS_REGNUM VAX_PSL_REGNUM + #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS vax_rtx_costs #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST vax_address_cost +/* Return the narrowest CC mode that spans both modes offered. */ +#undef TARGET_CC_MODES_COMPATIBLE +#define TARGET_CC_MODES_COMPATIBLE vax_cc_modes_compatible + +/* Mark PSL as clobbered for compatibility with the CC0 representation. */ +#undef TARGET_MD_ASM_ADJUST +#define TARGET_MD_ASM_ADJUST vax_md_asm_adjust + #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true @@ -1070,6 +1086,102 @@ vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED, return true; } +/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE, + return the mode to be used for the comparison. As we have the same + interpretation of condition codes across all the instructions we just + return the narrowest mode suitable for the comparison code requested. */ + +extern machine_mode +vax_select_cc_mode (enum rtx_code op, + rtx x ATTRIBUTE_UNUSED, rtx y ATTRIBUTE_UNUSED) +{ + switch (op) + { + default: + gcc_unreachable (); + case NE: + case EQ: + return CCZmode; + case GE: + case LT: + return CCNmode; + case GT: + case LE: + return CCNZmode; + case GEU: + case GTU: + case LEU: + case LTU: + return CCmode; + } +} + +/* Return the narrowest CC mode that spans both modes offered. If they + intersect, this will be the wider of the two, and if they do not then + find find one that is a superset of both (i.e. CCNZmode for a pair + consisting of CCNmode and CCZmode). A wider CC writer will satisfy + a narrower CC reader, e.g. a comparison operator that uses CCZmode + can use a CCNZmode output of a previous instruction. */ + +static machine_mode +vax_cc_modes_compatible (machine_mode m1, machine_mode m2) +{ + switch (m1) + { + default: + gcc_unreachable (); + case E_CCmode: + switch (m2) + { + default: + gcc_unreachable (); + case E_CCmode: + case E_CCNZmode: + case E_CCNmode: + case E_CCZmode: + return m1; + } + case E_CCNZmode: + switch (m2) + { + default: + gcc_unreachable (); + case E_CCmode: + return m2; + case E_CCNmode: + case E_CCNZmode: + case E_CCZmode: + return m1; + } + case E_CCNmode: + case E_CCZmode: + switch (m2) + { + default: + gcc_unreachable (); + case E_CCmode: + case E_CCNZmode: + return m2; + case E_CCNmode: + case E_CCZmode: + return m1 == m2 ? m1 : E_CCNZmode; + } + } +} + +/* Mark PSL as clobbered for compatibility with the CC0 representation. */ + +static rtx_insn * +vax_md_asm_adjust (vec &outputs ATTRIBUTE_UNUSED, + vec &inputs ATTRIBUTE_UNUSED, + vec &constraints ATTRIBUTE_UNUSED, + vec &clobbers, HARD_REG_SET &clobbered_regs) +{ + clobbers.safe_push (gen_rtx_REG (CCmode, VAX_PSL_REGNUM)); + SET_HARD_REG_BIT (clobbered_regs, VAX_PSL_REGNUM); + return NULL; +} + /* Output code to add DELTA to the first argument, and then jump to FUNCTION. Used for C++ multiple inheritance. .mask ^m #conservative entry mask @@ -1102,81 +1214,21 @@ vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM); } -/* Worker function for NOTICE_UPDATE_CC. */ +/* Output integer move instructions. */ -void -vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED) +bool +vax_maybe_split_dimode_move (rtx *operands) { - if (GET_CODE (exp) == SET) - { - if (GET_CODE (SET_SRC (exp)) == CALL) - CC_STATUS_INIT; - else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT - && GET_CODE (SET_DEST (exp)) != PC) - { - cc_status.flags = 0; - /* The integer operations below don't set carry or - set it in an incompatible way. That's ok though - as the Z bit is all we need when doing unsigned - comparisons on the result of these insns (since - they're always with 0). Set CC_NO_OVERFLOW to - generate the correct unsigned branches. */ - switch (GET_CODE (SET_SRC (exp))) - { - case NEG: - if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT) - break; - /* FALLTHRU */ - case AND: - case IOR: - case XOR: - case NOT: - case MEM: - case REG: - cc_status.flags = CC_NO_OVERFLOW; - break; - case CTZ: - cc_status.flags = CC_NOT_NEGATIVE; - break; - default: - break; - } - cc_status.value1 = SET_DEST (exp); - cc_status.value2 = SET_SRC (exp); - } - } - else if (GET_CODE (exp) == PARALLEL - && GET_CODE (XVECEXP (exp, 0, 0)) == SET) - { - if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL) - CC_STATUS_INIT; - else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC) - { - cc_status.flags = 0; - cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0)); - cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0)); - } - else - /* PARALLELs whose first element sets the PC are aob, - sob insns. They do change the cc's. */ - CC_STATUS_INIT; - } - else - CC_STATUS_INIT; - if (cc_status.value1 && REG_P (cc_status.value1) - && cc_status.value2 - && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) - cc_status.value2 = 0; - if (cc_status.value1 && MEM_P (cc_status.value1) - && cc_status.value2 - && MEM_P (cc_status.value2)) - cc_status.value2 = 0; - /* Actual condition, one line up, should be that value2's address - depends on value1, but that is too much of a pain. */ + return (TARGET_QMATH + && (!MEM_P (operands[0]) + || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC + || GET_CODE (XEXP (operands[0], 0)) == POST_INC + || !illegal_addsub_di_memory_operand (operands[0], DImode)) + && ((CONST_INT_P (operands[1]) + && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) + || GET_CODE (operands[1]) == CONST_DOUBLE)); } -/* Output integer move instructions. */ - const char * vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, machine_mode mode) @@ -1252,14 +1304,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, } } - if (TARGET_QMATH - && (!MEM_P (operands[0]) - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC - || GET_CODE (XEXP (operands[0], 0)) == POST_INC - || !illegal_addsub_di_memory_operand (operands[0], DImode)) - && ((CONST_INT_P (operands[1]) - && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) - || GET_CODE (operands[1]) == CONST_DOUBLE)) + if (vax_maybe_split_dimode_move (operands)) { hi[0] = operands[0]; hi[1] = operands[1]; diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index 43182ff..8b2b2d1 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -120,12 +120,12 @@ along with GCC; see the file COPYING3. If not see from 0 to just below FIRST_PSEUDO_REGISTER. All registers that the compiler knows about must be given numbers, even those that are not normally considered general registers. */ -#define FIRST_PSEUDO_REGISTER 16 +#define FIRST_PSEUDO_REGISTER 17 /* 1 for registers that have pervasive standard uses and are not available for the register allocator. On the VAX, these are the AP, FP, SP and PC. */ -#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} +#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -133,7 +133,7 @@ along with GCC; see the file COPYING3. If not see The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} +#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ @@ -465,24 +465,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define BRANCH_COST(speed_p, predictable_p) 0 -/* Tell final.c how to eliminate redundant test instructions. */ - -/* Here we define machine-dependent flags and fields in cc_status - (see `conditions.h'). No extra ones are needed for the VAX. */ - -/* Store in cc_status the expressions - that the condition codes will describe - after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. */ - -#define NOTICE_UPDATE_CC(EXP, INSN) \ - vax_notice_update_cc ((EXP), (INSN)) - -#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ - { if (cc_status.flags & CC_NO_OVERFLOW) \ - return NO_OV; \ - return NORMAL; \ - } +/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE, + return the mode to be used for the comparison. As we have the same + interpretation of condition codes across all the instructions we just + return the narrowest mode suitable for the comparison code requested. */ +#define SELECT_CC_MODE(OP, X, Y) vax_select_cc_mode (OP, X, Y) /* Control the assembler format that we output. */ @@ -517,7 +504,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define REGISTER_PREFIX "" #define REGISTER_NAMES \ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", } + "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", \ + "psl" } /* This is BSD, so it wants DBX format. */ diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 1bb4e30..b8cf4ee 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -22,9 +22,6 @@ ;;- the first one in the file is chosen. ;;- ;;- See file "rtl.def" for documentation on define_insn, match_*, et al. -;;- -;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code -;;- updates for most instructions. ;; UNSPEC_VOLATILE usage: @@ -40,6 +37,8 @@ (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer (VAX_PC_REGNUM 15) ; Register 15 contains the program counter + (VAX_PSL_REGNUM 16) ; Register 16 contains the processor status + ; and condition codes in particular ] ) @@ -57,34 +56,96 @@ ;; Some output patterns want integer immediates with a prefix... (define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")]) +(define_mode_iterator VAXcc [CC CCN CCNZ CCZ]) +(define_mode_iterator VAXccnz [CCN CCNZ CCZ]) +(define_mode_attr cc [(CC "cc") (CCN "ccn") (CCNZ "ccnz") (CCZ "ccz")]) + +(define_code_iterator any_extract [sign_extract zero_extract]) + ;; (include "constraints.md") (include "predicates.md") -(define_insn "*cmp" - [(set (cc0) - (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT") - (match_operand:VAXint 1 "general_operand" "I,nrmT")))] +;; Make instructions that set the N, N+Z, and Z condition codes respectively. +(define_subst "subst_" + [(set (match_operand 0 "") + (match_operand 1 "")) + (clobber (reg:CC VAX_PSL_REGNUM))] "" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (match_dup 1))]) + +(define_subst "subst_f" + [(set (match_operand 0 "") + (match_operand 1 "")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_dup 1) + (const_double_zero))) + (set (match_dup 0) + (match_dup 1))]) + +;; Select all from the attributes below that apply to a given insn that +;; has a clobber on CC for the comparison elimination pass to use it in +;; place of a subsequent comparison instruction matching the mode used +;; by a comparison operator in branch. +;; +;; For example a branch doing `eq' in SImode will use `*cmpsi_ccz', so +;; to eliminate it a `*movsi_ccz', etc. pattern will be required via the +;; `ccz' substitution. Analogously for the other CC modes. +;; +;; The general `cc' mode, which sets all of the C, N, V and Z condition +;; codes, has to be handled specially as it makes no sense for the usual +;; comparison against zero, so no substitution has been defined for it. +(define_subst_attr "ccn" "subst_ccn" "" "_ccn") +(define_subst_attr "ccnz" "subst_ccnz" "" "_ccnz") +(define_subst_attr "ccz" "subst_ccz" "" "_ccz") +(define_subst_attr "fccn" "subst_fccn" "" "_ccn") +(define_subst_attr "fccnz" "subst_fccnz" "" "_ccnz") +(define_subst_attr "fccz" "subst_fccz" "" "_ccz") + +(define_insn "*cmp_" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (match_operand:VAXint 0 "general_operand" "nrmT,nrmT") + (match_operand:VAXint 1 "general_operand" "I,nrmT")))] + "reload_completed" "@ tst %0 cmp %0,%1") -(define_insn "*cmp" - [(set (cc0) - (compare (match_operand:VAXfp 0 "general_operand" "gF,gF") - (match_operand:VAXfp 1 "general_operand" "G,gF")))] - "" +;; We don't have a CMPQ instruction, but we can set the N and Z condition +;; codes with MOVQ, and also this comparison can be folded into a preceding +;; operation by the post-reload comparison elimination pass. +(define_insn "*cmpdi_" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_operand:DI 0 "general_operand" "r,nmT") + (match_operand:DI 1 "const_zero_operand" "I,I"))) + (clobber (match_scratch:DI 2 "=X,r"))] + "reload_completed" + "@ + movq %0,%0 + movq %0,%2") + +(define_insn "*cmp_" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_operand:VAXfp 0 "general_operand" "gF,gF") + (match_operand:VAXfp 1 "general_operand" "G,gF")))] + "reload_completed" "@ tst %0 cmp %0,%1") -(define_insn "*bit" - [(set (cc0) - (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT") - (match_operand:VAXint 1 "general_operand" "nrmT")) - (const_int 0)))] - "" +(define_insn "*bit_" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz + (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT") + (match_operand:VAXint 1 "general_operand" "nrmT")) + (const_int 0)))] + "reload_completed" "bit %0,%1") ;; The VAX has no sCOND insns. It does have add/subtract with carry @@ -95,25 +156,76 @@ ;; and has been deleted. -(define_insn "mov" +(define_insn_and_split "mov" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (match_operand:VAXfp 1 "general_operand" "G,gF"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mov" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (match_operand:VAXfp 1 "general_operand" "G,gF")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ clr %0 mov %1,%0") ;; Some VAXen don't support this instruction. -;;(define_insn "movti" +;;(define_insn_and_split "movti" ;; [(set (match_operand:TI 0 "nonimmediate_operand" "=g") ;; (match_operand:TI 1 "general_operand" "g"))] ;; "" +;; "#" +;; "reload_completed" +;; [(parallel +;; [(set (match_dup 0) +;; (match_dup 1)) +;; (clobber (reg:CC VAX_PSL_REGNUM))])] +;; "") +;; +;;(define_insn "*movti" +;; [(set (match_operand:TI 0 "nonimmediate_operand" "=g") +;; (match_operand:TI 1 "general_operand" "g")) +;; (clobber (reg:CC VAX_PSL_REGNUM))] +;; "reload_completed" ;; "movo %1,%0") -(define_insn "movdi" +(define_insn_and_split "movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (match_operand:DI 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +;; In some cases `vax_output_int_move' splits a `DImode' move into a pair +;; of `SImode' moves, in which case the flags aren't usefully set. Have +;; separate patterns then, for the cases where the move may and may not be +;; split each. We use the outer condition only so in some cases we will +;; fail to notice the move does not actually get split, but this is OK. +(define_insn "*movdi_maybe_split" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (match_operand:DI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed && vax_maybe_split_dimode_move (operands)" + "* return vax_output_int_move (insn, operands, DImode);") + +(define_insn "*movdi_unsplit" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (match_operand:DI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed && !vax_maybe_split_dimode_move (operands)" "* return vax_output_int_move (insn, operands, DImode);") ;; The VAX move instructions have space-time tradeoffs. On a MicroVAX @@ -155,22 +267,61 @@ #endif }") -(define_insn "movsi_2" +(define_insn_and_split "movsi_2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movsi_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:SI 1 "nonsymbolic_operand" "nrmT")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* return vax_output_int_move (insn, operands, SImode);") -(define_insn "mov" +(define_insn_and_split "mov" [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g") (match_operand:VAXintQH 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mov" + [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g") + (match_operand:VAXintQH 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* return vax_output_int_move (insn, operands, mode);") -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g")) +(define_insn_and_split "movstricthi" + [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) (match_operand:HI 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (strict_low_part (match_dup 0)) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movstricthi" + [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) + (match_operand:HI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (CONST_INT_P (operands[1])) @@ -188,10 +339,23 @@ return \"movw %1,%0\"; }") -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g")) +(define_insn_and_split "movstrictqi" + [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r")) (match_operand:QI 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (strict_low_part (match_dup 0)) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movstrictqi" + [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r")) + (match_operand:QI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (CONST_INT_P (operands[1])) @@ -236,7 +400,7 @@ ;; that anything generated as this insn will be recognized as one ;; and that it won't successfully combine with anything. -(define_insn "movmemhi1" +(define_insn_and_split "movmemhi1" [(set (match_operand:BLK 0 "memory_operand" "=o") (match_operand:BLK 1 "memory_operand" "o")) (use (match_operand:HI 2 "general_operand" "g")) @@ -247,90 +411,286 @@ (clobber (reg:SI 4)) (clobber (reg:SI 5))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (use (match_dup 2)) + (clobber (reg:SI 0)) + (clobber (reg:SI 1)) + (clobber (reg:SI 2)) + (clobber (reg:SI 3)) + (clobber (reg:SI 4)) + (clobber (reg:SI 5)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movmemhi1" + [(set (match_operand:BLK 0 "memory_operand" "=o") + (match_operand:BLK 1 "memory_operand" "o")) + (use (match_operand:HI 2 "general_operand" "g")) + (clobber (reg:SI 0)) + (clobber (reg:SI 1)) + (clobber (reg:SI 2)) + (clobber (reg:SI 3)) + (clobber (reg:SI 4)) + (clobber (reg:SI 5)) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movc3 %2,%1,%0") ;; Extension and truncation insns. -(define_insn "truncsiqi2" +(define_insn_and_split "truncsiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (truncate:QI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*truncsiqi2" + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") + (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtlb %1,%0") -(define_insn "truncsihi2" +(define_insn_and_split "truncsihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (truncate:HI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*truncsihi2" + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") + (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtlw %1,%0") -(define_insn "trunchiqi2" +(define_insn_and_split "trunchiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (truncate:QI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*trunchiqi2" + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") + (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtwb %1,%0") -(define_insn "extendhisi2" +(define_insn_and_split "extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendhisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtwl %1,%0") -(define_insn "extendqihi2" +(define_insn_and_split "extendqihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extend:HI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendqihi2" + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtbw %1,%0") -(define_insn "extendqisi2" +(define_insn_and_split "extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendqisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtbl %1,%0") -(define_insn "extendsfdf2" +(define_insn_and_split "extendsfdf2" [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (float_extend:DF (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendsfdf2" + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") + (float_extend:DF (match_operand:SF 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtf%# %1,%0") -(define_insn "truncdfsf2" +(define_insn_and_split "truncdfsf2" [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (float_truncate:SF (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*truncdfsf2" + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") + (float_truncate:SF (match_operand:DF 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvt%#f %1,%0") -(define_insn "zero_extendhisi2" +(define_insn_and_split "zero_extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*zero_extendhisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movzwl %1,%0") -(define_insn "zero_extendqihi2" +(define_insn_and_split "zero_extendqihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extend:HI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*zero_extendqihi2" + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movzbw %1,%0") -(define_insn "zero_extendqisi2" +(define_insn_and_split "zero_extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*zero_extendqisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movzbl %1,%0") ;; Fix-to-float conversion insns. -(define_insn "float2" +(define_insn_and_split "float2" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (float:VAXfp (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*float2" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") + (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvt %1,%0") ;; Float-to-fix conversion insns. -(define_insn "fix_trunc2" +(define_insn_and_split "fix_trunc2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (fix:VAXint (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*fix_trunc2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvt %1,%0") (define_expand "fixuns_trunc2" @@ -340,21 +700,51 @@ ;;- All kinds of add instructions. -(define_insn "add3" +(define_insn_and_split "add3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (plus:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*add3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") + (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") + (match_operand:VAXfp 2 "general_operand" "gF,0,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ add2 %2,%0 add2 %1,%0 add3 %1,%2,%0") -(define_insn "add3" +(define_insn_and_split "add3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") (match_operand:VAXint 2 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (plus:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*add3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* return vax_output_int_add (insn, operands, mode);") (define_expand "adddi3" @@ -364,37 +754,109 @@ "!reload_in_progress" "vax_expand_addsub_di_operands (operands, PLUS); DONE;") -(define_insn "adcdi3" +(define_insn_and_split "adcdi3" [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr") (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0") (match_operand:DI 2 "general_addsub_di_operand" "nRr")))] "TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*adcdi3" + [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr") + (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0") + (match_operand:DI 2 "general_addsub_di_operand" "nRr"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "TARGET_QMATH && reload_completed" "* return vax_output_int_add (insn, operands, DImode);") ;; The add-with-carry (adwc) instruction only accepts two operands. -(define_insn "adddi3_old" +(define_insn_and_split "adddi3_old" [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") (match_operand:DI 2 "general_operand" "Fsro,Fs")))] "!TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*adddi3_old" + [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") + (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") + (match_operand:DI 2 "general_operand" "Fsro,Fs"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_QMATH && reload_completed" "* return vax_output_int_add (insn, operands, DImode);") ;;- All kinds of subtract instructions. -(define_insn "sub3" +(define_insn_and_split "sub3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (minus:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*sub3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") + (match_operand:VAXfp 2 "general_operand" "gF,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ sub2 %2,%0 sub3 %2,%1,%0") -(define_insn "sub3" +(define_insn_and_split "sub3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (minus:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*sub3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "@ + sub2 %2,%0 + sub3 %2,%1,%0") + +(define_insn "*sub3_cc" + [(set (reg:CC VAX_PSL_REGNUM) + (compare:CC (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,nrmT"))) + (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (minus:VAXint (match_dup 1) + (match_dup 2)))] + "reload_completed" "@ sub2 %2,%0 sub3 %2,%1,%0") @@ -406,52 +868,129 @@ "!reload_in_progress" "vax_expand_addsub_di_operands (operands, MINUS); DONE;") -(define_insn "sbcdi3" +(define_insn_and_split "sbcdi3" [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr") (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I") (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))] "TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (minus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*sbcdi3" + [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr") + (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I") + (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "TARGET_QMATH && reload_completed" "* return vax_output_int_subtract (insn, operands, DImode);") ;; The subtract-with-carry (sbwc) instruction only takes two operands. -(define_insn "subdi3_old" +(define_insn_and_split "subdi3_old" [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") (minus:DI (match_operand:DI 1 "general_operand" "0,or>") (match_operand:DI 2 "general_operand" "Fsor,Fs")))] "!TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (minus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*subdi3_old" + [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") + (minus:DI (match_operand:DI 1 "general_operand" "0,or>") + (match_operand:DI 2 "general_operand" "Fsor,Fs"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_QMATH && reload_completed" "* return vax_output_int_subtract (insn, operands, DImode);") ;;- Multiply instructions. -(define_insn "mul3" +(define_insn_and_split "mul3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (mult:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mul3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") + (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") + (match_operand:VAXfp 2 "general_operand" "gF,0,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ mul2 %2,%0 mul2 %1,%0 mul3 %1,%2,%0") -(define_insn "mul3" +(define_insn_and_split "mul3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (mult:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mul3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ mul2 %2,%0 mul2 %1,%0 mul3 %1,%2,%0") -(define_insn "mulsidi3" +(define_insn_and_split "mulsidi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (mult:DI (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (mult:DI + (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mulsidi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "emul %1,%2,$0,%0") -(define_insn "*maddsidi4" +(define_insn_and_split "*maddsidi4" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI (mult:DI @@ -459,10 +998,31 @@ (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) (sign_extend:DI (match_operand:SI 3 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI + (mult:DI + (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2))) + (sign_extend:DI (match_dup 3)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*maddsidi4_2" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (plus:DI + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "emul %1,%2,%3,%0") ;; 'F' constraint means type CONST_DOUBLE -(define_insn "*maddsidi4_const" +(define_insn_and_split "*maddsidi4_const" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI (mult:DI @@ -471,6 +1031,29 @@ (match_operand:DI 3 "immediate_operand" "F")))] "GET_CODE (operands[3]) == CONST_DOUBLE && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI + (mult:DI + (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2))) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*maddsidi4_const_2" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (plus:DI + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (match_operand:DI 3 "immediate_operand" "F"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "GET_CODE (operands[3]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31) + && reload_completed" "* { if (CONST_DOUBLE_HIGH (operands[3])) @@ -480,27 +1063,57 @@ ;;- Divide instructions. -(define_insn "div3" +(define_insn_and_split "div3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (div:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*div3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") + (match_operand:VAXfp 2 "general_operand" "gF,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ div2 %2,%0 div3 %2,%1,%0") -(define_insn "div3" +(define_insn_and_split "div3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (div:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*div3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ div2 %2,%0 div3 %2,%1,%0") ;; This is left out because it is very slow; ;; we are better off programming around the "lack" of this insn. -;;(define_insn "divmoddisi4" +;;(define_insn_and_split "divmoddisi4" ;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") ;; (div:SI (match_operand:DI 1 "general_operand" "g") ;; (match_operand:SI 2 "general_operand" "g"))) @@ -508,6 +1121,27 @@ ;; (mod:SI (match_dup 1) ;; (match_dup 2)))] ;; "" +;; "#" +;; "reload_completed" +;; [(parallel +;; [(set (match_dup 0) +;; (div:SI (match_dup 1) +;; (match_dup 2))) +;; (set (match_dup 3) +;; (mod:SI (match_dup 1) +;; (match_dup 2))) +;; (clobber (reg:CC VAX_PSL_REGNUM))])] +;; "") +;; +;;(define_insn "*divmoddisi4" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (div:SI (match_operand:DI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g"))) +;; (set (match_operand:SI 3 "nonimmediate_operand" "=g") +;; (mod:SI (match_dup 1) +;; (match_dup 2))) +;; (clobber (reg:CC VAX_PSL_REGNUM))] +;; "reload_completed" ;; "ediv %2,%1,%0,%3") ;; Bit-and on the VAX is done with a clear-bits insn. @@ -534,11 +1168,29 @@ operands[1] = expand_unop (mode, one_cmpl_optab, op1, 0, 1); }") -(define_insn "*and" +(define_insn_and_split "*and3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") - (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) + (and:VAXint (not:VAXint + (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) (match_operand:VAXint 2 "general_operand" "0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (and:VAXint (not:VAXint + (match_dup 1)) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*and3_2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (and:VAXint (not:VAXint + (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) + (match_operand:VAXint 2 "general_operand" "0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ bic2 %1,%0 bic3 %1,%2,%0") @@ -548,23 +1200,80 @@ ;; longer a problem. However, having these patterns allows optimization ;; opportunities in combine.c. -(define_insn "*and_const_int" +(define_insn_and_split "*and3_const_int" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") (match_operand:VAXint 2 "const_int_operand" "n,n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (and:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*and3_2_const_int" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "const_int_operand" "n,n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ bic2 %2,%0 bic3 %2,%1,%0") +;; We have no direct AND operation and consequently the RTL sequence +;; the "and3" pattern produces does not match the instruction +;; the "*bit" pattern does for the purpose of the compare +;; elimination pass. Try to get rid of the extra operation by hand +;; and where the sequence is used to set the condition codes only +;; convert MNEG/BIC => BIT. +(define_peephole2 + [(parallel + [(set (match_operand:VAXint 0 "register_operand") + (not:VAXint (match_operand:VAXint 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (parallel + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz + (and:VAXint (not:VAXint (match_dup 0)) + (match_operand:VAXint 3 "general_operand")) + (const_int 0))) + (set (match_operand:VAXint 2 "register_operand") + (and:VAXint (not:VAXint (match_dup 0)) + (match_dup 3)))])] + "peep2_reg_dead_p (2, operands[0]) && peep2_reg_dead_p (2, operands[2])" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz + (and:VAXint (match_dup 1) + (match_dup 3)) + (const_int 0)))] + "") ;;- Bit set instructions. -(define_insn "ior3" +(define_insn_and_split "ior3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ior:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ior3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ bis2 %2,%0 bis2 %1,%0 @@ -572,35 +1281,97 @@ ;;- xor instructions. -(define_insn "xor3" +(define_insn_and_split "xor3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (xor:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*xor3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ xor2 %2,%0 xor2 %1,%0 xor3 %2,%1,%0") - -(define_insn "neg2" +(define_insn_and_split "neg2" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (neg:VAXfp (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*neg2" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") + (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mneg %1,%0") -(define_insn "neg2" +(define_insn_and_split "neg2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (neg:VAXint (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*neg2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "mneg %1,%0") + +(define_insn "*neg2_cc" + [(set (reg:CC VAX_PSL_REGNUM) + (compare:CC (const_int 0) + (neg:VAXint + (match_operand:VAXint 1 "general_operand" "0,nrmT")))) + (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (neg:VAXint (match_dup 1)))] + "reload_completed" "mneg %1,%0") -(define_insn "one_cmpl2" +(define_insn_and_split "one_cmpl2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))] "" - "mcom %1,%0") + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (not:VAXint (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") +(define_insn "*one_cmpl2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "mcom %1,%0") ;; Arithmetic right shift on the VAX works by negating the shift count, ;; then emitting a right shift with the shift count negated. This means @@ -618,25 +1389,70 @@ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") -(define_insn "" +(define_insn_and_split "*ashlnegsi3_const_int" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashiftrt:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlnegsi3_const_int_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashl $%n2,%1,%0") -(define_insn "" +(define_insn_and_split "*ashlnegsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashiftrt:SI (match_dup 1) + (neg:QI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlnegsi3_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") + (neg:QI (match_operand:QI 2 "general_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashl %2,%1,%0") -(define_insn "ashlsi3" +(define_insn_and_split "ashlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "general_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashift:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "general_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1])) @@ -673,18 +1489,48 @@ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") -(define_insn "ashldi3" +(define_insn_and_split "ashldi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashift:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashldi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (ashift:DI (match_operand:DI 1 "general_operand" "g") + (match_operand:QI 2 "general_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashq %2,%D1,%0") -(define_insn "" +(define_insn_and_split "*ashlnegdi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashiftrt:DI (match_dup 1) + (neg:QI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlnegdi3_2" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") + (neg:QI (match_operand:QI 2 "general_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashq %2,%D1,%0") ;; We used to have expand_shift handle logical right shifts by using extzv, @@ -719,34 +1565,96 @@ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") -(define_insn "rotlsi3" +(define_insn_and_split "rotlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotate:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "general_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (rotate:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*rotlsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (rotate:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "general_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "rotl %2,%1,%0") -(define_insn "" +(define_insn_and_split "*rotrsi3_const_int" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (rotatert:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*rotrsi3_const_int_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "rotl %R2,%1,%0") -(define_insn "" +(define_insn_and_split "*rotrnegsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (rotatert:SI (match_dup 1) + (neg:QI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*rotrnegsi3_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") + (neg:QI (match_operand:QI 2 "general_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "rotl %2,%1,%0") ;; This insn is probably slower than a multiply and an add. -;;(define_insn "*amulsi4" +;;(define_insn_and_split "*amulsi4" ;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") ;; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") ;; (match_operand:SI 2 "general_operand" "g")) ;; (match_operand:SI 3 "general_operand" "g")))] ;; "" +;; "#" +;; "reload_completed" +;; [(parallel +;; [(set (match_dup 0) +;; (mult:SI (plus:SI (match_dup 1) +;; (match_dup 2)) +;; (match_dup 3))) +;; (clobber (reg:CC VAX_PSL_REGNUM))])] +;; "") +;; +;;(define_insn "*amulsi4_2" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g")) +;; (match_operand:SI 3 "general_operand" "g"))) +;; (clobber (reg:CC VAX_PSL_REGNUM))] +;; "reload_completed" ;; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") ;; Special cases of bit-field insns which we should @@ -754,7 +1662,7 @@ ;; These handle aligned 8-bit and 16-bit fields ;; that can be done with move or convert instructions. -(define_insn "*insv_aligned" +(define_insn_and_split "*insv_aligned" [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") (match_operand:QI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) @@ -770,6 +1678,34 @@ && (!(REG_P (operands[0]) || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0])))) || INTVAL (operands[2]) == 0)" + "#" + "&& reload_completed" + [(parallel + [(set (zero_extract:SI (match_dup 0) + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*insv_aligned_2" + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") + (match_operand:QI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) + && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 + && (!MEM_P (operands[0]) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[0], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[0], 0), + MEM_ADDR_SPACE (operands[0])))) + && (!(REG_P (operands[0]) + || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0])))) + || INTVAL (operands[2]) == 0) + && reload_completed" "* { if (!REG_P (operands[0])) @@ -780,13 +1716,12 @@ else gcc_assert (INTVAL (operands[2]) == 0); - CC_STATUS_INIT; if (INTVAL (operands[1]) == 8) return \"movb %3,%0\"; return \"movw %3,%0\"; }") -(define_insn "*extzv_aligned" +(define_insn_and_split "*extzv_aligned" [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") @@ -802,6 +1737,34 @@ && (!(REG_P (operands[1]) || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) || INTVAL (operands[3]) == 0)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extzv_aligned_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) + && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 + && (!MEM_P (operands[1]) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0) + && reload_completed" "* { if (!REG_P (operands[1])) @@ -817,7 +1780,7 @@ return \"movzwl %1,%0\"; }") -(define_insn "*extv_aligned" +(define_insn_and_split "*extv_aligned" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") @@ -833,6 +1796,34 @@ && (!(REG_P (operands[1]) || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) || INTVAL (operands[3]) == 0)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extv_aligned_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) + && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 + && (!MEM_P (operands[1]) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0) + && reload_completed" "* { if (!REG_P (operands[1])) @@ -850,24 +1841,24 @@ ;; Register and non-offsettable-memory SImode cases of bit-field insns. -(define_insn "*cmpv" - [(set (cc0) - (compare +(define_insn "*cmpv_" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (sign_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpv %2,%1,%0,%3") -(define_insn "*cmpzv" - [(set (cc0) - (compare +(define_insn "*cmpzv_" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpzv %2,%1,%0,%3") ;; When the field position and size are constant and the destination @@ -875,12 +1866,29 @@ ;; by a bicl or sign extension. Because we might end up choosing ext[z]v ;; anyway, we can't allow immediate values for the primary source operand. -(define_insn "*extv_non_const" +(define_insn_and_split "*extv_non_const" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extv_non_const_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2]) @@ -892,12 +1900,29 @@ return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; }") -(define_insn "*extzv_non_const" +(define_insn_and_split "*extzv_non_const" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extzv_non_const_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2]) @@ -918,24 +1943,24 @@ ;; nonimmediate_operand is used to make sure that mode-ambiguous cases ;; don't match these (and therefore match the cases above instead). -(define_insn "*cmpv_2" - [(set (cc0) - (compare +(define_insn "*cmpv_2_" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (sign_extract:SI (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpv %2,%1,%0,%3") -(define_insn "*cmpzv_2" - [(set (cc0) - (compare +(define_insn "*cmpzv_2_" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpzv %2,%1,%0,%3") (define_expand "extv" @@ -946,12 +1971,29 @@ "" "") -(define_insn "*extv" +(define_insn_and_split "*extv" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extv_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (!REG_P (operands[0]) || !CONST_INT_P (operands[2]) @@ -976,12 +2018,29 @@ "" "") -(define_insn "*extzv" +(define_insn_and_split "*extzv" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extzv_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (!REG_P (operands[0]) || !CONST_INT_P (operands[2]) @@ -1021,6 +2080,28 @@ return \"rotl %R3,%1,%0\;bicl2 %M2,%0\"; }") +;; Combine EXTV/CMPL and EXTZV/CMPL sequences where the output of +;; extraction is used for the comparison only into CMPV and CMPZV +;; respectively. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand") + (any_extract:SI (match_operand 1 "general_operand") + (match_operand:QI 2 "general_operand") + (match_operand:SI 3 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (match_dup 0) + (match_operand:SI 4 "general_operand")))] + "peep2_reg_dead_p (2, operands[0])" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc + (any_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3)) + (match_dup 4)))] + "") + (define_expand "insv" [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") (match_operand:QI 1 "general_operand" "") @@ -1029,6 +2110,7 @@ "" "") +;; This one actually doesn't change CC. (define_insn "*insv" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m") (match_operand:QI 1 "general_operand" "g") @@ -1060,6 +2142,7 @@ return \"insv %3,%2,%1,%0\"; }") +;; This one actually doesn't change CC. (define_insn "*insv_2" [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") (match_operand:QI 1 "general_operand" "g") @@ -1078,48 +2161,88 @@ ;; Conditional jumps (define_expand "cbranch4" - [(set (cc0) - (compare (match_operand:VAXint 1 "nonimmediate_operand" "") - (match_operand:VAXint 2 "general_operand" ""))) + [(set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" + [(match_operand:VAXint 1 "general_operand" "") + (match_operand:VAXint 2 "general_operand" "")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "") + +(define_insn_and_split "*cbranch4_" + [(set (pc) + (if_then_else + (match_operator 0 "vax__comparison_operator" + [(match_operand:VAXint 1 "general_operand" "nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "#" + "reload_completed" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (match_dup 1) (match_dup 2))) (set (pc) - (if_then_else - (match_operator 0 "ordered_comparison_operator" [(cc0) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "") + (if_then_else + (match_op_dup 0 [(reg:VAXcc VAX_PSL_REGNUM) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") (define_expand "cbranch4" - [(set (cc0) - (compare (match_operand:VAXfp 1 "general_operand" "") - (match_operand:VAXfp 2 "general_operand" ""))) + [(set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" + [(match_operand:VAXfp 1 "general_operand" "") + (match_operand:VAXfp 2 "general_operand" "")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "") + +(define_insn_and_split "*cbranch4_" + [(set (pc) + (if_then_else + (match_operator 0 "vax__comparison_operator" + [(match_operand:VAXfp 1 "general_operand" "gF") + (match_operand:VAXfp 2 "general_operand" "gF")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "#" + "reload_completed" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_dup 1) (match_dup 2))) (set (pc) - (if_then_else - (match_operator 0 "ordered_comparison_operator" [(cc0) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "") - -(define_insn "*branch" + (if_then_else + (match_op_dup 0 [(reg:VAXccnz VAX_PSL_REGNUM) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") + +(define_insn "*branch_" [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(cc0) + (if_then_else (match_operator 0 "vax__comparison_operator" + [(reg:VAXcc VAX_PSL_REGNUM) (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] - "" + "reload_completed" "j%k0 %l1") ;; Recognize reversed jumps. -(define_insn "*branch_reversed" +(define_insn "*branch__reversed" [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(cc0) + (if_then_else (match_operator 0 "vax__comparison_operator" + [(reg:VAXcc VAX_PSL_REGNUM) (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] - "" + "reload_completed" "j%K0 %l1") ; %K0 negates condition ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand @@ -1189,7 +2312,7 @@ ;; Normal sob insns. -(define_insn "" +(define_insn_and_split "*jsobgtr" [(set (pc) (if_then_else (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1201,9 +2324,38 @@ (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (gt (plus:SI (match_dup 0) + (const_int -1)) + (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jsobgtr_2" + [(set (pc) + (if_then_else + (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jsobgtr %0,%l1") -(define_insn "" +(define_insn_and_split "*jsobgeq" [(set (pc) (if_then_else (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1215,10 +2367,39 @@ (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (ge (plus:SI (match_dup 0) + (const_int -1)) + (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jsobgeq_2" + [(set (pc) + (if_then_else + (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jsobgeq %0,%l1") ;; Normal aob insns. Define a version for when operands[1] is a constant. -(define_insn "" +(define_insn_and_split "*jaoblss" [(set (pc) (if_then_else (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1230,9 +2411,38 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (lt (plus:SI (match_dup 0) + (const_int 1)) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaoblss_2" + [(set (pc) + (if_then_else + (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int 1)) + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jaoblss %1,%0,%l2") -(define_insn "" +(define_insn_and_split "*jaoblss_const" [(set (pc) (if_then_else (lt (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1243,9 +2453,36 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (lt (match_dup 0) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaoblss_const_2" + [(set (pc) + (if_then_else + (lt (match_operand:SI 0 "nonimmediate_operand" "+g") + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed" "jaoblss %P1,%0,%l2") -(define_insn "" +(define_insn_and_split "*jaobleq" [(set (pc) (if_then_else (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1257,9 +2494,38 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (le (plus:SI (match_dup 0) + (const_int 1)) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaobleq_2" + [(set (pc) + (if_then_else + (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int 1)) + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jaobleq %1,%0,%l2") -(define_insn "" +(define_insn_and_split "*jaobleq_const" [(set (pc) (if_then_else (le (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1270,12 +2536,39 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (le (match_dup 0) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaobleq_const_2" + [(set (pc) + (if_then_else + (le (match_operand:SI 0 "nonimmediate_operand" "+g") + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed" "jaobleq %P1,%0,%l2") ;; Something like a sob insn, but compares against -1. ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'. -(define_insn "" +(define_insn_and_split "*jsobneq_minus_one" [(set (pc) (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1286,6 +2579,33 @@ (plus:SI (match_dup 0) (const_int -1)))] "" + "#" + "reload_completed" + [(parallel + [(set (pc) + (if_then_else + (ne (match_dup 0) + (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jsobneq_minus_one_2" + [(set (pc) + (if_then_else + (ne (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "decl %0\;jgequ %l1") (define_expand "call_pop" @@ -1512,41 +2832,126 @@ ;; This insn is a bit of a lier. It actually falls through if no case ;; matches. But, we prevent that from ever happening by emitting a jump ;; before this, see the define_expand above. -(define_insn "casesi1" +(define_insn_and_split "casesi1" [(match_operand:SI 1 "const_int_operand" "n") (set (pc) (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT") - (const_int 2)) - (pc)))) + (mem:HI (plus:SI + (mult:SI + (match_operand:SI 0 "general_operand" "nrmT") + (const_int 2)) + (pc)))) (label_ref:SI (match_operand 2 "" ""))))] "" + "#" + "reload_completed" + [(parallel + [(match_dup 1) + (set (pc) + (plus:SI (sign_extend:SI + (mem:HI (plus:SI + (mult:SI + (match_dup 0) + (const_int 2)) + (pc)))) + (label_ref:SI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*casesi1" + [(match_operand:SI 1 "const_int_operand" "n") + (set (pc) + (plus:SI (sign_extend:SI + (mem:HI (plus:SI + (mult:SI + (match_operand:SI 0 "general_operand" "nrmT") + (const_int 2)) + (pc)))) + (label_ref:SI (match_operand 2 "" "")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "casel %0,$0,%1") -(define_insn "*pushsym" +(define_insn_and_split "*pushsym" [(set (match_operand:SI 0 "push_operand" "=g") (match_operand:SI 1 "pic_symbolic_operand" "A"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushsym_2" + [(set (match_operand:SI 0 "push_operand" "=g") + (match_operand:SI 1 "pic_symbolic_operand" "A")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "pushab %a1") -(define_insn "*movsym" +(define_insn_and_split "*movsym" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:SI 1 "pic_symbolic_operand" "A"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movsym_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:SI 1 "pic_symbolic_operand" "A")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movab %a1,%0") -(define_insn "*pushsymreg" +(define_insn_and_split "*pushsymreg" [(set (match_operand:SI 0 "push_operand" "=g") (plus:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "pic_symbolic_operand" "A")))] "flag_pic" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushsymreg_2" + [(set (match_operand:SI 0 "push_operand" "=g") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "flag_pic && reload_completed" "pushab %a2[%1]") -(define_insn "*movsymreg" +(define_insn_and_split "*movsymreg" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (plus:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "pic_symbolic_operand" "A")))] "flag_pic" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movsymreg_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "flag_pic && reload_completed" "movab %a2[%1],%0") ;;- load or push effective address @@ -1557,28 +2962,80 @@ ;; It does not work to use constraints to distinguish pushes from moves, ;; because < matches any autodecrement, not just a push. -(define_insn "pushaddr" +(define_insn_and_split "pushaddr" [(set (match_operand:SI 0 "push_operand" "=g") (match_operand:VAXintQHSD 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushaddr" + [(set (match_operand:SI 0 "push_operand" "=g") + (match_operand:VAXintQHSD 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "pusha %a1") -(define_insn "movaddr" +(define_insn_and_split "movaddr" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:VAXintQHSD 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movaddr" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:VAXintQHSD 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mova %a1,%0") -(define_insn "pushaddr" +(define_insn_and_split "pushaddr" [(set (match_operand:SI 0 "push_operand" "=g") (match_operand:VAXfp 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushaddr" + [(set (match_operand:SI 0 "push_operand" "=g") + (match_operand:VAXfp 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "pusha %a1") -(define_insn "movaddr" +(define_insn_and_split "movaddr" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:VAXfp 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movaddr" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:VAXfp 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mova %a1,%0") ;; These used to be peepholes, but it is more straightforward to do them @@ -1594,12 +3051,30 @@ ;; with other operands constant. This is what the combiner converts the ;; above sequences to before attempting to recognize the new insn. -(define_insn "" +(define_insn_and_split "*andashlnegsi4" [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (and:SI (ashiftrt:SI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*andashlnegsi4_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") + (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0 + && reload_completed" "* { unsigned long mask1 = INTVAL (operands[3]); @@ -1616,12 +3091,29 @@ ;; bits that the ashl would anyways, in which case it should have been ;; optimized away. -(define_insn "" +(define_insn_and_split "*andashlsi4" [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (and:SI (ashift:SI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*andashlsi4_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") + (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { operands[3] -- cgit v1.1 From 4f47fca1d0fc2c6efef791d6dd115abd9d221733 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:27 +0000 Subject: PR target/95294: VAX: Add test cases for MODE_CC representation gcc/testsuite/ PR target/95294 * gcc.target/vax/cmpelim-eq-adddf.c: New test. * gcc.target/vax/cmpelim-eq-addhi.c: New test. * gcc.target/vax/cmpelim-eq-addqi.c: New test. * gcc.target/vax/cmpelim-eq-addsf.c: New test. * gcc.target/vax/cmpelim-eq-addsi.c: New test. * gcc.target/vax/cmpelim-eq-andhi.c: New test. * gcc.target/vax/cmpelim-eq-andqi.c: New test. * gcc.target/vax/cmpelim-eq-andsi.c: New test. * gcc.target/vax/cmpelim-eq-ashlsi.c: New test. * gcc.target/vax/cmpelim-eq-ashrsi.c: New test. * gcc.target/vax/cmpelim-eq-divdf.c: New test. * gcc.target/vax/cmpelim-eq-divhi.c: New test. * gcc.target/vax/cmpelim-eq-divqi.c: New test. * gcc.target/vax/cmpelim-eq-divsf.c: New test. * gcc.target/vax/cmpelim-eq-divsi.c: New test. * gcc.target/vax/cmpelim-eq-extendhisi.c: New test. * gcc.target/vax/cmpelim-eq-extendqisi.c: New test. * gcc.target/vax/cmpelim-eq-extvsi.c: New test. * gcc.target/vax/cmpelim-eq-extzvsi.c: New test. * gcc.target/vax/cmpelim-eq-fixdfhi.c: New test. * gcc.target/vax/cmpelim-eq-fixdfqi.c: New test. * gcc.target/vax/cmpelim-eq-fixdfsi.c: New test. * gcc.target/vax/cmpelim-eq-fixsfhi.c: New test. * gcc.target/vax/cmpelim-eq-fixsfqi.c: New test. * gcc.target/vax/cmpelim-eq-fixsfsi.c: New test. * gcc.target/vax/cmpelim-eq-floatsisf.c: New test. * gcc.target/vax/cmpelim-eq-insvsi.c: New test. * gcc.target/vax/cmpelim-eq-iorhi.c: New test. * gcc.target/vax/cmpelim-eq-iorqi.c: New test. * gcc.target/vax/cmpelim-eq-iorsi.c: New test. * gcc.target/vax/cmpelim-eq-mova.c: New test. * gcc.target/vax/cmpelim-eq-movdf.c: New test. * gcc.target/vax/cmpelim-eq-movhi.c: New test. * gcc.target/vax/cmpelim-eq-movqi.c: New test. * gcc.target/vax/cmpelim-eq-movsf.c: New test. * gcc.target/vax/cmpelim-eq-movsi.c: New test. * gcc.target/vax/cmpelim-eq-muldf.c: New test. * gcc.target/vax/cmpelim-eq-mulhi.c: New test. * gcc.target/vax/cmpelim-eq-mulqi.c: New test. * gcc.target/vax/cmpelim-eq-mulsf.c: New test. * gcc.target/vax/cmpelim-eq-mulsi.c: New test. * gcc.target/vax/cmpelim-eq-nothi.c: New test. * gcc.target/vax/cmpelim-eq-notqi.c: New test. * gcc.target/vax/cmpelim-eq-notsi.c: New test. * gcc.target/vax/cmpelim-eq-rotlsi.c: New test. * gcc.target/vax/cmpelim-eq-rotrsi.c: New test. * gcc.target/vax/cmpelim-eq-subdf.c: New test. * gcc.target/vax/cmpelim-eq-subhi.c: New test. * gcc.target/vax/cmpelim-eq-subqi.c: New test. * gcc.target/vax/cmpelim-eq-subsf.c: New test. * gcc.target/vax/cmpelim-eq-subsi.c: New test. * gcc.target/vax/cmpelim-eq-truncdfsf.c: New test. * gcc.target/vax/cmpelim-eq-trunchiqi.c: New test. * gcc.target/vax/cmpelim-eq-truncsihi.c: New test. * gcc.target/vax/cmpelim-eq-truncsiqi.c: New test. * gcc.target/vax/cmpelim-eq-zextendhisi.c: New test. * gcc.target/vax/cmpelim-eq-zextendqihi.c: New test. * gcc.target/vax/cmpelim-eq-zextendqisi.c: New test. * gcc.target/vax/cmpelim-le-adddf.c: New test. * gcc.target/vax/cmpelim-le-addhi.c: New test. * gcc.target/vax/cmpelim-le-addqi.c: New test. * gcc.target/vax/cmpelim-le-addsf.c: New test. * gcc.target/vax/cmpelim-le-addsi.c: New test. * gcc.target/vax/cmpelim-le-andhi.c: New test. * gcc.target/vax/cmpelim-le-andqi.c: New test. * gcc.target/vax/cmpelim-le-andsi.c: New test. * gcc.target/vax/cmpelim-le-ashlsi.c: New test. * gcc.target/vax/cmpelim-le-ashrsi.c: New test. * gcc.target/vax/cmpelim-le-divdf.c: New test. * gcc.target/vax/cmpelim-le-divhi.c: New test. * gcc.target/vax/cmpelim-le-divqi.c: New test. * gcc.target/vax/cmpelim-le-divsf.c: New test. * gcc.target/vax/cmpelim-le-divsi.c: New test. * gcc.target/vax/cmpelim-le-extendhisi.c: New test. * gcc.target/vax/cmpelim-le-extendqisi.c: New test. * gcc.target/vax/cmpelim-le-extvsi.c: New test. * gcc.target/vax/cmpelim-le-extzvsi.c: New test. * gcc.target/vax/cmpelim-le-fixdfhi.c: New test. * gcc.target/vax/cmpelim-le-fixdfqi.c: New test. * gcc.target/vax/cmpelim-le-fixdfsi.c: New test. * gcc.target/vax/cmpelim-le-fixsfhi.c: New test. * gcc.target/vax/cmpelim-le-fixsfqi.c: New test. * gcc.target/vax/cmpelim-le-fixsfsi.c: New test. * gcc.target/vax/cmpelim-le-floatsisf.c: New test. * gcc.target/vax/cmpelim-le-insvsi.c: New test. * gcc.target/vax/cmpelim-le-iorhi.c: New test. * gcc.target/vax/cmpelim-le-iorqi.c: New test. * gcc.target/vax/cmpelim-le-iorsi.c: New test. * gcc.target/vax/cmpelim-le-movdf.c: New test. * gcc.target/vax/cmpelim-le-movhi.c: New test. * gcc.target/vax/cmpelim-le-movqi.c: New test. * gcc.target/vax/cmpelim-le-movsf.c: New test. * gcc.target/vax/cmpelim-le-movsi.c: New test. * gcc.target/vax/cmpelim-le-muldf.c: New test. * gcc.target/vax/cmpelim-le-mulhi.c: New test. * gcc.target/vax/cmpelim-le-mulqi.c: New test. * gcc.target/vax/cmpelim-le-mulsf.c: New test. * gcc.target/vax/cmpelim-le-mulsi.c: New test. * gcc.target/vax/cmpelim-le-nothi.c: New test. * gcc.target/vax/cmpelim-le-notqi.c: New test. * gcc.target/vax/cmpelim-le-notsi.c: New test. * gcc.target/vax/cmpelim-le-rotlsi.c: New test. * gcc.target/vax/cmpelim-le-rotrsi.c: New test. * gcc.target/vax/cmpelim-le-subdf.c: New test. * gcc.target/vax/cmpelim-le-subhi.c: New test. * gcc.target/vax/cmpelim-le-subqi.c: New test. * gcc.target/vax/cmpelim-le-subsf.c: New test. * gcc.target/vax/cmpelim-le-subsi.c: New test. * gcc.target/vax/cmpelim-le-truncdfsf.c: New test. * gcc.target/vax/cmpelim-le-xorhi.c: New test. * gcc.target/vax/cmpelim-le-xorqi.c: New test. * gcc.target/vax/cmpelim-le-xorsi.c: New test. * gcc.target/vax/cmpelim-leu-subhi.c: New test. * gcc.target/vax/cmpelim-leu-subqi.c: New test. * gcc.target/vax/cmpelim-leu-subsi.c: New test. * gcc.target/vax/cmpelim-lt-adddf.c: New test. * gcc.target/vax/cmpelim-lt-addhi.c: New test. * gcc.target/vax/cmpelim-lt-addqi.c: New test. * gcc.target/vax/cmpelim-lt-addsf.c: New test. * gcc.target/vax/cmpelim-lt-addsi.c: New test. * gcc.target/vax/cmpelim-lt-andhi.c: New test. * gcc.target/vax/cmpelim-lt-andqi.c: New test. * gcc.target/vax/cmpelim-lt-andsi.c: New test. * gcc.target/vax/cmpelim-lt-ashlsi.c: New test. * gcc.target/vax/cmpelim-lt-ashrsi.c: New test. * gcc.target/vax/cmpelim-lt-divdf.c: New test. * gcc.target/vax/cmpelim-lt-divhi.c: New test. * gcc.target/vax/cmpelim-lt-divqi.c: New test. * gcc.target/vax/cmpelim-lt-divsf.c: New test. * gcc.target/vax/cmpelim-lt-divsi.c: New test. * gcc.target/vax/cmpelim-lt-extendhisi.c: New test. * gcc.target/vax/cmpelim-lt-extendqisi.c: New test. * gcc.target/vax/cmpelim-lt-extvsi.c: New test. * gcc.target/vax/cmpelim-lt-extzvsi.c: New test. * gcc.target/vax/cmpelim-lt-fixdfhi.c: New test. * gcc.target/vax/cmpelim-lt-fixdfqi.c: New test. * gcc.target/vax/cmpelim-lt-fixdfsi.c: New test. * gcc.target/vax/cmpelim-lt-fixsfhi.c: New test. * gcc.target/vax/cmpelim-lt-fixsfqi.c: New test. * gcc.target/vax/cmpelim-lt-fixsfsi.c: New test. * gcc.target/vax/cmpelim-lt-floatsisf.c: New test. * gcc.target/vax/cmpelim-lt-insvsi.c: New test. * gcc.target/vax/cmpelim-lt-iorhi.c: New test. * gcc.target/vax/cmpelim-lt-iorqi.c: New test. * gcc.target/vax/cmpelim-lt-iorsi.c: New test. * gcc.target/vax/cmpelim-lt-movdf.c: New test. * gcc.target/vax/cmpelim-lt-movhi.c: New test. * gcc.target/vax/cmpelim-lt-movqi.c: New test. * gcc.target/vax/cmpelim-lt-movsf.c: New test. * gcc.target/vax/cmpelim-lt-movsi.c: New test. * gcc.target/vax/cmpelim-lt-muldf.c: New test. * gcc.target/vax/cmpelim-lt-mulhi.c: New test. * gcc.target/vax/cmpelim-lt-mulqi.c: New test. * gcc.target/vax/cmpelim-lt-mulsf.c: New test. * gcc.target/vax/cmpelim-lt-mulsi.c: New test. * gcc.target/vax/cmpelim-lt-nothi.c: New test. * gcc.target/vax/cmpelim-lt-notqi.c: New test. * gcc.target/vax/cmpelim-lt-notsi.c: New test. * gcc.target/vax/cmpelim-lt-rotlsi.c: New test. * gcc.target/vax/cmpelim-lt-rotrsi.c: New test. * gcc.target/vax/cmpelim-lt-subdf.c: New test. * gcc.target/vax/cmpelim-lt-subhi.c: New test. * gcc.target/vax/cmpelim-lt-subqi.c: New test. * gcc.target/vax/cmpelim-lt-subsf.c: New test. * gcc.target/vax/cmpelim-lt-subsi.c: New test. * gcc.target/vax/cmpelim-lt-truncdfsf.c: New test. * gcc.target/vax/cmpelim-lt-xorhi.c: New test. * gcc.target/vax/cmpelim-lt-xorqi.c: New test. * gcc.target/vax/cmpelim-lt-xorsi.c: New test. * gcc.target/vax/cmpelim-ltu-subhi.c: New test. * gcc.target/vax/cmpelim-ltu-subqi.c: New test. * gcc.target/vax/cmpelim-ltu-subsi.c: New test. * gcc.target/vax/cmpelim-xx-addsi.c: New test. * gcc.target/vax/cmpelim-xx-insvsi.c: New test. * gcc.target/vax/cmpelim-xxu-subsi.c: New test. * gcc.target/vax/peephole2-eq-andhi.c: New test. * gcc.target/vax/peephole2-eq-andqi.c: New test. * gcc.target/vax/peephole2-eq-andsi.c: New test. * gcc.target/vax/peephole2-eq-cmpvsi.c: New test. * gcc.target/vax/peephole2-eq-cmpzvsi.c: New test. * gcc.target/vax/peephole2-eq-ctzhi-0.c: New test. * gcc.target/vax/peephole2-eq-ctzhi-1.c: New test. * gcc.target/vax/peephole2-eq-ctzqi-0.c: New test. * gcc.target/vax/peephole2-eq-ctzqi-1.c: New test. * gcc.target/vax/peephole2-eq-ctzsi-0.c: New test. * gcc.target/vax/peephole2-eq-ctzsi-1.c: New test. * gcc.target/vax/peephole2-eq-ffshi.c: New test. * gcc.target/vax/peephole2-eq-ffsqi.c: New test. * gcc.target/vax/peephole2-eq-ffssi.c: New test. * gcc.target/vax/peephole2-le-andhi.c: New test. * gcc.target/vax/peephole2-le-andqi.c: New test. * gcc.target/vax/peephole2-le-andsi.c: New test. * gcc.target/vax/peephole2-le-cmpvsi.c: New test. * gcc.target/vax/peephole2-le-cmpzvsi.c: New test. * gcc.target/vax/peephole2-leu-cmpvsi.c: New test. * gcc.target/vax/peephole2-leu-cmpzvsi.c: New test. * gcc.target/vax/peephole2-lt-andhi.c: New test. * gcc.target/vax/peephole2-lt-andqi.c: New test. * gcc.target/vax/peephole2-lt-andsi.c: New test. * gcc.target/vax/peephole2-lt-cmpvsi.c: New test. * gcc.target/vax/peephole2-lt-cmpzvsi.c: New test. * gcc.target/vax/peephole2-ltu-cmpvsi.c: New test. * gcc.target/vax/peephole2-ltu-cmpzvsi.c: New test. --- gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c | 29 ++++++++++++ .../gcc.target/vax/cmpelim-eq-extendhisi.c | 30 ++++++++++++ .../gcc.target/vax/cmpelim-eq-extendqisi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c | 38 ++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c | 39 ++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c | 32 +++++++++++++ .../gcc.target/vax/cmpelim-eq-floatsisf.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c | 46 +++++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c | 34 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c | 29 ++++++++++++ .../gcc.target/vax/cmpelim-eq-truncdfsf.c | 32 +++++++++++++ .../gcc.target/vax/cmpelim-eq-trunchiqi.c | 33 ++++++++++++++ .../gcc.target/vax/cmpelim-eq-truncsihi.c | 33 ++++++++++++++ .../gcc.target/vax/cmpelim-eq-truncsiqi.c | 33 ++++++++++++++ .../gcc.target/vax/cmpelim-eq-zextendhisi.c | 30 ++++++++++++ .../gcc.target/vax/cmpelim-eq-zextendqihi.c | 32 +++++++++++++ .../gcc.target/vax/cmpelim-eq-zextendqisi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c | 29 ++++++++++++ .../gcc.target/vax/cmpelim-le-extendhisi.c | 30 ++++++++++++ .../gcc.target/vax/cmpelim-le-extendqisi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c | 38 ++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c | 32 +++++++++++++ .../gcc.target/vax/cmpelim-le-floatsisf.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c | 46 +++++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c | 34 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c | 29 ++++++++++++ .../gcc.target/vax/cmpelim-le-truncdfsf.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c | 29 ++++++++++++ .../gcc.target/vax/cmpelim-lt-extendhisi.c | 30 ++++++++++++ .../gcc.target/vax/cmpelim-lt-extendqisi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c | 38 ++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c | 32 +++++++++++++ .../gcc.target/vax/cmpelim-lt-floatsisf.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c | 46 +++++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c | 28 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c | 34 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c | 29 ++++++++++++ .../gcc.target/vax/cmpelim-lt-truncdfsf.c | 32 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c | 29 ++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c | 36 +++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c | 53 ++++++++++++++++++++++ gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c | 40 ++++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c | 36 +++++++++++++++ .../gcc.target/vax/peephole2-eq-cmpzvsi.c | 36 +++++++++++++++ .../gcc.target/vax/peephole2-eq-ctzhi-0.c | 32 +++++++++++++ .../gcc.target/vax/peephole2-eq-ctzhi-1.c | 34 ++++++++++++++ .../gcc.target/vax/peephole2-eq-ctzqi-0.c | 32 +++++++++++++ .../gcc.target/vax/peephole2-eq-ctzqi-1.c | 34 ++++++++++++++ .../gcc.target/vax/peephole2-eq-ctzsi-0.c | 32 +++++++++++++ .../gcc.target/vax/peephole2-eq-ctzsi-1.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c | 26 +++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c | 26 +++++++++++ gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c | 27 +++++++++++ gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c | 36 +++++++++++++++ .../gcc.target/vax/peephole2-le-cmpzvsi.c | 34 ++++++++++++++ .../gcc.target/vax/peephole2-leu-cmpvsi.c | 40 ++++++++++++++++ .../gcc.target/vax/peephole2-leu-cmpzvsi.c | 31 +++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c | 33 ++++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c | 30 ++++++++++++ gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c | 36 +++++++++++++++ .../gcc.target/vax/peephole2-lt-cmpzvsi.c | 34 ++++++++++++++ .../gcc.target/vax/peephole2-ltu-cmpvsi.c | 40 ++++++++++++++++ .../gcc.target/vax/peephole2-ltu-cmpzvsi.c | 31 +++++++++++++ 203 files changed, 6382 insertions(+) create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c new file mode 100644 index 0000000..872d46b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +eq_adddf (float_t x, float_t y) +{ + x += y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addd3 4(%ap),12(%ap),%r0 # 35 [c=68] *adddf3_ccz/2 + jeql .L1 # 37 [c=26] *branch_ccz + addd2 $0d2.0e+0,%r0 # 34 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "adddf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c new file mode 100644 index 0000000..3a5dbad --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_addhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x + *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + addw3 *8(%ap),*12(%ap),%r0 # 33 [c=64] *addhi3_ccz + jeql .L2 # 35 [c=26] *branch_ccz + addw2 $2,%r0 # 32 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c new file mode 100644 index 0000000..b0fe468 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_addqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x + *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + addb3 *8(%ap),*12(%ap),%r0 # 33 [c=64] *addqi3_ccz + jeql .L2 # 35 [c=26] *branch_ccz + addb2 $2,%r0 # 32 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c new file mode 100644 index 0000000..de9e9c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +eq_addsf (float_t x, float_t y) +{ + x += y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addf3 4(%ap),8(%ap),%r0 # 34 [c=48] *addsf3_ccz/2 + jeql .L1 # 36 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 33 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c new file mode 100644 index 0000000..6998e60 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_addsi (int_t x, int_t y) +{ + x += y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addl3 4(%ap),8(%ap),%r0 # 33 [c=48] *addsi3_ccz + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c new file mode 100644 index 0000000..d4d0c59 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_andhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & ~*y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bicw3 *12(%ap),*8(%ap),%r0 # 34 [c=44] *andhi3_2_ccz/1 + jeql .L2 # 36 [c=26] *branch_ccz + addw2 $2,%r0 # 33 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c new file mode 100644 index 0000000..efa0dfe --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_andqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & ~*y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bicb3 *12(%ap),*8(%ap),%r0 # 34 [c=44] *andqi3_2_ccz/1 + jeql .L2 # 36 [c=26] *branch_ccz + addb2 $2,%r0 # 33 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c new file mode 100644 index 0000000..9afc860 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_andsi (int_t x, int_t y) +{ + x &= ~y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + bicl3 8(%ap),4(%ap),%r0 # 35 [c=28] *andsi3_2_ccz/1 + jeql .L1 # 37 [c=26] *branch_ccz + addl2 $2,%r0 # 34 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c new file mode 100644 index 0000000..a824f2d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +eq_ashlsi (int_t x, short_t y) +{ + x <<= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + ashl 8(%ap),4(%ap),%r0 # 35 [c=56] *ashlsi3_ccz + jeql .L1 # 37 [c=26] *branch_ccz + addl2 $2,%r0 # 34 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ashlsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c new file mode 100644 index 0000000..5f1e3a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +eq_ashrsi (int_t x, short_t y) +{ + x >>= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mnegb 8(%ap),%r0 # 36 [c=16] *negqi2 + ashl %r0,4(%ap),%r0 # 37 [c=52] *ashlnegsi3_2_ccz + jeql .L1 # 39 [c=26] *branch_ccz + addl2 $2,%r0 # 35 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ashlnegsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c new file mode 100644 index 0000000..7101960 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +eq_divdf (float_t x, float_t y) +{ + x /= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divd3 12(%ap),4(%ap),%r0 # 35 [c=112] *divdf3_ccz/1 + jeql .L1 # 37 [c=26] *branch_ccz + addd2 $0d2.0e+0,%r0 # 34 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divdf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c new file mode 100644 index 0000000..03866f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI), vector_size (2))) int_t; + +void +eq_divhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x / *y; + if (v[0] == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + divw3 *12(%ap),*8(%ap),%r0 # 38 [c=76] *divhi3_ccz/1 + jeql .L2 # 40 [c=26] *branch_ccz + addw2 $2,%r0 # 37 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c new file mode 100644 index 0000000..e4cfbf0 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI), vector_size (1))) int_t; + +void +eq_divqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x / *y; + if (v[0] == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + divb3 *12(%ap),*8(%ap),%r0 # 38 [c=76] *divqi3_ccz/1 + jeql .L2 # 40 [c=26] *branch_ccz + addb2 $2,%r0 # 37 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c new file mode 100644 index 0000000..492becf --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +eq_divsf (float_t x, float_t y) +{ + x /= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divf3 8(%ap),4(%ap),%r0 # 34 [c=60] *divsf3_ccz/1 + jeql .L1 # 36 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 33 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c new file mode 100644 index 0000000..324614f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_divsi (int_t x, int_t y) +{ + x /= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divl3 8(%ap),4(%ap),%r0 # 33 [c=60] *divsi3_ccz/1 + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c new file mode 100644 index 0000000..f875da9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (HI))) short_t; + +int_t +eq_extendhisi (int_t x) +{ + x = (short_t) x; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + cvtwl 4(%ap),%r0 # 33 [c=20] *extendhisi2_ccz + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extendhisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c new file mode 100644 index 0000000..16a6acd --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +eq_extendqisi (int_t x) +{ + x = (short_t) x; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + cvtbl 4(%ap),%r0 # 33 [c=20] *extendqisi2_ccz + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extendqisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c new file mode 100644 index 0000000..5383059 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +eq_extvsi (bit_t x) +{ + int_t v; + + v = x.i; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + extv $7,$18,4(%ap),%r0 # 32 [c=68] *extv_non_const_2_ccz + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c new file mode 100644 index 0000000..d21fa29 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +eq_extzvsi (bit_t x) +{ + int_t v; + + v = x.i; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + rotl $25,4(%ap),%r0 # 32 [c=68] *extzv_non_const_2_ccz + bicl2 $-262144,%r0 + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extzv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c new file mode 100644 index 0000000..8912d14 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_fixdfhi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtdw 8(%ap),%r0 # 31 [c=36] *fix_truncdfhi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addw2 $2,%r0 # 30 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c new file mode 100644 index 0000000..12f9385 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_fixdfqi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtdb 8(%ap),%r0 # 31 [c=36] *fix_truncdfqi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addb2 $2,%r0 # 30 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c new file mode 100644 index 0000000..ad54d88 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_fixdfsi (float_t x) +{ + int_t v; + + v = x; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtdl 4(%ap),%r0 # 32 [c=36] *fix_truncdfsi2_ccz + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c new file mode 100644 index 0000000..0c26857 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_fixsfhi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtfw 8(%ap),%r0 # 31 [c=36] *fix_truncsfhi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addw2 $2,%r0 # 30 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c new file mode 100644 index 0000000..2d32525 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_fixsfqi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtfb 8(%ap),%r0 # 31 [c=36] *fix_truncsfqi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addb2 $2,%r0 # 30 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c new file mode 100644 index 0000000..a704ad8 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_fixsfsi (float_t x) +{ + int_t v; + + v = x; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtfl 4(%ap),%r0 # 32 [c=36] *fix_truncsfsi2_ccz + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c new file mode 100644 index 0000000..1ea83cc --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +float_t +eq_floatsisf (int_t x) +{ + float_t v; + + v = x; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtlf 4(%ap),%r0 # 33 [c=32] *floatsisf2_ccz + jeql .L1 # 35 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 32 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "floatsisf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c new file mode 100644 index 0000000..fbdcdb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef union + { + int_t i; + struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } b; + } +bit_t; + +int +eq_insvsi (bit_t x, int_t y) +{ + int_t v; + + v = x.b.i; + x.b.i = y; + if (v != 0) + return x.i; + else + return x.i + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 35 [c=16] *movsi_2 + extv $7,$18,%r0,%r1 # 36 [c=60] *extv_non_const_2_ccz + insv 8(%ap),$7,$18,%r0 # 8 [c=16] *insv_2 + jneq .L1 # 38 [c=26] *branch_ccz + addl2 $2,%r0 # 34 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "extv.*insv.*branch" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c new file mode 100644 index 0000000..9bbe881 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_iorhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x | *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bisw3 *12(%ap),*8(%ap),%r0 # 32 [c=44] *iorhi3_ccz/2 + jeql .L2 # 34 [c=26] *branch_ccz + addw2 $2,%r0 # 31 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c new file mode 100644 index 0000000..82f3f6b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_iorqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x | *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bisb3 *12(%ap),*8(%ap),%r0 # 32 [c=44] *iorqi3_ccz/2 + jeql .L2 # 34 [c=26] *branch_ccz + addb2 $2,%r0 # 31 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c new file mode 100644 index 0000000..dd4490d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_iorsi (int_t x, int_t y) +{ + x |= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + bisl3 8(%ap),4(%ap),%r0 # 33 [c=28] *iorsi3_ccz/2 + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c new file mode 100644 index 0000000..286025f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +extern char __attribute__ ((weak)) c; + +char * +eq_mova (char *p) +{ + char *v; + + v = &c; + if (v) + return v; + return p; +} + +/* Expect assembly like: + + movab c,%r0 # 35 [c=12] *movsym_2_ccz + jeql .L6 # 37 [c=26] *branch_ccz + ret # 43 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsym\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c new file mode 100644 index 0000000..c83e966 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +eq_movdf (float_t x) +{ + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movd 4(%ap),%r0 # 34 [c=24] *movdf_ccz/1 + jeql .L2 # 36 [c=26] *branch_ccz + addd2 $0d2.0e+0,%r0 # 33 [c=56] *adddf3/0 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movdf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c new file mode 100644 index 0000000..99832dc --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_movhi (int_t *w, int_t *x) +{ + int_t v; + + v = *x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movw *8(%ap),%r0 # 31 [c=24] *movhi_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addw2 $2,%r0 # 30 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c new file mode 100644 index 0000000..5014b8b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_movqi (int_t *w, int_t *x) +{ + int_t v; + + v = *x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movb *8(%ap),%r0 # 31 [c=24] *movqi_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addb2 $2,%r0 # 30 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c new file mode 100644 index 0000000..8907461 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +eq_movsf (float_t x) +{ + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movf 4(%ap),%r0 # 33 [c=16] *movsf_ccz/1 + jeql .L2 # 35 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 32 [c=36] *addsf3/0 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c new file mode 100644 index 0000000..1e65f4b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_movsi (int_t x) +{ + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 32 [c=16] *movsi_2_ccz + jeql .L2 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c new file mode 100644 index 0000000..7271c21 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +eq_muldf (float_t x, float_t y) +{ + x *= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + muld3 4(%ap),12(%ap),%r0 # 35 [c=80] *muldf3_ccz/2 + jeql .L1 # 37 [c=26] *branch_ccz + addd2 $0d2.0e+0,%r0 # 34 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "muldf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c new file mode 100644 index 0000000..d44a622 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_mulhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x * *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mulw3 *8(%ap),*12(%ap),%r0 # 33 [c=72] *mulhi3_ccz/2 + jeql .L2 # 35 [c=26] *branch_ccz + addw2 $2,%r0 # 32 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c new file mode 100644 index 0000000..2451843 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_mulqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x * *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mulb3 *8(%ap),*12(%ap),%r0 # 33 [c=72] *mulqi3_ccz/2 + jeql .L2 # 35 [c=26] *branch_ccz + addb2 $2,%r0 # 32 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c new file mode 100644 index 0000000..824487b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +eq_mulsf (float_t x, float_t y) +{ + x *= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mulf3 4(%ap),8(%ap),%r0 # 34 [c=52] *mulsf3_ccz/2 + jeql .L1 # 36 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 33 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c new file mode 100644 index 0000000..fbefa54 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_mulsi (int_t x, int_t y) +{ + x *= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mull3 4(%ap),8(%ap),%r0 # 33 [c=56] *mulsi3_ccz/2 + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c new file mode 100644 index 0000000..79b274c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_nothi (int_t *w, int_t *x) +{ + int_t v; + + v = ~*x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mcomw *8(%ap),%r0 # 31 [c=24] *one_cmplhi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addw2 $2,%r0 # 30 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c new file mode 100644 index 0000000..ae98a2f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_notqi (int_t *w, int_t *x) +{ + int_t v; + + v = ~*x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mcomb *8(%ap),%r0 # 31 [c=24] *one_cmplqi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addb2 $2,%r0 # 30 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c new file mode 100644 index 0000000..ba5b735 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_notsi (int_t x) +{ + x = ~x; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mcoml 4(%ap),%r0 # 32 [c=16] *one_cmplsi2_ccz + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c new file mode 100644 index 0000000..17c4868 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) ulong_t; +typedef int __attribute__ ((mode (SI))) long_t; +typedef int __attribute__ ((mode (QI))) int_t; + +ulong_t +eq_rotlsi (ulong_t x, int_t y) +{ + long_t v; + + v = x << y | x >> 8 * sizeof (x) - y; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + rotl 8(%ap),4(%ap),%r0 # 36 [c=40] *rotlsi3_ccz + jeql .L1 # 38 [c=26] *branch_ccz + addl2 $2,%r0 # 35 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "rotlsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c new file mode 100644 index 0000000..ffbca23 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) ulong_t; +typedef int __attribute__ ((mode (SI))) long_t; +typedef int __attribute__ ((mode (QI))) int_t; + +ulong_t +eq_rotrsi (ulong_t x, int_t y) +{ + long_t v; + + v = x >> y | x << 8 * sizeof (x) - y; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + mnegb 8(%ap),%r0 # 37 [c=16] *negqi2 + rotl %r0,4(%ap),%r0 # 38 [c=36] *rotrnegsi3_2_ccz + jeql .L1 # 40 [c=26] *branch_ccz + addl2 $2,%r0 # 36 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "rotrnegsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c new file mode 100644 index 0000000..a8d3f1f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +eq_subdf (float_t x, float_t y) +{ + x -= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subd3 12(%ap),4(%ap),%r0 # 35 [c=68] *subdf3_ccz/1 + jeql .L1 # 37 [c=26] *branch_ccz + addd2 $0d2.0e+0,%r0 # 34 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subdf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c new file mode 100644 index 0000000..f01b4b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_subhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + subw3 *12(%ap),*8(%ap),%r0 # 33 [c=64] *subhi3_ccz/1 + jeql .L2 # 35 [c=26] *branch_ccz + addw2 $2,%r0 # 32 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c new file mode 100644 index 0000000..733e30f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_subqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + subb3 *12(%ap),*8(%ap),%r0 # 33 [c=64] *subqi3_ccz/1 + jeql .L2 # 35 [c=26] *branch_ccz + addb2 $2,%r0 # 32 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c new file mode 100644 index 0000000..34e8555 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +eq_subsf (float_t x, float_t y) +{ + x -= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subf3 8(%ap),4(%ap),%r0 # 34 [c=48] *subsf3_ccz/1 + jeql .L1 # 36 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 33 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c new file mode 100644 index 0000000..456e35a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_subsi (int_t x, int_t y) +{ + x -= y; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subl3 8(%ap),4(%ap),%r0 # 33 [c=48] *subsi3_ccz/1 + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c new file mode 100644 index 0000000..7192d87 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) single_t; +typedef float __attribute__ ((mode (DF))) double_t; + +single_t +eq_truncdfsf (double_t x) +{ + single_t v; + + v = x; + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtdf 4(%ap),%r0 # 33 [c=20] *truncdfsf2_ccz + jeql .L1 # 35 [c=26] *branch_ccz + addf2 $0f2.0e+0,%r0 # 32 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "truncdfsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c new file mode 100644 index 0000000..9e7a885 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (HI))) int_t; +typedef unsigned int __attribute__ ((mode (QI))) short_t; + +void +eq_trunchiqi (short_t *w, int_t *x, int y) +{ + short_t v; + + v = x[y]; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movl 12(%ap),%r0 # 33 [c=16] *movsi_2 + cvtwb *8(%ap)[%r0],%r0 # 34 [c=28] *trunchiqi2_ccz + jeql .L2 # 36 [c=26] *branch_ccz + addb2 $2,%r0 # 32 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "trunchiqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c new file mode 100644 index 0000000..36dd7df --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; +typedef unsigned int __attribute__ ((mode (HI))) short_t; + +void +eq_truncsihi (short_t *w, int_t *x, int y) +{ + short_t v; + + v = x[y]; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movl 12(%ap),%r0 # 33 [c=16] *movsi_2 + cvtlw *8(%ap)[%r0],%r0 # 34 [c=28] *truncsihi2_ccz + jeql .L2 # 36 [c=26] *branch_ccz + addw2 $2,%r0 # 32 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "truncsihi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c new file mode 100644 index 0000000..a0ee4cf --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; +typedef unsigned int __attribute__ ((mode (QI))) short_t; + +void +eq_truncsiqi (short_t *w, int_t *x, int y) +{ + short_t v; + + v = x[y]; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movl 12(%ap),%r0 # 33 [c=16] *movsi_2 + cvtlb *8(%ap)[%r0],%r0 # 34 [c=28] *truncsiqi2_ccz + jeql .L2 # 36 [c=26] *branch_ccz + addb2 $2,%r0 # 32 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "truncsiqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c new file mode 100644 index 0000000..2fa86dd --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; +typedef unsigned int __attribute__ ((mode (HI))) short_t; + +int_t +eq_zextendhisi (int_t x) +{ + x = (short_t) x; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movzwl 4(%ap),%r0 # 32 [c=20] *zero_extendhisi2_ccz + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "zero_extendhisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c new file mode 100644 index 0000000..16613c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (HI))) int_t; +typedef unsigned int __attribute__ ((mode (QI))) short_t; + +void +eq_zextendqihi (int_t *w, int_t *x) +{ + int_t v; + + v = (short_t) *x; + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movzbw *8(%ap),%r0 # 31 [c=28] *zero_extendqihi2_ccz + jeql .L2 # 33 [c=26] *branch_ccz + addw2 $2,%r0 # 30 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "zero_extendqihi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c new file mode 100644 index 0000000..bb75f73 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; +typedef unsigned int __attribute__ ((mode (QI))) short_t; + +int_t +eq_zextendqisi (int_t x) +{ + x = (short_t) x; + if (x == 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movzbl 4(%ap),%r0 # 32 [c=20] *zero_extendqisi2_ccz + jeql .L1 # 34 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "zero_extendqisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c new file mode 100644 index 0000000..383d51d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +le_adddf (float_t x, float_t y) +{ + x += y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addd3 4(%ap),12(%ap),%r0 # 29 [c=68] *adddf3_ccnz/2 + jleq .L1 # 31 [c=26] *branch_ccnz + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "adddf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c new file mode 100644 index 0000000..19cc621 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_addhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x + *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + addw3 *8(%ap),*12(%ap),%r0 # 29 [c=64] *addhi3_ccnz + jleq .L2 # 31 [c=26] *branch_ccnz + addw2 $2,%r0 # 28 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c new file mode 100644 index 0000000..291beb0 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_addqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x + *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + addb3 *8(%ap),*12(%ap),%r0 # 29 [c=64] *addqi3_ccnz + jleq .L2 # 31 [c=26] *branch_ccnz + addb2 $2,%r0 # 28 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c new file mode 100644 index 0000000..e4596fe --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +le_addsf (float_t x, float_t y) +{ + x += y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addf3 4(%ap),8(%ap),%r0 # 28 [c=48] *addsf3_ccnz/2 + jleq .L1 # 30 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c new file mode 100644 index 0000000..254b30c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_addsi (int_t x, int_t y) +{ + x += y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addl3 4(%ap),8(%ap),%r0 # 29 [c=48] *addsi3_ccnz + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c new file mode 100644 index 0000000..ddf04d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_andhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & ~*y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bicw3 *12(%ap),*8(%ap),%r0 # 30 [c=44] *andhi3_2_ccnz/1 + jleq .L2 # 32 [c=26] *branch_ccnz + addw2 $2,%r0 # 29 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c new file mode 100644 index 0000000..bd781dc --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_andqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & ~*y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bicb3 *12(%ap),*8(%ap),%r0 # 30 [c=44] *andqi3_2_ccnz/1 + jleq .L2 # 32 [c=26] *branch_ccnz + addb2 $2,%r0 # 29 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c new file mode 100644 index 0000000..81fd7ba --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_andsi (int_t x, int_t y) +{ + x &= ~y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + bicl3 8(%ap),4(%ap),%r0 # 31 [c=28] *andsi3_2_ccnz/1 + jleq .L1 # 33 [c=26] *branch_ccnz + addl2 $2,%r0 # 30 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c new file mode 100644 index 0000000..2b67742 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +le_ashlsi (int_t x, short_t y) +{ + x <<= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + ashl 8(%ap),4(%ap),%r0 # 31 [c=56] *ashlsi3_ccnz + jleq .L1 # 33 [c=26] *branch_ccnz + addl2 $2,%r0 # 30 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ashlsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c new file mode 100644 index 0000000..c4d9f28 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +le_ashrsi (int_t x, short_t y) +{ + x >>= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mnegb 8(%ap),%r0 # 32 [c=16] *negqi2 + ashl %r0,4(%ap),%r0 # 33 [c=52] *ashlnegsi3_2_ccnz + jleq .L1 # 35 [c=26] *branch_ccnz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ashlnegsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c new file mode 100644 index 0000000..62b419c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +le_divdf (float_t x, float_t y) +{ + x /= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divd3 12(%ap),4(%ap),%r0 # 29 [c=112] *divdf3_ccnz/1 + jleq .L1 # 31 [c=26] *branch_ccnz + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divdf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c new file mode 100644 index 0000000..68ee484 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI), vector_size (2))) int_t; + +void +le_divhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x / *y; + if (v[0] <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + divw3 *12(%ap),*8(%ap),%r0 # 34 [c=76] *divhi3_ccnz/1 + jleq .L2 # 36 [c=26] *branch_ccnz + addw2 $2,%r0 # 33 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c new file mode 100644 index 0000000..e0b0cd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI), vector_size (1))) int_t; + +void +le_divqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x / *y; + if (v[0] <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + divb3 *12(%ap),*8(%ap),%r0 # 34 [c=76] *divqi3_ccnz/1 + jleq .L2 # 36 [c=26] *branch_ccnz + addb2 $2,%r0 # 33 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c new file mode 100644 index 0000000..b55b36e --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +le_divsf (float_t x, float_t y) +{ + x /= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divf3 8(%ap),4(%ap),%r0 # 28 [c=60] *divsf3_ccnz/1 + jleq .L1 # 30 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c new file mode 100644 index 0000000..6a45a38 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_divsi (int_t x, int_t y) +{ + x /= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divl3 8(%ap),4(%ap),%r0 # 29 [c=60] *divsi3_ccnz/1 + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c new file mode 100644 index 0000000..693c752f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (HI))) short_t; + +int_t +le_extendhisi (int_t x) +{ + x = (short_t) x; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + cvtwl 4(%ap),%r0 # 29 [c=20] *extendhisi2_ccnz + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extendhisi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c new file mode 100644 index 0000000..4965bcf --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +le_extendqisi (int_t x) +{ + x = (short_t) x; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + cvtbl 4(%ap),%r0 # 29 [c=20] *extendqisi2_ccnz + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extendqisi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c new file mode 100644 index 0000000..641c8f0d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +le_extvsi (bit_t x) +{ + int_t v; + + v = x.i; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + extv $7,$18,4(%ap),%r0 # 28 [c=68] *extv_non_const_2_ccnz + jleq .L1 # 30 [c=26] *branch_ccnz + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c new file mode 100644 index 0000000..18dd7ff --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef int __attribute__ ((mode (SI))) int_t; + +uint_t +le_extzvsi (uint_t x, int_t y) +{ + int_t v; + + v = x >> y; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + subb3 8(%ap),$32,%r0 # 31 [c=40] *subqi3/1 + extzv 8(%ap),%r0,4(%ap),%r0 # 32 [c=76] *extzv_non_const_2_ccnz + jleq .L1 # 34 [c=26] *branch_ccnz + addl2 $2,%r0 # 30 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extzv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c new file mode 100644 index 0000000..ea649c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_fixdfhi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtdw 8(%ap),%r0 # 27 [c=36] *fix_truncdfhi2_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c new file mode 100644 index 0000000..a53e936 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_fixdfqi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtdb 8(%ap),%r0 # 27 [c=36] *fix_truncdfqi2_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c new file mode 100644 index 0000000..bcf5f36 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_fixdfsi (float_t x) +{ + int_t v; + + v = x; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtdl 4(%ap),%r0 # 28 [c=36] *fix_truncdfsi2_ccnz + jleq .L1 # 30 [c=26] *branch_ccnz + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c new file mode 100644 index 0000000..2301500 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_fixsfhi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtfw 8(%ap),%r0 # 27 [c=36] *fix_truncsfhi2_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c new file mode 100644 index 0000000..34a4783 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_fixsfqi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtfb 8(%ap),%r0 # 27 [c=36] *fix_truncsfqi2_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c new file mode 100644 index 0000000..39735af --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_fixsfsi (float_t x) +{ + int_t v; + + v = x; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtfl 4(%ap),%r0 # 28 [c=36] *fix_truncsfsi2_ccnz + jleq .L1 # 30 [c=26] *branch_ccnz + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c new file mode 100644 index 0000000..bab7101c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +float_t +le_floatsisf (int_t x) +{ + float_t v; + + v = x; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtlf 4(%ap),%r0 # 27 [c=32] *floatsisf2_ccnz + jleq .L1 # 29 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 26 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "floatsisf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c new file mode 100644 index 0000000..26c368b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef union + { + int_t i; + struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } b; + } +bit_t; + +int +le_insvsi (bit_t x, int_t y) +{ + int_t v; + + v = x.b.i; + x.b.i = y; + if (v <= 0) + return x.i; + else + return x.i + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 37 [c=16] *movsi_2 + extv $7,$18,%r0,%r1 # 38 [c=60] *extv_non_const_2_ccnz + insv 8(%ap),$7,$18,%r0 # 8 [c=16] *insv_2 + jleq .L1 # 40 [c=26] *branch_ccnz + addl2 $2,%r0 # 36 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "extv.*insv.*branch" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c new file mode 100644 index 0000000..26a4d76 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_iorhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x | *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bisw3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *iorhi3_ccnz/2 + jleq .L2 # 30 [c=26] *branch_ccnz + addw2 $2,%r0 # 27 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c new file mode 100644 index 0000000..fbb97b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_iorqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x | *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bisb3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *iorqi3_ccnz/2 + jleq .L2 # 30 [c=26] *branch_ccnz + addb2 $2,%r0 # 27 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c new file mode 100644 index 0000000..4cf50fe --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_iorsi (int_t x, int_t y) +{ + x |= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + bisl3 8(%ap),4(%ap),%r0 # 29 [c=28] *iorsi3_ccnz/2 + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c new file mode 100644 index 0000000..acbaa2d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +le_movdf (float_t x) +{ + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movd 4(%ap),%r0 # 34 [c=24] *movdf_ccnz/1 + jleq .L1 # 36 [c=26] *branch_ccnz + addd2 $0d2.0e+0,%r0 # 33 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movdf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c new file mode 100644 index 0000000..3e99f87 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_movhi (int_t *w, int_t *x) +{ + int_t v; + + v = *x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movw *8(%ap),%r0 # 27 [c=24] *movhi_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c new file mode 100644 index 0000000..8c73a82 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_movqi (int_t *w, int_t *x) +{ + int_t v; + + v = *x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movb *8(%ap),%r0 # 27 [c=24] *movqi_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c new file mode 100644 index 0000000..71a70b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +le_movsf (float_t x) +{ + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movf 4(%ap),%r0 # 33 [c=16] *movsf_ccnz/1 + jleq .L1 # 35 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 32 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c new file mode 100644 index 0000000..2203f8b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_movsi (int_t x) +{ + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 34 [c=16] *movsi_2_ccnz + jleq .L1 # 36 [c=26] *branch_ccnz + addl2 $2,%r0 # 33 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c new file mode 100644 index 0000000..ed3193d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +le_muldf (float_t x, float_t y) +{ + x *= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + muld3 4(%ap),12(%ap),%r0 # 29 [c=80] *muldf3_ccnz/2 + jleq .L1 # 31 [c=26] *branch_ccnz + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "muldf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c new file mode 100644 index 0000000..426a469 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_mulhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x * *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mulw3 *8(%ap),*12(%ap),%r0 # 29 [c=72] *mulhi3_ccnz/2 + jleq .L2 # 31 [c=26] *branch_ccnz + addw2 $2,%r0 # 28 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c new file mode 100644 index 0000000..ca3bb48 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_mulqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x * *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mulb3 *8(%ap),*12(%ap),%r0 # 29 [c=72] *mulqi3_ccnz/2 + jleq .L2 # 31 [c=26] *branch_ccnz + addb2 $2,%r0 # 28 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c new file mode 100644 index 0000000..0d3ac37 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +le_mulsf (float_t x, float_t y) +{ + x *= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mulf3 4(%ap),8(%ap),%r0 # 28 [c=52] *mulsf3_ccnz/2 + jleq .L1 # 30 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c new file mode 100644 index 0000000..de72158 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_mulsi (int_t x, int_t y) +{ + x *= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mull3 4(%ap),8(%ap),%r0 # 29 [c=56] *mulsi3_ccnz/2 + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c new file mode 100644 index 0000000..6884a78 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_nothi (int_t *w, int_t *x) +{ + int_t v; + + v = ~*x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mcomw *8(%ap),%r0 # 27 [c=24] *one_cmplhi2_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c new file mode 100644 index 0000000..60a9e61 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_notqi (int_t *w, int_t *x) +{ + int_t v; + + v = ~*x; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mcomb *8(%ap),%r0 # 27 [c=24] *one_cmplqi2_ccnz + jleq .L2 # 29 [c=26] *branch_ccnz + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c new file mode 100644 index 0000000..938a6b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_notsi (int_t x) +{ + x = ~x; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mcoml 4(%ap),%r0 # 28 [c=16] *one_cmplsi2_ccnz + jleq .L1 # 30 [c=26] *branch_ccnz + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c new file mode 100644 index 0000000..9e01429 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) ulong_t; +typedef int __attribute__ ((mode (SI))) long_t; +typedef int __attribute__ ((mode (QI))) int_t; + +ulong_t +le_rotlsi (ulong_t x, int_t y) +{ + long_t v; + + v = x << y | x >> 8 * sizeof (x) - y; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + rotl 8(%ap),4(%ap),%r0 # 32 [c=40] *rotlsi3_ccnz + jleq .L1 # 34 [c=26] *branch_ccnz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "rotlsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c new file mode 100644 index 0000000..4fe533b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) ulong_t; +typedef int __attribute__ ((mode (SI))) long_t; +typedef int __attribute__ ((mode (QI))) int_t; + +ulong_t +le_rotrsi (ulong_t x, int_t y) +{ + long_t v; + + v = x >> y | x << 8 * sizeof (x) - y; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + mnegb 8(%ap),%r0 # 33 [c=16] *negqi2 + rotl %r0,4(%ap),%r0 # 34 [c=36] *rotrnegsi3_2_ccnz + jleq .L1 # 36 [c=26] *branch_ccnz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "rotrnegsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c new file mode 100644 index 0000000..0456cd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +le_subdf (float_t x, float_t y) +{ + x -= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subd3 12(%ap),4(%ap),%r0 # 29 [c=68] *subdf3_ccnz/1 + jleq .L1 # 31 [c=26] *branch_ccnz + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subdf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c new file mode 100644 index 0000000..4391b76 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_subhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + subw3 *12(%ap),*8(%ap),%r0 # 29 [c=64] *subhi3_ccnz/1 + jleq .L2 # 31 [c=26] *branch_ccnz + addw2 $2,%r0 # 28 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c new file mode 100644 index 0000000..f725be9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_subqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + subb3 *12(%ap),*8(%ap),%r0 # 29 [c=64] *subqi3_ccnz/1 + jleq .L2 # 31 [c=26] *branch_ccnz + addb2 $2,%r0 # 28 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c new file mode 100644 index 0000000..77a9bf0 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +le_subsf (float_t x, float_t y) +{ + x -= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subf3 8(%ap),4(%ap),%r0 # 28 [c=48] *subsf3_ccnz/1 + jleq .L1 # 30 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c new file mode 100644 index 0000000..db64ffc --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_subsi (int_t x, int_t y) +{ + x -= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subl3 8(%ap),4(%ap),%r0 # 29 [c=48] *subsi3_ccnz/1 + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c new file mode 100644 index 0000000..6e7673d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) single_t; +typedef float __attribute__ ((mode (DF))) double_t; + +single_t +le_truncdfsf (double_t x) +{ + single_t v; + + v = x; + if (v <= 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtdf 4(%ap),%r0 # 27 [c=20] *truncdfsf2_ccnz + jleq .L1 # 29 [c=26] *branch_ccnz + addf2 $0f2.0e+0,%r0 # 26 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "truncdfsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c new file mode 100644 index 0000000..e65eed8 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_xorhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x ^ *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + xorw3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *xorhi3_ccnz/2 + jleq .L2 # 30 [c=26] *branch_ccnz + addw2 $2,%r0 # 27 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "xorhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c new file mode 100644 index 0000000..ca8d5fb --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_xorqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x ^ *y; + if (v <= 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + xorb3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *xorqi3_ccnz/2 + jleq .L2 # 30 [c=26] *branch_ccnz + addb2 $2,%r0 # 27 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "xorqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c new file mode 100644 index 0000000..3de63ca --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_xorsi (int_t x, int_t y) +{ + x ^= y; + if (x <= 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + xorl3 8(%ap),4(%ap),%r0 # 29 [c=28] *xorsi3_ccnz/2 + jleq .L1 # 31 [c=26] *branch_ccnz + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "xorsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c new file mode 100644 index 0000000..5f3e372 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (HI))) int_t; + +void +leu_subhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (*x <= *y) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movw *8(%ap),%r2 # 28 [c=24] *movhi + movw *12(%ap),%r1 # 29 [c=24] *movhi + subw3 %r1,%r2,%r0 # 30 [c=32] *subhi3_cc/1 + jlequ .L2 # 32 [c=26] *branch_cc + addw2 $2,%r0 # 27 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subhi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c new file mode 100644 index 0000000..97ef2a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (QI))) int_t; + +void +leu_subqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (*x <= *y) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movb *8(%ap),%r2 # 28 [c=24] *movqi + movb *12(%ap),%r1 # 29 [c=24] *movqi + subb3 %r1,%r2,%r0 # 30 [c=32] *subqi3_cc/1 + jlequ .L2 # 32 [c=26] *branch_cc + addb2 $2,%r0 # 27 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subqi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c new file mode 100644 index 0000000..9402fab --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; + +int_t +leu_subsi (int_t x, int_t y) +{ + int_t v; + + v = x - y; + if (x <= y) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r2 # 27 [c=16] *movsi_2 + movl 8(%ap),%r1 # 28 [c=16] *movsi_2 + subl3 %r1,%r2,%r0 # 29 [c=32] *subsi3_cc/1 + jlequ .L1 # 31 [c=26] *branch_cc + addl2 $2,%r0 # 26 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c new file mode 100644 index 0000000..6e3718d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +lt_adddf (float_t x, float_t y) +{ + x += y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addd3 4(%ap),12(%ap),%r0 # 29 [c=68] *adddf3_ccn/2 + jlss .L1 # 31 [c=26] *branch_ccn + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "adddf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c new file mode 100644 index 0000000..a93675a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_addhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x + *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + addw3 *8(%ap),*12(%ap),%r0 # 29 [c=64] *addhi3_ccn + jlss .L2 # 31 [c=26] *branch_ccn + addw2 $2,%r0 # 28 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c new file mode 100644 index 0000000..32a1328 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_addqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x + *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + addb3 *8(%ap),*12(%ap),%r0 # 29 [c=64] *addqi3_ccn + jlss .L2 # 31 [c=26] *branch_ccn + addb2 $2,%r0 # 28 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c new file mode 100644 index 0000000..19c0b68 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +lt_addsf (float_t x, float_t y) +{ + x += y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addf3 4(%ap),8(%ap),%r0 # 28 [c=48] *addsf3_ccn/2 + jlss .L1 # 30 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c new file mode 100644 index 0000000..1bb59d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_addsi (int_t x, int_t y) +{ + x += y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + addl3 4(%ap),8(%ap),%r0 # 29 [c=48] *addsi3_ccn + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c new file mode 100644 index 0000000..f725931 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_andhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & ~*y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bicw3 *12(%ap),*8(%ap),%r0 # 30 [c=44] *andhi3_2_ccn/1 + jlss .L2 # 32 [c=26] *branch_ccn + addw2 $2,%r0 # 29 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c new file mode 100644 index 0000000..afae635 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_andqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & ~*y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bicb3 *12(%ap),*8(%ap),%r0 # 30 [c=44] *andqi3_2_ccn/1 + jlss .L2 # 32 [c=26] *branch_ccn + addb2 $2,%r0 # 29 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c new file mode 100644 index 0000000..5a86ddb --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_andsi (int_t x, int_t y) +{ + x &= ~y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + bicl3 8(%ap),4(%ap),%r0 # 31 [c=28] *andsi3_2_ccn/1 + jlss .L1 # 33 [c=26] *branch_ccn + addl2 $2,%r0 # 30 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "andsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c new file mode 100644 index 0000000..0c85893 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +lt_ashlsi (int_t x, short_t y) +{ + x <<= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + ashl 8(%ap),4(%ap),%r0 # 31 [c=56] *ashlsi3_ccn + jlss .L1 # 33 [c=26] *branch_ccn + addl2 $2,%r0 # 30 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ashlsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c new file mode 100644 index 0000000..977f32c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +lt_ashrsi (int_t x, short_t y) +{ + x >>= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mnegb 8(%ap),%r0 # 32 [c=16] *negqi2 + ashl %r0,4(%ap),%r0 # 33 [c=52] *ashlnegsi3_2_ccn + jlss .L1 # 35 [c=26] *branch_ccn + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ashlnegsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c new file mode 100644 index 0000000..ddcb8c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +lt_divdf (float_t x, float_t y) +{ + x /= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divd3 12(%ap),4(%ap),%r0 # 29 [c=112] *divdf3_ccn/1 + jlss .L1 # 31 [c=26] *branch_ccn + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divdf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c new file mode 100644 index 0000000..23bbf42 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI), vector_size (2))) int_t; + +void +lt_divhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x / *y; + if (v[0] < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + divw3 *12(%ap),*8(%ap),%r0 # 34 [c=76] *divhi3_ccn/1 + jlss .L2 # 36 [c=26] *branch_ccn + addw2 $2,%r0 # 33 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c new file mode 100644 index 0000000..5401b6b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI), vector_size (1))) int_t; + +void +lt_divqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x / *y; + if (v[0] < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + divb3 *12(%ap),*8(%ap),%r0 # 34 [c=76] *divqi3_ccn/1 + jlss .L2 # 36 [c=26] *branch_ccn + addb2 $2,%r0 # 33 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c new file mode 100644 index 0000000..89d5930 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +lt_divsf (float_t x, float_t y) +{ + x /= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divf3 8(%ap),4(%ap),%r0 # 28 [c=60] *divsf3_ccn/1 + jlss .L1 # 30 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c new file mode 100644 index 0000000..5c50635 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_divsi (int_t x, int_t y) +{ + x /= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + divl3 8(%ap),4(%ap),%r0 # 29 [c=60] *divsi3_ccn/1 + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "divsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c new file mode 100644 index 0000000..5dcc89a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (HI))) short_t; + +int_t +lt_extendhisi (int_t x) +{ + x = (short_t) x; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + cvtwl 4(%ap),%r0 # 29 [c=20] *extendhisi2_ccn + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extendhisi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c new file mode 100644 index 0000000..9ec5a41 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; +typedef int __attribute__ ((mode (QI))) short_t; + +int_t +lt_extendqisi (int_t x) +{ + x = (short_t) x; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + cvtbl 4(%ap),%r0 # 29 [c=20] *extendqisi2_ccn + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extendqisi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c new file mode 100644 index 0000000..a10435b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +lt_extvsi (bit_t x) +{ + int_t v; + + v = x.i; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + extv $7,$18,4(%ap),%r0 # 28 [c=68] *extv_non_const_2_ccn + jlss .L1 # 30 [c=26] *branch_ccn + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c new file mode 100644 index 0000000..e019d74 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef int __attribute__ ((mode (SI))) int_t; + +uint_t +lt_extzvsi (uint_t x, int_t y) +{ + int_t v; + + v = x >> y; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + subb3 8(%ap),$32,%r0 # 31 [c=40] *subqi3/1 + extzv 8(%ap),%r0,4(%ap),%r0 # 32 [c=76] *extzv_non_const_2_ccn + jlss .L1 # 34 [c=26] *branch_ccn + addl2 $2,%r0 # 30 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extzv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c new file mode 100644 index 0000000..5d63a22 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_fixdfhi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtdw 8(%ap),%r0 # 27 [c=36] *fix_truncdfhi2_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c new file mode 100644 index 0000000..d161655 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_fixdfqi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtdb 8(%ap),%r0 # 27 [c=36] *fix_truncdfqi2_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c new file mode 100644 index 0000000..b07d1de --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_fixdfsi (float_t x) +{ + int_t v; + + v = x; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtdl 4(%ap),%r0 # 28 [c=36] *fix_truncdfsi2_ccn + jlss .L1 # 30 [c=26] *branch_ccn + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncdfsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c new file mode 100644 index 0000000..42c8d74 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_fixsfhi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtfw 8(%ap),%r0 # 27 [c=36] *fix_truncsfhi2_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c new file mode 100644 index 0000000..49327ee --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_fixsfqi (int_t *w, float_t x) +{ + int_t v; + + v = x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtfb 8(%ap),%r0 # 27 [c=36] *fix_truncsfqi2_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c new file mode 100644 index 0000000..3d17291 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_fixsfsi (float_t x) +{ + int_t v; + + v = x; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtfl 4(%ap),%r0 # 28 [c=36] *fix_truncsfsi2_ccn + jlss .L1 # 30 [c=26] *branch_ccn + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "fix_truncsfsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c new file mode 100644 index 0000000..cefc71e --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; +typedef int __attribute__ ((mode (SI))) int_t; + +float_t +lt_floatsisf (int_t x) +{ + float_t v; + + v = x; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtlf 4(%ap),%r0 # 27 [c=32] *floatsisf2_ccn + jlss .L1 # 29 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 26 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "floatsisf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c new file mode 100644 index 0000000..52f97ef --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef union + { + int_t i; + struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } b; + } +bit_t; + +int +lt_insvsi (bit_t x, int_t y) +{ + int_t v; + + v = x.b.i; + x.b.i = y; + if (v < 0) + return x.i; + else + return x.i + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 37 [c=16] *movsi_2 + extv $7,$18,%r0,%r1 # 38 [c=60] *extv_non_const_2_ccn + insv 8(%ap),$7,$18,%r0 # 8 [c=16] *insv_2 + jlss .L1 # 40 [c=26] *branch_ccn + addl2 $2,%r0 # 36 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "extv.*insv.*branch" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c new file mode 100644 index 0000000..edd91e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_iorhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x | *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bisw3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *iorhi3_ccn/2 + jlss .L2 # 30 [c=26] *branch_ccn + addw2 $2,%r0 # 27 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c new file mode 100644 index 0000000..82a9e04 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_iorqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x | *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + bisb3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *iorqi3_ccn/2 + jlss .L2 # 30 [c=26] *branch_ccn + addb2 $2,%r0 # 27 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c new file mode 100644 index 0000000..1246686 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_iorsi (int_t x, int_t y) +{ + x |= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + bisl3 8(%ap),4(%ap),%r0 # 29 [c=28] *iorsi3_ccn/2 + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "iorsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c new file mode 100644 index 0000000..02b4c5a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +lt_movdf (float_t x) +{ + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movd 4(%ap),%r0 # 34 [c=24] *movdf_ccn/1 + jlss .L1 # 36 [c=26] *branch_ccn + addd2 $0d2.0e+0,%r0 # 33 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movdf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c new file mode 100644 index 0000000..51ce5b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_movhi (int_t *w, int_t *x) +{ + int_t v; + + v = *x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movw *8(%ap),%r0 # 27 [c=24] *movhi_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c new file mode 100644 index 0000000..fb5450c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_movqi (int_t *w, int_t *x) +{ + int_t v; + + v = *x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movb *8(%ap),%r0 # 27 [c=24] *movqi_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c new file mode 100644 index 0000000..1669f16 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +lt_movsf (float_t x) +{ + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movf 4(%ap),%r0 # 33 [c=16] *movsf_ccn/1 + jlss .L1 # 35 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 32 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c new file mode 100644 index 0000000..b4cd073 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_movsi (int_t x) +{ + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 34 [c=16] *movsi_2_ccn + jlss .L1 # 36 [c=26] *branch_ccn + addl2 $2,%r0 # 33 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "movsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c new file mode 100644 index 0000000..1f9279b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +lt_muldf (float_t x, float_t y) +{ + x *= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + muld3 4(%ap),12(%ap),%r0 # 29 [c=80] *muldf3_ccn/2 + jlss .L1 # 31 [c=26] *branch_ccn + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "muldf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c new file mode 100644 index 0000000..29a77e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_mulhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x * *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mulw3 *8(%ap),*12(%ap),%r0 # 29 [c=72] *mulhi3_ccn/2 + jlss .L2 # 31 [c=26] *branch_ccn + addw2 $2,%r0 # 28 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c new file mode 100644 index 0000000..844456e --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_mulqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x * *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mulb3 *8(%ap),*12(%ap),%r0 # 29 [c=72] *mulqi3_ccn/2 + jlss .L2 # 31 [c=26] *branch_ccn + addb2 $2,%r0 # 28 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c new file mode 100644 index 0000000..ea1c083 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +lt_mulsf (float_t x, float_t y) +{ + x *= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mulf3 4(%ap),8(%ap),%r0 # 28 [c=52] *mulsf3_ccn/2 + jlss .L1 # 30 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c new file mode 100644 index 0000000..5f46c8c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_mulsi (int_t x, int_t y) +{ + x *= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mull3 4(%ap),8(%ap),%r0 # 29 [c=56] *mulsi3_ccn/2 + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "mulsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c new file mode 100644 index 0000000..59d1d9a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_nothi (int_t *w, int_t *x) +{ + int_t v; + + v = ~*x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mcomw *8(%ap),%r0 # 27 [c=24] *one_cmplhi2_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addw2 $2,%r0 # 26 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c new file mode 100644 index 0000000..7a2ef96 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_notqi (int_t *w, int_t *x) +{ + int_t v; + + v = ~*x; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + mcomb *8(%ap),%r0 # 27 [c=24] *one_cmplqi2_ccn + jlss .L2 # 29 [c=26] *branch_ccn + addb2 $2,%r0 # 26 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c new file mode 100644 index 0000000..c3586b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_notsi (int_t x) +{ + x = ~x; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + mcoml 4(%ap),%r0 # 28 [c=16] *one_cmplsi2_ccn + jlss .L1 # 30 [c=26] *branch_ccn + addl2 $2,%r0 # 27 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "one_cmplsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c new file mode 100644 index 0000000..7f5c89d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) ulong_t; +typedef int __attribute__ ((mode (SI))) long_t; +typedef int __attribute__ ((mode (QI))) int_t; + +ulong_t +lt_rotlsi (ulong_t x, int_t y) +{ + long_t v; + + v = x << y | x >> 8 * sizeof (x) - y; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + rotl 8(%ap),4(%ap),%r0 # 32 [c=40] *rotlsi3_ccn + jlss .L1 # 34 [c=26] *branch_ccn + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "rotlsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c new file mode 100644 index 0000000..6c9daf4 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) ulong_t; +typedef int __attribute__ ((mode (SI))) long_t; +typedef int __attribute__ ((mode (QI))) int_t; + +ulong_t +lt_rotrsi (ulong_t x, int_t y) +{ + long_t v; + + v = x >> y | x << 8 * sizeof (x) - y; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + mnegb 8(%ap),%r0 # 33 [c=16] *negqi2 + rotl %r0,4(%ap),%r0 # 34 [c=36] *rotrnegsi3_2_ccn + jlss .L1 # 36 [c=26] *branch_ccn + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "rotrnegsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c new file mode 100644 index 0000000..fb7bb1d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (DF))) float_t; + +float_t +lt_subdf (float_t x, float_t y) +{ + x -= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subd3 12(%ap),4(%ap),%r0 # 29 [c=68] *subdf3_ccn/1 + jlss .L1 # 31 [c=26] *branch_ccn + addd2 $0d2.0e+0,%r0 # 28 [c=56] *adddf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subdf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c new file mode 100644 index 0000000..d06af83 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_subhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + subw3 *12(%ap),*8(%ap),%r0 # 29 [c=64] *subhi3_ccn/1 + jlss .L2 # 31 [c=26] *branch_ccn + addw2 $2,%r0 # 28 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c new file mode 100644 index 0000000..254ad71 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_subqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + subb3 *12(%ap),*8(%ap),%r0 # 29 [c=64] *subqi3_ccn/1 + jlss .L2 # 31 [c=26] *branch_ccn + addb2 $2,%r0 # 28 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c new file mode 100644 index 0000000..26181d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) float_t; + +float_t +lt_subsf (float_t x, float_t y) +{ + x -= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subf3 8(%ap),4(%ap),%r0 # 28 [c=48] *subsf3_ccn/1 + jlss .L1 # 30 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 27 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c new file mode 100644 index 0000000..6e98e4c --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_subsi (int_t x, int_t y) +{ + x -= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + subl3 8(%ap),4(%ap),%r0 # 29 [c=48] *subsi3_ccn/1 + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c new file mode 100644 index 0000000..98fac66 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef float __attribute__ ((mode (SF))) single_t; +typedef float __attribute__ ((mode (DF))) double_t; + +single_t +lt_truncdfsf (double_t x) +{ + single_t v; + + v = x; + if (v < 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + cvtdf 4(%ap),%r0 # 27 [c=20] *truncdfsf2_ccn + jlss .L1 # 29 [c=26] *branch_ccn + addf2 $0f2.0e+0,%r0 # 26 [c=36] *addsf3/0 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "truncdfsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c new file mode 100644 index 0000000..be36e0a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +lt_xorhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x ^ *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + xorw3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *xorhi3_ccn/2 + jlss .L2 # 30 [c=26] *branch_ccn + addw2 $2,%r0 # 27 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "xorhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c new file mode 100644 index 0000000..51b05e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_xorqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x ^ *y; + if (v < 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + xorb3 *12(%ap),*8(%ap),%r0 # 28 [c=44] *xorqi3_ccn/2 + jlss .L2 # 30 [c=26] *branch_ccn + addb2 $2,%r0 # 27 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "xorqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c new file mode 100644 index 0000000..439e36d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_xorsi (int_t x, int_t y) +{ + x ^= y; + if (x < 0) + return x; + else + return x + 2; +} + +/* Expect assembly like: + + xorl3 8(%ap),4(%ap),%r0 # 29 [c=28] *xorsi3_ccn/2 + jlss .L1 # 31 [c=26] *branch_ccn + addl2 $2,%r0 # 28 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "xorsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c new file mode 100644 index 0000000..7965322 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (HI))) int_t; + +void +ltu_subhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (*x < *y) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movw *8(%ap),%r2 # 28 [c=24] *movhi + movw *12(%ap),%r1 # 29 [c=24] *movhi + subw3 %r1,%r2,%r0 # 30 [c=32] *subhi3_cc/1 + jlssu .L2 # 32 [c=26] *branch_cc + addw2 $2,%r0 # 27 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subhi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c new file mode 100644 index 0000000..3ba1d0f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (QI))) int_t; + +void +ltu_subqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x - *y; + if (*x < *y) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movb *8(%ap),%r2 # 28 [c=24] *movqi + movb *12(%ap),%r1 # 29 [c=24] *movqi + subb3 %r1,%r2,%r0 # 30 [c=32] *subqi3_cc/1 + jlssu .L2 # 32 [c=26] *branch_cc + addb2 $2,%r0 # 27 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subqi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c new file mode 100644 index 0000000..542ff80 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; + +int_t +ltu_subsi (int_t x, int_t y) +{ + int_t v; + + v = x - y; + if (x < y) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r2 # 27 [c=16] *movsi_2 + movl 8(%ap),%r1 # 28 [c=16] *movsi_2 + subl3 %r1,%r2,%r0 # 29 [c=32] *subsi3_cc/1 + jlssu .L1 # 31 [c=26] *branch_cc + addl2 $2,%r0 # 26 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c new file mode 100644 index 0000000..033b119 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +xx_addsi (int_t x, int_t y) +{ + x += y; + if (x == 0) + return x; + else if (x >= 0) + return x + 2; + else + return x - 3; +} + +/* Expect assembly like: + + addl3 4(%ap),8(%ap),%r0 # 47 [c=48] *addsi3_ccnz + jeql .L1 # 49 [c=26] *branch_ccz + jlss .L3 # 46 [c=26] *branch_ccn + addl2 $2,%r0 # 44 [c=32] *addsi3 + ret # 39 [c=0] return +.L3: + subl2 $3,%r0 # 43 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 2 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "addsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c new file mode 100644 index 0000000..8f3e4ff --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef union + { + int_t i; + struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } b; + } +bit_t; + +int +xx_insvsi (bit_t x, int_t y) +{ + int_t v; + + v = x.b.i; + x.b.i = y; + if (v == 0) + return x.i; + else if (v >= 0) + return x.i + 2; + else + return x.i - 3; +} + +/* Expect assembly like: + + movl 4(%ap),%r0 # 50 [c=16] *movsi_2 + extv $7,$18,%r0,%r1 # 51 [c=60] *extv_non_const_2_ccnz + insv 8(%ap),$7,$18,%r0 # 8 [c=16] *insv_2 + jeql .L1 # 53 [c=26] *branch_ccz + jlss .L4 # 49 [c=26] *branch_ccn + addl2 $2,%r0 # 47 [c=32] *addsi3 + ret # 42 [c=0] return +.L4: + subl2 $3,%r0 # 46 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 2 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "extv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "extv.*insv.*branch" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c new file mode 100644 index 0000000..b9f7304 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-cmpelim -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; + +int_t +xxu_subsi (int_t x, int_t y) +{ + int_t v; + + v = x - y; + if (x == y) + return v; + else if (x >= y) + return v + 2; + else + return v - 3; +} + +/* Expect assembly like: + + movl 4(%ap),%r2 # 39 [c=16] *movsi_2 + movl 8(%ap),%r1 # 40 [c=16] *movsi_2 + subl3 %r1,%r2,%r0 # 41 [c=32] *subsi3_cc/1 + jeql .L1 # 43 [c=26] *branch_ccz + jlssu .L3 # 38 [c=26] *branch_cc + addl2 $2,%r0 # 36 [c=32] *addsi3 + ret # 31 [c=0] return +.L3: + subl2 $3,%r0 # 35 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 2 "cmpelim" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "subsi\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c new file mode 100644 index 0000000..485b324 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_andhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & *y; + if (v == 0) + *w = 1; + else + *w = 2; +} + +/* Expect assembly like: + + bitw *8(%ap),*12(%ap) # 50 [c=50] *bithi_ccz + jneq .L3 # 40 [c=26] *branch_ccz + movw $1,%r0 # 36 [c=4] *movhi + movw %r0,*4(%ap) # 34 [c=4] *movhi + ret # 46 [c=0] return +.L3: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bithi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c new file mode 100644 index 0000000..ffea453 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_andqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & *y; + if (v == 0) + *w = 1; + else + *w = 2; +} + +/* Expect assembly like: + + bitb *8(%ap),*12(%ap) # 50 [c=50] *bitqi_ccz + jneq .L3 # 40 [c=26] *branch_ccz + movb $1,%r0 # 36 [c=4] *movqi + movb %r0,*4(%ap) # 34 [c=4] *movqi + ret # 46 [c=0] return +.L3: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bitqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c new file mode 100644 index 0000000..b84c352 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_andsi (int_t x, int_t y) +{ + x &= y; + if (x == 0) + return 1; + else + return 2; +} + +/* Expect assembly like: + + bitl 4(%ap),8(%ap) # 52 [c=34] *bitsi_ccz + jneq .L6 # 41 [c=26] *branch_ccz + movl $1,%r0 # 36 [c=4] *movsi_2 + ret # 47 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bitsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c new file mode 100644 index 0000000..3e09a78 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +eq_cmpvsi (bit_t x, int_t y) +{ + if (x.i == y) + return 1; + else + return 2; +} + +/* Expect assembly like: + + cmpv $7,$18,4(%ap),8(%ap) # 50 [c=88] *cmpv_ccz + jeql .L3 # 39 [c=26] *branch_ccz + movl $2,%r0 # 36 [c=4] *movsi_2 + ret # 31 [c=0] return +.L3: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c new file mode 100644 index 0000000..3713c1d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +eq_extzvsi (bit_t x, int_t y) +{ + if (x.i == y) + return 1; + else + return 2; +} + +/* Expect assembly like: + + cmpzv $7,$18,4(%ap),8(%ap) # 50 [c=88] *cmpzv_ccz + jeql .L3 # 39 [c=26] *branch_ccz + movl $2,%r0 # 36 [c=4] *movsi_2 + ret # 31 [c=0] return +.L3: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpzv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c new file mode 100644 index 0000000..8a56451 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_ctzhi (int_t *w, int_t *x) +{ + int_t v; + + v = __builtin_ctz (*x); + if (*x == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movw *8(%ap),%r1 # 34 [c=24] *movhi + ffs $0,$16,%r1,%r0 # 49 [c=4] *ctzhi2_ccz + jeql .L3 # 38 [c=26] *branch_ccz + addw2 $2,%r0 # 33 [c=32] *addhi3 +.L3: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 2 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ctzhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c new file mode 100644 index 0000000..db76da4 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_ctzhi (int_t *w, int_t *x) +{ + int_t v; + + v = __builtin_ctz (*x + 1); + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtwl *8(%ap),%r0 # 34 [c=28] *extendhisi2 + incl %r0 # 35 [c=32] *addsi3 + ffs $0,$32,%r0,%r0 # 36 [c=4] *ctzsi2 + tstl %r0 # 37 [c=6] *cmpsi_ccz/0 + jeql .L2 # 38 [c=26] *branch_ccz + addw2 $2,%r0 # 33 [c=32] *addhi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-not "Splitting with gen_peephole2" "peephole2" } } */ +/* { dg-final { scan-assembler "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "cmpsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c new file mode 100644 index 0000000..b6078bc --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_ctzqi (int_t *w, int_t *x) +{ + int_t v; + + v = __builtin_ctz (*x); + if (*x == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + movb *8(%ap),%r1 # 34 [c=24] *movqi + ffs $0,$8,%r1,%r0 # 49 [c=4] *ctzqi2_ccz + jeql .L3 # 38 [c=26] *branch_ccz + addb2 $2,%r0 # 33 [c=32] *addqi3 +.L3: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 2 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ctzqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c new file mode 100644 index 0000000..44311b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_ctzqi (int_t *w, int_t *x) +{ + int_t v; + + v = __builtin_ctz (*x + 1); + if (v == 0) + *w = v; + else + *w = v + 2; +} + +/* Expect assembly like: + + cvtbl *8(%ap),%r0 # 34 [c=28] *extendqisi2 + incl %r0 # 35 [c=32] *addsi3 + ffs $0,$32,%r0,%r0 # 36 [c=4] *ctzsi2 + tstl %r0 # 37 [c=6] *cmpsi_ccz/0 + jeql .L2 # 38 [c=26] *branch_ccz + addb2 $2,%r0 # 33 [c=32] *addqi3 +.L2: + + */ + +/* { dg-final { scan-rtl-dump-not "Splitting with gen_peephole2" "peephole2" } } */ +/* { dg-final { scan-assembler "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "cmpsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c new file mode 100644 index 0000000..bf84bdc --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_ctzsi (int_t x) +{ + int_t v; + + v = __builtin_ctz (x); + if (x == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + movl 4(%ap),%r1 # 32 [c=16] *movsi_2 + ffs $0,$32,%r1,%r0 # 45 [c=4] *ctzsi2_ccz + jeql .L1 # 35 [c=26] *branch_ccz + addl2 $2,%r0 # 31 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ctzsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c new file mode 100644 index 0000000..0cc40ed --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_ctzsi (int_t x) +{ + int_t v; + + v = __builtin_ctz (x + 1); + if (v == 0) + return v; + else + return v + 2; +} + +/* Expect assembly like: + + addl3 4(%ap),$1,%r0 # 33 [c=40] *addsi3 + ffs $0,$32,%r0,%r0 # 34 [c=4] *ctzsi2 + tstl %r0 # 35 [c=6] *cmpsi_ccz/0 + jeql .L1 # 36 [c=26] *branch_ccz + addl2 $2,%r0 # 32 [c=32] *addsi3 +.L1: + + */ + +/* { dg-final { scan-rtl-dump-not "Splitting with gen_peephole2" "peephole2" } } */ +/* { dg-final { scan-assembler "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "cmpsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c new file mode 100644 index 0000000..50a6cdb --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +eq_ffshi (int_t *w, int_t *x) +{ + *w = __builtin_ffs (*x); +} + +/* Expect assembly like: + + ffs $0,$16,*8(%ap),%r1 # 40 [c=28] *ctzhi2_ccz + jneq .L2 # 30 [c=26] *branch_ccz + mnegl $1,%r1 # 26 [c=8] *negsi2 +.L2: + addw3 %r1,$1,*4(%ap) # 25 [c=32] *addhi3 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ctzhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c new file mode 100644 index 0000000..0b3ef0f --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +eq_ffsqi (int_t *w, int_t *x) +{ + *w = __builtin_ffs (*x); +} + +/* Expect assembly like: + + ffs $0,$8,*8(%ap),%r1 # 40 [c=28] *ctzqi2_ccz + jneq .L2 # 30 [c=26] *branch_ccz + mnegl $1,%r1 # 26 [c=8] *negsi2 +.L2: + addb3 %r1,$1,*4(%ap) # 25 [c=32] *addqi3 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ctzqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c new file mode 100644 index 0000000..0e32121 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +eq_ffssi (int_t x) +{ + return __builtin_ffs (x); +} + +/* Expect assembly like: + + movl 4(%ap),%r1 # 28 [c=16] *movsi_2 + ffs $0,$32,%r1,%r0 # 41 [c=4] *ctzsi2_ccz + jneq .L2 # 31 [c=26] *branch_ccz + mnegl $1,%r0 # 27 [c=8] *negsi2 +.L2: + incl %r0 # 26 [c=32] *addsi3 + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "ctzsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c new file mode 100644 index 0000000..9eb40c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_andhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & *y; + if (v <= 0) + *w = 1; + else + *w = 2; +} + +/* Expect assembly like: + + bitw *8(%ap),*12(%ap) # 56 [c=50] *bithi_ccnz + jleq .L6 # 46 [c=26] *branch_ccnz + movw $2,%r0 # 41 [c=4] *movhi + movw %r0,*4(%ap) # 40 [c=4] *movhi + ret # 52 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bithi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c new file mode 100644 index 0000000..14797b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +le_andqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & *y; + if (v <= 0) + *w = 1; + else + *w = 2; +} + +/* Expect assembly like: + + bitb *8(%ap),*12(%ap) # 56 [c=50] *bitqi_ccnz + jleq .L6 # 46 [c=26] *branch_ccnz + movb $2,%r0 # 41 [c=4] *movqi + movb %r0,*4(%ap) # 40 [c=4] *movqi + ret # 52 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bitqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c new file mode 100644 index 0000000..6d1193e --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +le_andsi (int_t x, int_t y) +{ + x &= y; + if (x <= 0) + return 1; + else + return 2; +} + +/* Expect assembly like: + + bitl 4(%ap),8(%ap) # 58 [c=34] *bitsi_ccnz + jgtr .L6 # 47 [c=26] *branch_ccnz + movl $1,%r0 # 42 [c=4] *movsi_2 + ret # 53 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bitsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c new file mode 100644 index 0000000..dd26849 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +le_cmpvsi (bit_t x, int_t y) +{ + if (x.i <= y) + return 1; + else + return 2; +} + +/* Expect assembly like: + + cmpv $7,$18,4(%ap),8(%ap) # 50 [c=88] *cmpv_ccnz + jgtr .L6 # 39 [c=26] *branch_ccnz + movl $1,%r0 # 35 [c=4] *movsi_2 + ret # 45 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c new file mode 100644 index 0000000..3cf028a --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef int __attribute__ ((mode (SI))) int_t; + +uint_t +le_cmpzvsi (uint_t x, int_t y, int_t z) +{ + int_t v; + + v = x >> y; + if (v <= z) + return 1; + else + return 2; +} + +/* Expect assembly like: + + subb3 8(%ap),$32,%r0 # 39 [c=40] *subqi3/1 + cmpzv 8(%ap),%r0,4(%ap),12(%ap) # 53 [c=96] *cmpzv_ccnz + jgtr .L6 # 42 [c=26] *branch_ccnz + movl $1,%r0 # 37 [c=4] *movsi_2 + ret # 48 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpzv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c new file mode 100644 index 0000000..0a0468b --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +leu_cmpvsi (bit_t x, uint_t y) +{ + uint_t v; + + v = x.i; + if (v <= y) + return 1; + else + return 2; +} + +/* Expect assembly like: + + cmpv $7,$18,4(%ap),8(%ap) # 50 [c=88] *cmpv_cc + jgtru .L6 # 39 [c=26] *branch_cc + movl $1,%r0 # 35 [c=4] *movsi_2 + ret # 45 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpv\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c new file mode 100644 index 0000000..ca7cfe4 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef int __attribute__ ((mode (SI))) int_t; + +uint_t +leu_cmpzvsi (uint_t x, int_t y, uint_t z) +{ + if (x >> y <= z) + return 1; + else + return 2; +} + +/* Expect assembly like: + + subb3 8(%ap),$32,%r0 # 39 [c=40] *subqi3/1 + cmpzv 8(%ap),%r0,4(%ap),12(%ap) # 53 [c=96] *cmpzv_cc + jgtru .L6 # 42 [c=26] *branch_cc + movl $1,%r0 # 37 [c=4] *movsi_2 + ret # 48 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpzv\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c new file mode 100644 index 0000000..9eb40c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (HI))) int_t; + +void +le_andhi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & *y; + if (v <= 0) + *w = 1; + else + *w = 2; +} + +/* Expect assembly like: + + bitw *8(%ap),*12(%ap) # 56 [c=50] *bithi_ccnz + jleq .L6 # 46 [c=26] *branch_ccnz + movw $2,%r0 # 41 [c=4] *movhi + movw %r0,*4(%ap) # 40 [c=4] *movhi + ret # 52 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bithi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccnz\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c new file mode 100644 index 0000000..d71c46d --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (QI))) int_t; + +void +lt_andqi (int_t *w, int_t *x, int_t *y) +{ + int_t v; + + v = *x & *y; + if (v < 0) + *w = 1; + else + *w = 2; +} + +/* Expect assembly like: + + bitb *8(%ap),*12(%ap) # 68 [c=50] *bitqi_ccn + jlss .L6 # 58 [c=26] *branch_ccn + movb $2,%r0 # 53 [c=4] *movqi + movb %r0,*4(%ap) # 52 [c=4] *movqi + ret # 64 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bitqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c new file mode 100644 index 0000000..4045b36 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef int __attribute__ ((mode (SI))) int_t; + +int_t +lt_andsi (int_t x, int_t y) +{ + x &= y; + if (x < 0) + return 1; + else + return 2; +} + +/* Expect assembly like: + + bitl 4(%ap),8(%ap) # 68 [c=34] *bitsi_ccn + jgeq .L6 # 57 [c=26] *branch_ccn + movl $1,%r0 # 52 [c=4] *movsi_2 + ret # 63 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */ +/* { dg-final { scan-assembler "bitsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c new file mode 100644 index 0000000..a50f322 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +lt_cmpvsi (bit_t x, int_t y) +{ + if (x.i < y) + return 1; + else + return 2; +} + +/* Expect assembly like: + + cmpv $7,$18,4(%ap),8(%ap) # 50 [c=88] *cmpv_ccn + jgeq .L6 # 39 [c=26] *branch_ccn + movl $1,%r0 # 35 [c=4] *movsi_2 + ret # 45 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c new file mode 100644 index 0000000..de38643 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef int __attribute__ ((mode (SI))) int_t; + +uint_t +lt_cmpzvsi (uint_t x, int_t y, int_t z) +{ + int_t v; + + v = x >> y; + if (v < z) + return 1; + else + return 2; +} + +/* Expect assembly like: + + subb3 8(%ap),$32,%r0 # 39 [c=40] *subqi3/1 + cmpzv 8(%ap),%r0,4(%ap),12(%ap) # 53 [c=96] *cmpzv_ccn + jgeq .L6 # 42 [c=26] *branch_ccn + movl $1,%r0 # 37 [c=4] *movsi_2 + ret # 48 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpzv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_ccn\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c new file mode 100644 index 0000000..8eba505 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef signed int __attribute__ ((mode (SI))) int_t; +typedef struct + { + int_t h : 7; + int_t i : 18; + int_t l : 7; + } +bit_t; + +int_t +ltu_cmpvsi (bit_t x, uint_t y) +{ + uint_t v; + + v = x.i; + if (v < y) + return 1; + else + return 2; +} + +/* Expect assembly like: + + cmpv $7,$18,4(%ap),8(%ap) # 50 [c=88] *cmpv_cc + jgequ .L6 # 39 [c=26] *branch_cc + movl $1,%r0 # 35 [c=4] *movsi_2 + ret # 45 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpv\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ diff --git a/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c new file mode 100644 index 0000000..9cdee86 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-peephole2 -dp" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */ + +typedef unsigned int __attribute__ ((mode (SI))) uint_t; +typedef int __attribute__ ((mode (SI))) int_t; + +uint_t +ltu_cmpzvsi (uint_t x, int_t y, uint_t z) +{ + if (x >> y < z) + return 1; + else + return 2; +} + +/* Expect assembly like: + + subb3 8(%ap),$32,%r0 # 39 [c=40] *subqi3/1 + cmpzv 8(%ap),%r0,4(%ap),12(%ap) # 53 [c=96] *cmpzv_cc + jgequ .L6 # 42 [c=26] *branch_cc + movl $1,%r0 # 37 [c=4] *movsi_2 + ret # 48 [c=0] return +.L6: + + */ + +/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */ +/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */ +/* { dg-final { scan-assembler "cmpzv\[^ \]*_cc(/\[0-9\]+)?\n" } } */ +/* { dg-final { scan-assembler "branch_cc\n" } } */ -- cgit v1.1 From 904ac8577521b8152b97e9b549c1a1ca569a3d1f Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sat, 5 Dec 2020 13:47:22 -0500 Subject: c++: Distinguish unsatisfaction vs errors during satisfaction [PR97093] During satisfaction, the flag info.noisy() controls three things: whether to diagnose ill-formed satisfaction (such as the satisfaction value of an atom being non-bool or non-constant); whether to diagnose unsatisfaction; and whether to bypass the satisfaction cache. The flag turns out to be too coarse however, because in some cases we want to diagnose ill-formed satisfaction (and bypass the satisfaction cache) but not diagnose unsatisfaction, for instance when replaying an erroneous satisfaction result from constraint_satisfaction_value, evaluate_concept_check and tsubst_nested_requirement. And when noisily evaluating a disjunction, we want to first evaluate its branches noisily (bypassing the satisfaction cache) but suppress unsatisfaction diagnostics. We currently work around this by instead first evaluating each branch quietly, but that means the recursive calls to satisfy_atom will use the satisfaction cache. To fix this, this patch adds the info.diagnose_unsatisfaction_p() flag, which refines the info.noisy() flag as part of a new sat_info class that derives from subst_info. During satisfaction, info.noisy() now controls whether to diagnose ill-formed satisfaction, and info.diagnose_unsatisfaction_p() controls whether to additionally diagnose unsatisfaction. This enables us to address the above two issues straightforwardly. Incidentally, the change to satisfy_disjunction suppresses the ICE in the PR97093 testcase because we no longer insert atoms into the satisfaction cache that have been incorrectly re-normalized in diagnose_nested_requirement (after losing the necessary template context). But the underlying re-normalization issue remains, and will be fixed in a subsequent patch. gcc/cp/ChangeLog: PR c++/97093 * constraint.cc (struct sat_info): Define. (tsubst_nested_requirement): Pass a sat_info object to satisfy_constraint. (satisfy_constraint_r): Take a sat_info argument instead of subst_info. (satisfy_conjunction): Likewise. (satisfy_disjunction): Likewise. Instead of first evaluating each branch quietly, evaluate each branch only with unsatisfaction diagnostics disabled. Exit early if evaluation of a branch returns error_mark_node. (satisfy_atom): Take a sat_info argument instead of subst_info. Fix a comment. Check diagnose_unsatisfaction_p() instead of noisy() before replaying a substitution failure. (satisfy_constraint): Take a sat_info argument instead of subst_info. (satisfy_associated_constraints): Likewise. (satisfy_constraint_expression): Likewise. (satisfy_declaration_constraints): Likewise. (constraint_satisfaction_value): Likewise and adjust accordingly. Fix formatting. (constraints_satisfied_p): Pass a sat_info object to constraint_satisfaction_value. (evaluate_concept_check): Pass a sat_info object to satisfy_constraint_expression. (diagnose_nested_requirement): Likewise. (diagnose_constraints): Pass an appropriate sat_info object to constraint_satisfaction_value. gcc/testsuite/ChangeLog: PR c++/97093 * g++.dg/concepts/pr94252.C: Verify we no longer issue a spurious unsatisfaction note when diagnosing ill-formed satisfaction. * g++.dg/cpp2a/concepts-requires18.C: No longer expect a spurious unsatisfaction diagnostic when evaluating the nested-requirement subst of a requires-expression that appears outside of a template. * g++.dg/cpp2a/concepts-requires21.C: Verify we no longer issue a spurious unsatisfaction note when evaluating a nested-requirement of a requires-expression that appears outside of a template. * g++.dg/cpp2a/concepts-nonbool3.C: New test. * g++.dg/cpp2a/concepts-pr97093.C: New test. --- gcc/cp/constraint.cc | 155 +++++++++++++++-------- gcc/testsuite/g++.dg/concepts/pr94252.C | 1 + gcc/testsuite/g++.dg/cpp2a/concepts-nonbool3.C | 5 + gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C | 32 +++++ gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C | 2 +- gcc/testsuite/g++.dg/cpp2a/concepts-requires21.C | 1 + 6 files changed, 142 insertions(+), 54 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-nonbool3.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C (limited to 'gcc') diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 00d2f2e..1117508 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -98,7 +98,42 @@ struct subst_info tree in_decl; }; -static tree satisfy_constraint (tree, tree, subst_info); +/* Provides additional context for satisfaction. + + The flag noisy() controls whether to diagnose ill-formed satisfaction, + such as the satisfaction value of an atom being non-bool or non-constant. + + The flag diagnose_unsatisfaction_p() controls whether to explain why + a constraint is not satisfied. + + The entrypoints to satisfaction for which we set noisy+unsat are + diagnose_constraints and diagnose_nested_requirement. The entrypoints for + which we set noisy-unsat are the replays inside constraint_satisfaction_value, + evaluate_concept_check and tsubst_nested_requirement. In other entrypoints, + e.g. constraints_satisfied_p, we enter satisfaction quietly (both flags + cleared). */ + +struct sat_info : subst_info +{ + sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false) + : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat) + { + if (diagnose_unsatisfaction_p ()) + gcc_checking_assert (noisy ()); + } + + /* True if we should diagnose the cause of satisfaction failure. + Implies noisy(). */ + bool + diagnose_unsatisfaction_p () const + { + return diagnose_unsatisfaction; + } + + bool diagnose_unsatisfaction; +}; + +static tree satisfy_constraint (tree, tree, sat_info); /* True if T is known to be some type other than bool. Note that this is false for dependent types and errors. */ @@ -2059,10 +2094,11 @@ tsubst_nested_requirement (tree t, tree args, subst_info info) { /* Ensure that we're in an evaluation context prior to satisfaction. */ tree norm = TREE_TYPE (t); - tree result = satisfy_constraint (norm, args, info); + tree result = satisfy_constraint (norm, args, + sat_info (info.complain, info.in_decl)); if (result == error_mark_node && info.quiet ()) { - subst_info noisy (tf_warning_or_error, info.in_decl); + sat_info noisy (tf_warning_or_error, info.in_decl); satisfy_constraint (norm, args, noisy); } if (result != boolean_true_node) @@ -2499,12 +2535,12 @@ tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl) return expr; } -static tree satisfy_constraint_r (tree, tree, subst_info info); +static tree satisfy_constraint_r (tree, tree, sat_info info); /* Compute the satisfaction of a conjunction. */ static tree -satisfy_conjunction (tree t, tree args, subst_info info) +satisfy_conjunction (tree t, tree args, sat_info info) { tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info); if (lhs == error_mark_node || lhs == boolean_false_node) @@ -2558,20 +2594,25 @@ collect_operands_of_disjunction (tree t, auto_vec *operands) /* Compute the satisfaction of a disjunction. */ static tree -satisfy_disjunction (tree t, tree args, subst_info info) +satisfy_disjunction (tree t, tree args, sat_info info) { - /* Evaluate the operands quietly. */ - subst_info quiet (tf_none, NULL_TREE); + /* Evaluate each operand with unsatisfaction diagnostics disabled. */ + sat_info sub = info; + sub.diagnose_unsatisfaction = false; - /* Register the constraint for diagnostics, if needed. */ - diagnosing_failed_constraint failure (t, args, info.noisy ()); + tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, sub); + if (lhs == boolean_true_node || lhs == error_mark_node) + return lhs; - tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, quiet); - if (lhs == boolean_true_node) - return boolean_true_node; - tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, quiet); - if (rhs != boolean_true_node && info.noisy ()) + tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, sub); + if (rhs == boolean_true_node || rhs == error_mark_node) + return rhs; + + /* Both branches evaluated to false. Explain the satisfaction failure in + each branch. */ + if (info.diagnose_unsatisfaction_p ()) { + diagnosing_failed_constraint failure (t, args, info.noisy ()); cp_expr disj_expr = CONSTR_EXPR (t); inform (disj_expr.get_location (), "no operand of the disjunction is satisfied"); @@ -2592,7 +2633,8 @@ satisfy_disjunction (tree t, tree args, subst_info info) } } } - return rhs; + + return boolean_false_node; } /* Ensures that T is a truth value and not (accidentally, as sometimes @@ -2673,7 +2715,7 @@ static void diagnose_atomic_constraint (tree, tree, tree, subst_info); /* Compute the satisfaction of an atomic constraint. */ static tree -satisfy_atom (tree t, tree args, subst_info info) +satisfy_atom (tree t, tree args, sat_info info) { satisfaction_cache cache (t, args, info.complain); if (tree r = cache.get ()) @@ -2691,9 +2733,9 @@ satisfy_atom (tree t, tree args, subst_info info) tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet); if (map == error_mark_node) { - /* If instantiation of the parameter mapping fails, the program - is ill-formed. */ - if (info.noisy()) + /* If instantiation of the parameter mapping fails, the constraint is + not satisfied. Replay the substitution. */ + if (info.diagnose_unsatisfaction_p ()) tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info); return cache.save (boolean_false_node); } @@ -2720,7 +2762,7 @@ satisfy_atom (tree t, tree args, subst_info info) { /* If substitution results in an invalid type or expression, the constraint is not satisfied. Replay the substitution. */ - if (info.noisy ()) + if (info.diagnose_unsatisfaction_p ()) tsubst_expr (expr, args, info.complain, info.in_decl, false); return cache.save (inst_cache.save (boolean_false_node)); } @@ -2748,7 +2790,7 @@ satisfy_atom (tree t, tree args, subst_info info) result = error_mark_node; } result = satisfaction_value (result); - if (result == boolean_false_node && info.noisy ()) + if (result == boolean_false_node && info.diagnose_unsatisfaction_p ()) diagnose_atomic_constraint (t, map, result, info); return cache.save (inst_cache.save (result)); @@ -2766,7 +2808,7 @@ satisfy_atom (tree t, tree args, subst_info info) constraint only matters for subsumption. */ static tree -satisfy_constraint_r (tree t, tree args, subst_info info) +satisfy_constraint_r (tree t, tree args, sat_info info) { if (t == error_mark_node) return error_mark_node; @@ -2787,7 +2829,7 @@ satisfy_constraint_r (tree t, tree args, subst_info info) /* Check that the normalized constraint T is satisfied for ARGS. */ static tree -satisfy_constraint (tree t, tree args, subst_info info) +satisfy_constraint (tree t, tree args, sat_info info) { auto_timevar time (TV_CONSTRAINT_SAT); @@ -2805,7 +2847,7 @@ satisfy_constraint (tree t, tree args, subst_info info) value (either true, false, or error). */ static tree -satisfy_associated_constraints (tree t, tree args, subst_info info) +satisfy_associated_constraints (tree t, tree args, sat_info info) { /* If there are no constraints then this is trivially satisfied. */ if (!t) @@ -2823,7 +2865,7 @@ satisfy_associated_constraints (tree t, tree args, subst_info info) satisfaction value. */ static tree -satisfy_constraint_expression (tree t, tree args, subst_info info) +satisfy_constraint_expression (tree t, tree args, sat_info info) { if (t == error_mark_node) return error_mark_node; @@ -2852,12 +2894,12 @@ satisfy_constraint_expression (tree t, tree args, subst_info info) tree satisfy_constraint_expression (tree expr) { - subst_info info (tf_none, NULL_TREE); + sat_info info (tf_none, NULL_TREE); return satisfy_constraint_expression (expr, NULL_TREE, info); } static tree -satisfy_declaration_constraints (tree t, subst_info info) +satisfy_declaration_constraints (tree t, sat_info info) { gcc_assert (DECL_P (t)); const tree saved_t = t; @@ -2917,7 +2959,7 @@ satisfy_declaration_constraints (tree t, subst_info info) } static tree -satisfy_declaration_constraints (tree t, tree args, subst_info info) +satisfy_declaration_constraints (tree t, tree args, sat_info info) { /* Update the declaration for diagnostics. */ info.in_decl = t; @@ -2942,9 +2984,8 @@ satisfy_declaration_constraints (tree t, tree args, subst_info info) } static tree -constraint_satisfaction_value (tree t, tsubst_flags_t complain) +constraint_satisfaction_value (tree t, sat_info info) { - subst_info info (complain, NULL_TREE); tree r; if (DECL_P (t)) r = satisfy_declaration_constraints (t, info); @@ -2952,26 +2993,31 @@ constraint_satisfaction_value (tree t, tsubst_flags_t complain) r = satisfy_constraint_expression (t, NULL_TREE, info); if (r == error_mark_node && info.quiet () && !(DECL_P (t) && TREE_NO_WARNING (t))) - { - constraint_satisfaction_value (t, tf_warning_or_error); - if (DECL_P (t)) - /* Avoid giving these errors again. */ - TREE_NO_WARNING (t) = true; - } + { + /* Replay the error with re-normalized requirements. */ + sat_info noisy (tf_warning_or_error, info.in_decl); + constraint_satisfaction_value (t, noisy); + if (DECL_P (t)) + /* Avoid giving these errors again. */ + TREE_NO_WARNING (t) = true; + } return r; } static tree -constraint_satisfaction_value (tree t, tree args, tsubst_flags_t complain) +constraint_satisfaction_value (tree t, tree args, sat_info info) { - subst_info info (complain, NULL_TREE); tree r; if (DECL_P (t)) r = satisfy_declaration_constraints (t, args, info); else r = satisfy_constraint_expression (t, args, info); if (r == error_mark_node && info.quiet ()) - constraint_satisfaction_value (t, args, tf_warning_or_error); + { + /* Replay the error with re-normalized requirements. */ + sat_info noisy (tf_warning_or_error, info.in_decl); + constraint_satisfaction_value (t, args, noisy); + } return r; } @@ -2984,7 +3030,8 @@ constraints_satisfied_p (tree t) if (!flag_concepts) return true; - return constraint_satisfaction_value (t, tf_none) == boolean_true_node; + sat_info quiet (tf_none, NULL_TREE); + return constraint_satisfaction_value (t, quiet) == boolean_true_node; } /* True iff the result of satisfying T with ARGS is BOOLEAN_TRUE_NODE @@ -2996,7 +3043,8 @@ constraints_satisfied_p (tree t, tree args) if (!flag_concepts) return true; - return constraint_satisfaction_value (t, args, tf_none) == boolean_true_node; + sat_info quiet (tf_none, NULL_TREE); + return constraint_satisfaction_value (t, args, quiet) == boolean_true_node; } /* Evaluate a concept check of the form C. This is only used for the @@ -3011,14 +3059,14 @@ evaluate_concept_check (tree check, tsubst_flags_t complain) gcc_assert (concept_check_p (check)); /* Check for satisfaction without diagnostics. */ - subst_info quiet (tf_none, NULL_TREE); + sat_info quiet (tf_none, NULL_TREE); tree result = satisfy_constraint_expression (check, NULL_TREE, quiet); if (result == error_mark_node && (complain & tf_error)) - { - /* Replay the error with re-normalized requirements. */ - subst_info noisy (tf_warning_or_error, NULL_TREE); - satisfy_constraint_expression (check, NULL_TREE, noisy); - } + { + /* Replay the error with re-normalized requirements. */ + sat_info noisy (tf_warning_or_error, NULL_TREE); + satisfy_constraint_expression (check, NULL_TREE, noisy); + } return result; } @@ -3496,7 +3544,7 @@ diagnose_nested_requirement (tree req, tree args) /* Quietly check for satisfaction first. We can elaborate details later if needed. */ tree norm = TREE_TYPE (req); - subst_info info (tf_none, NULL_TREE); + sat_info info (tf_none, NULL_TREE); tree result = satisfy_constraint (norm, args, info); if (result == boolean_true_node) return; @@ -3507,7 +3555,7 @@ diagnose_nested_requirement (tree req, tree args) { /* Replay the substitution error. */ inform (loc, "nested requirement %qE is not satisfied, because", expr); - subst_info noisy (tf_warning_or_error, NULL_TREE); + sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true); satisfy_constraint_expression (expr, args, noisy); } else @@ -3651,11 +3699,12 @@ diagnose_constraints (location_t loc, tree t, tree args) if (concepts_diagnostics_max_depth == 0) return; - /* Replay satisfaction, but diagnose errors. */ + /* Replay satisfaction, but diagnose unsatisfaction. */ + sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true); if (!args) - constraint_satisfaction_value (t, tf_warning_or_error); + constraint_satisfaction_value (t, noisy); else - constraint_satisfaction_value (t, args, tf_warning_or_error); + constraint_satisfaction_value (t, args, noisy); static bool suggested_p; if (concepts_diagnostics_max_depth_exceeded_p diff --git a/gcc/testsuite/g++.dg/concepts/pr94252.C b/gcc/testsuite/g++.dg/concepts/pr94252.C index 56ce5f8..b045703 100644 --- a/gcc/testsuite/g++.dg/concepts/pr94252.C +++ b/gcc/testsuite/g++.dg/concepts/pr94252.C @@ -16,6 +16,7 @@ static_assert(requires(S o, int i) { template concept c = requires (T t) { requires (T)5; }; // { dg-error "has type .int." } +// { dg-bogus "not satisfied" "" { target *-*-* } .-1 } int foo() diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-nonbool3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-nonbool3.C new file mode 100644 index 0000000..2a2af54 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-nonbool3.C @@ -0,0 +1,5 @@ +// { dg-do compile { target c++20 } } + +template concept C = false || V || false; // { dg-error "has type 'int'" } +template int f() requires C; +int a = f<0>(); // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C new file mode 100644 index 0000000..d662552 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C @@ -0,0 +1,32 @@ +// PR c++/97093 +// { dg-do compile { target c++20 } } +// { dg-additional-options "-fconcepts-diagnostics-depth=3 --param=hash-table-verification-limit=10000" } + +template +concept C = requires (T t) +{ + requires t.some_const < 2 || requires { t.some_fn (); }; +}; + +template +struct c +{}; + +template +concept P = requires (T t, c <0, 1> v) { { t (v) }; }; // { dg-error "no match" } + +template

+struct m +{ + constexpr auto operator () (C auto) const + {}; +}; + +struct pc +{ + constexpr auto operator () (C auto) const + {}; +}; + +constexpr auto cc = pc {}; +constexpr auto mmcc = m {}; // { dg-error "not satisfied" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C index a9b7720..9e45c58 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires18.C @@ -4,7 +4,7 @@ template concept integer = __is_same_as(T, int); template -concept subst = requires (T x) { requires true; }; // { dg-error "parameter type .void." } +concept subst = requires (T x) { requires true; }; template concept c1 = requires { requires integer || subst; }; // { dg-message "in requirements" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires21.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires21.C index bc38b89..8aead2f 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires21.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires21.C @@ -5,3 +5,4 @@ template constexpr bool is_same_v = __is_same (T, U); static_assert(is_same_v); +// { dg-bogus "evaluated to 'false" "" { target *-*-* } .-1 } -- cgit v1.1 From 40234200864b6c0d0079abbcdc7a4139b60257ff Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sat, 5 Dec 2020 13:44:20 -0500 Subject: c++: Normalize nested-requirements twice at parse time [PR97093] The re-normalization performed from diagnose_nested_requirement doesn't always work because we may have already lost the necessary template context that determines the set of in-scope template parameters used by the nested-requirement. This leads to normalization producing atoms that have incomplete/bogus parameter mappings, which breaks satisfaction. To fix this, we could just use the normal form that we previously computed at parse time, but this normal form lacks the diagnostic information that leads to good error messages. Instead, this patch makes diagnose_nested_requirement normalize twice at parse time -- once without diagnostic information and once with -- so that routines can use the "regular" normal form when performing satisfaction quietly and the "diagnostic" normal form when performing satisfaction noisily. Moreover, this patch makes tsubst_nested_requirement always first perform satisfaction quietly so that the satisfaction cache can get consistently utilized. This patch also adds some sanity checks to build_parameter_mapping that would have caught the underlying bug sooner (and deterministically). gcc/cp/ChangeLog: PR c++/97093 * constraint.cc (parameter_mapping_equivalent_p): Add some sanity checks. Clarify comment. (tsubst_nested_requirement): Always perform satisfaction quietly first. If that yields an erroneous result, emit a context message and replay satisfaction noisily with the diagnostic normal form. (finish_nested_requirement): Normalize the constraint-expression twice, once with diagnostic information and once without. Store them in a TREE_LIST within the TREE_TYPE. (diagnose_nested_requirement): When replaying satisfaction, use the diagnostic normal form instead of renormalizing on the spot. gcc/testsuite/ChangeLog: PR c++/97093 * g++.dg/cpp2a/concepts-requires22.C: New test. --- gcc/cp/constraint.cc | 41 +++++++++++++++--------- gcc/testsuite/g++.dg/cpp2a/concepts-requires22.C | 18 +++++++++++ 2 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires22.C (limited to 'gcc') diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 1117508..b4c501b 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -619,7 +619,8 @@ build_parameter_mapping (tree expr, tree args, tree decl) return map; } -/* True if the parameter mappings of two atomic constraints are equivalent. */ +/* True if the parameter mappings of two atomic constraints formed + from the same expression are equivalent. */ static bool parameter_mapping_equivalent_p (tree t1, tree t2) @@ -628,6 +629,7 @@ parameter_mapping_equivalent_p (tree t1, tree t2) tree map2 = ATOMIC_CONSTR_MAP (t2); while (map1 && map2) { + gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2)); tree arg1 = TREE_PURPOSE (map1); tree arg2 = TREE_PURPOSE (map2); if (!template_args_equal (arg1, arg2)) @@ -635,6 +637,7 @@ parameter_mapping_equivalent_p (tree t1, tree t2) map1 = TREE_CHAIN (map1); map2 = TREE_CHAIN (map2); } + gcc_checking_assert (!map1 && !map2); return true; } @@ -2092,14 +2095,16 @@ tsubst_compound_requirement (tree t, tree args, subst_info info) static tree tsubst_nested_requirement (tree t, tree args, subst_info info) { - /* Ensure that we're in an evaluation context prior to satisfaction. */ - tree norm = TREE_TYPE (t); - tree result = satisfy_constraint (norm, args, - sat_info (info.complain, info.in_decl)); - if (result == error_mark_node && info.quiet ()) + /* Perform satisfaction quietly with the regular normal form. */ + sat_info quiet (tf_none, info.in_decl); + tree norm = TREE_VALUE (TREE_TYPE (t)); + tree diag_norm = TREE_PURPOSE (TREE_TYPE (t)); + tree result = satisfy_constraint (norm, args, quiet); + if (result == error_mark_node) { + /* Replay the error using the diagnostic normal form. */ sat_info noisy (tf_warning_or_error, info.in_decl); - satisfy_constraint (norm, args, noisy); + satisfy_constraint (diag_norm, args, noisy); } if (result != boolean_true_node) return error_mark_node; @@ -3137,10 +3142,15 @@ finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept tree finish_nested_requirement (location_t loc, tree expr) { - tree norm = normalize_constraint_expression (expr, false); + /* We need to normalize the constraints now, at parse time, while + we have the necessary template context. We normalize twice, + once without diagnostic information and once with, which we'll + later use for quiet and noisy satisfaction respectively. */ + tree norm = normalize_constraint_expression (expr, /*diag=*/false); + tree diag_norm = normalize_constraint_expression (expr, /*diag=*/true); - /* Build the constraint, saving its normalization as its type. */ - tree r = build1 (NESTED_REQ, norm, expr); + /* Build the constraint, saving its two normalizations as its type. */ + tree r = build1 (NESTED_REQ, build_tree_list (diag_norm, norm), expr); SET_EXPR_LOCATION (r, loc); return r; } @@ -3541,9 +3551,10 @@ diagnose_type_requirement (tree req, tree args, tree in_decl) static void diagnose_nested_requirement (tree req, tree args) { - /* Quietly check for satisfaction first. We can elaborate details - later if needed. */ - tree norm = TREE_TYPE (req); + /* Quietly check for satisfaction first using the regular normal form. + We can elaborate details later if needed. */ + tree norm = TREE_VALUE (TREE_TYPE (req)); + tree diag_norm = TREE_PURPOSE (TREE_TYPE (req)); sat_info info (tf_none, NULL_TREE); tree result = satisfy_constraint (norm, args, info); if (result == boolean_true_node) @@ -3553,10 +3564,10 @@ diagnose_nested_requirement (tree req, tree args) location_t loc = cp_expr_location (expr); if (diagnosing_failed_constraint::replay_errors_p ()) { - /* Replay the substitution error. */ + /* Replay the substitution error using the diagnostic normal form. */ inform (loc, "nested requirement %qE is not satisfied, because", expr); sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true); - satisfy_constraint_expression (expr, args, noisy); + satisfy_constraint (diag_norm, args, noisy); } else inform (loc, "nested requirement %qE is not satisfied", expr); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires22.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires22.C new file mode 100644 index 0000000..5afcbbe --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires22.C @@ -0,0 +1,18 @@ +// PR c++/97093 +// { dg-do compile { target c++20 } } +// { dg-additional-options "-fconcepts-diagnostics-depth=3" } + +template +concept C = requires { + requires (X)x; // { dg-message "false" } + }; + +template +concept D = requires { + requires false || (X)x; // { dg-message "false" } + }; + +int main() { + static_assert(C); // { dg-error "failed" } + static_assert(D); // { dg-error "failed" } +} -- cgit v1.1 From bfa7dd84d1a0d83c716715e91c544203a7ad454d Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Sat, 5 Dec 2020 12:34:05 -0500 Subject: aix: fix ASM_OUTPUT_DEF warning ASM_OUTPUT_DEF is used by GCC as a proxy to enable alias support. But the macro does not provide the necessary implementation for symbol aliasing on AIX, which uses a different implementation. On AIX, the macro was empty. Because the macro is empty, none of the macro argument are used, which means that some of the variables in the function that calls the macro are never used. This causes a warning when building varasm.c, and -Werror converts that into a fatal error. This patch references the macro arguments as (void) to prevent the warning. 2020-12-05 Rainer Orth David Edelsohn gcc/ChangeLog: * config/rs6000/xcoff.h (ASM_OUTPUT_DEF): Reference macro arguments. --- gcc/config/rs6000/xcoff.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index 0f40b45..fe6221a 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -273,7 +273,9 @@ We still need to define this macro to let middle-end know that aliases are supported. */ -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0) +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { (void) (FILE); \ + (void) (LABEL1); \ + (void) (LABEL2); } while (0) /* Used by rs6000_assemble_integer, among others. */ -- cgit v1.1 From 6e1edf48ebe8881bc7c5e54157f47169290bdd12 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 6 Dec 2020 00:16:44 +0000 Subject: Daily bump. --- gcc/ChangeLog | 327 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 56 +++++++++ gcc/fortran/ChangeLog | 6 + gcc/testsuite/ChangeLog | 301 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 691 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 853d3b2..7a79a49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,330 @@ +2020-12-05 Rainer Orth + David Edelsohn + + * config/rs6000/xcoff.h (ASM_OUTPUT_DEF): Reference macro arguments. + +2020-12-05 Maciej W. Rozycki + + PR target/95294 + * config/vax/elf.h (REGISTER_NAMES): Append `%psl'. + * config/vax/vax-modes.def (CCN, CCNZ, CCZ): New modes. + * config/vax/vax-protos.h (vax_select_cc_mode): New prototype. + (vax_maybe_split_dimode_move): Likewise. + (vax_notice_update_cc): Remove prototype. + * config/vax/vax.c (TARGET_FLAGS_REGNUM): New macro. + (TARGET_CC_MODES_COMPATIBLE): Likewise. + (TARGET_MD_ASM_ADJUST): Likewise. + (vax_select_cc_mode): New function + (vax_cc_modes_compatible): Likewise. + (vax_md_asm_adjust): Likewise. + (vax_notice_update_cc): Remove function. + (vax_output_int_move): Factor out code checking if a DImode move + may have to be split... + (vax_maybe_split_dimode_move): ... into this new function. + * config/vax/vax.h (FIRST_PSEUDO_REGISTER): Bump up. + (FIXED_REGISTERS): Append an entry for PSL. + (CALL_USED_REGISTERS): Likewise. + (NOTICE_UPDATE_CC, OUTPUT_JUMP): Remove macros. + (SELECT_CC_MODE): New macro. + (REGISTER_NAMES): Append `psl'. + * config/vax/predicates.md (const_zero_operand) + (vax_cc_comparison_operator, vax_ccn_comparison_operator) + (vax_ccnz_comparison_operator, vax_ccz_comparison_operator): + New predicates. + * config/vax/builtins.md: Rewrite for MODE_CC representation. + * config/vax/vax.md: Likewise. + +2020-12-05 Maciej W. Rozycki + + * config/vax/elf.h (VAX_CC1_SPEC, VAX_CC1PLUS_SPEC): New macros. + * config/vax/netbsd-elf.h (CC1_SPEC): Use VAX_CC1_SPEC rather + than VAX_CC1_AND_CC1PLUS_SPEC. + (CC1PLUS_SPEC): Use VAX_CC1PLUS_SPEC rather than + VAX_CC1_AND_CC1PLUS_SPEC. + +2020-12-05 Maciej W. Rozycki + + * config/pdp11/pdp11.md (fcc_cc, fcc_ccnz): Use + `const_double_zero' to express double zero constant. + +2020-12-05 Maciej W. Rozycki + + * read-rtl.c (rtx_reader::read_rtx_code): Handle syntactic + `const_double_zero' rtx. + * doc/rtl.texi (Constant Expression Types): Document it. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (divmoddisi4, *amulsi4): Make the comment + notation consistent with the rest of the file. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (movti): Fix output predicate. Emit `movo' + rather than `movh'. + (divmoddisi4): Fix output predicates, correct RTL. + (*amulsi4): Name insn. Fix output predicate. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (mulsidi3): Fix the multiplicand predicates. + (*maddsidi4, *maddsidi4_const): Likewise. Name insns. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (*cmpv_2): Name insn. + (*cmpv, *cmpzv, *cmpzv_2): Likewise. Fix location predicate and + constraint. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (extv): Rename insn to... + (*extv): ... this. + (extv): New expander. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (*insv_aligned, *extzv_aligned) + (*extv_aligned): Also make sure the memory address of a bit-field + location can be adjusted in the PIC mode. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (*insv_aligned, *extzv_aligned) + (*extv_aligned): Reject register bit-field locations that are not + aligned to the least significant bit; update output statement + accordingly. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (*insv_aligned, *extzv_aligned) + (*extv_aligned, *extv_non_const, *extzv_non_const): Name insns. + Fix location predicate. + (*extzv): Name insn. + (*insv): Likewise. Fix location constraint. + (*insv_2): Likewise, and the predicate. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md (cpymemhi1): Rename insn to... + (movmemhi1): ... this. + (cpymemhi): Update accordingly. Remove constraints. + (movmemhi): New expander. + +2020-12-05 Maciej W. Rozycki + + * config/vax/builtins.md: Add a peephole2 for QImode and HImode + `ctz' operations. + (any_extend): New code iterator. + +2020-12-05 Maciej W. Rozycki + + * config/vax/builtins.md (width): New mode attribute. + (ffssi2): Rework expander into... + (ffs2): ... this. + (ctzsi2): Rework insn into... + (ctz2): ... this. + +2020-12-05 Maciej W. Rozycki + + * config/vax/builtins.md (ffssi2_internal): Rename insn to... + (ctzsi2): ... this. Update the RTL operation. + (ffssi2): Update accordingly. + * config/vax/vax.c (vax_notice_update_cc): Handle CTZ. + * config/vax/vax.h (CTZ_DEFINED_VALUE_AT_ZERO): New macro. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.md: Include `builtins.md'. + +2020-12-05 Maciej W. Rozycki + + * 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): Remove `set' and `unspec' + operations, match operands only. Reformat. + (sync_lock_release): Likewise. Remove cruft. + (jbbi): Wrap into `unspec_volatile', use + `any_memory_operand' predicate. + +2020-12-05 Maciej W. Rozycki + + * config/vax/builtins.md (bit): New int iterator. + (ccss): New int attribute. + (jbbssi, jbbcci): Fold insns into... + (jbbi): ... this. + +2020-12-05 Maciej W. Rozycki + + * config/vax/builtins.md (bb_mem): New mode attribute. + (jbbssiqi, jbbssihi, jbbssisi): Fold insns into... + (jbbssi): ... this. + (jbbcciqi, jbbccihi, jbbccisi): Likewise... + (jbbcci): ... this. + +2020-12-05 Maciej W. Rozycki + + * jump.c (pc_set): Also accept a jump wrapped in UNSPEC or + UNSPEC_VOLATILE. + (any_uncondjump_p, any_condjump_p): Update comment accordingly. + +2020-12-05 Maciej W. Rozycki + + * loop-doloop.c (add_test): Only remove the jump if `onlyjump_p'. + +2020-12-05 Maciej W. Rozycki + + * cfgrtl.c (rtl_block_empty_p): Return false if `!onlyjump_p' + too. + +2020-12-05 Maciej W. Rozycki + + * sel-sched-ir.c (maybe_tidy_empty_bb): Only try to remove a + conditional jump if `onlyjump_p'. + +2020-12-05 Maciej W. Rozycki + + * loop-iv.c (simplify_using_initial_values): Only process jumps + that match `onlyjump_p'. + (check_simple_exit): Likewise. + +2020-12-05 Maciej W. Rozycki + + * ifcvt.c (dead_or_predicable) [!IFCVT_MODIFY_TESTS]: Bail out + if `!onlyjump_p'. + +2020-12-05 Maciej W. Rozycki + + * read-rtl.c: Add a page-feed separator at the start of iterator + code. + (struct iterator_group): Change the return type to HOST_WIDE_INT + for the `find_builtin' member. Likewise the second parameter + type for the `apply_iterator' member. + (atoll) [!HAVE_ATOQ]: Reorder. + (find_mode, find_code): Change the return type to HOST_WIDE_INT. + (apply_mode_iterator, apply_code_iterator) + (apply_subst_iterator): Change the second parameter type to + HOST_WIDE_INT. + (find_int): Handle input suitable for HOST_WIDE_INT output. + (apply_int_iterator): Rewrite in terms of explicit format + interpretation. + (rtx_reader::read_rtx_operand) <'w'>: Fold into... + <'i', 'n', 'p'>: ... this. + * doc/md.texi (Int Iterators): Document 'w' rtx format support. + +2020-12-05 Maciej W. Rozycki + + * config/vax/builtins.md (ffssi2): Make preparation statements + actually buildable. + (ffssi2_internal): Fix input constraints; make the RTL pattern + match reality for `cc0'. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.c (vax_address_cost): Express the cost in terms + of COSTS_N_INSNS. + (vax_rtx_costs): Likewise. + +2020-12-05 Maciej W. Rozycki + + * config/vax/constraints.md (A): New constraint. + * config/vax/predicates.md (external_symbolic_operand) + (external_const_operand): Remove predicates. + (local_symbolic_operand): Rename to... + (pic_symbolic_operand): ... this, and rework. + (external_memory_operand): Rename to... + (non_pic_external_memory_operand): ... this, and rework. + (illegal_blk_memory_operand, illegal_addsub_di_memory_operand): + Update accordingly. + * config/vax/vax-protos.h (vax_acceptable_pic_operand_p): New + prototype. + * config/vax/vax.c (vax_acceptable_pic_operand_p): New function. + (vax_output_int_add): Update according to predicate rework. + * config/vax/vax.h (LEGITIMATE_PIC_OPERAND_P): New macro. + * config/vax/vax.md (pushlclsymreg, pushextsymreg): Fold + together, and rename to... + (*pushsymreg): ... this. Use the `pic_symbolic_operand' + predicate and the `A' constraint for the displacement operand. + (movlclsymreg, movextsymreg): Fold together, and rename to... + (*movsymreg): ... this. Use the `pic_symbolic_operand' + predicate and the `A' constraint for the displacement operand. + (pushextsym, pushlclsym): Fold together, and rename to... + (*pushsym): ... this. Use the `pic_symbolic_operand' predicate + and the `A' constraint for the displacement operand. + (movextsym, movlclsym): Fold together, and rename to... + (*movsym): ... this. Use the `pic_symbolic_operand' predicate + and the `A' constraint for the displacement operand. + +2020-12-05 Maciej W. Rozycki + + * config/vax/vax.c (print_operand): Replace `c' and `C' with + `k' and `K' respectively. + * config/vax/vax.md (*branch, *branch_reversed): Update + accordingly. + +2020-12-05 Matt Thomas + Maciej W. Rozycki + + PR target/58901 + * reload.c (push_reload): Also reload the inner expression of a + SUBREG for pseudos associated with a mode-dependent memory + reference. + (find_reloads): Force a reload likewise. + +2020-12-05 Roman Zhuykov + + PR rtl-optimization/97421 + * modulo-sched.c (generate_prolog_epilog): Remove forward + declaration, adjust last argument name and type. + (const_iteration_count): Add bool pointer parameter to return + whether count register is read in pre-header after its + initialization. + (sms_schedule): Fix count register initialization adjustment + procedure according to what const_iteration_count said. + +2020-12-05 Iain Sandoe + + PR target/97865 + * configure: Regenerate. + +2020-12-05 Venkataramanan Kumar + Sharavan Kumar + + * common/config/i386/cpuinfo.h (get_amd_cpu) recognize znver3. + * common/config/i386/i386-common.c (processor_names): Add + znver3. + (processor_alias_table): Add znver3 and AMDFAM19H entry. + * common/config/i386/i386-cpuinfo.h (processor_types): Add + AMDFAM19H. + (processor_subtypes): AMDFAM19H_ZNVER3. + * config.gcc (i[34567]86-*-linux* | ...): Likewise. + * config/i386/driver-i386.c: (host_detect_local_cpu): Let + -march=native recognize znver3 processors. + * config/i386/i386-c.c (ix86_target_macros_internal): Add + znver3. + * config/i386/i386-options.c (m_znver3): New definition. + (m_ZNVER): Include m_znver3. + (processor_cost_table): Add znver3. + * config/i386/i386.c (ix86_reassociation_width): Likewise. + * config/i386/i386.h (TARGET_znver3): New definition. + (enum processor_type): Add PROCESSOR_ZNVER3. + * config/i386/i386.md (define_attr "cpu"): Add znver3. + * config/i386/x86-tune-sched.c: (ix86_issue_rate): Likewise. + (ix86_adjust_cost): Likewise. + * config/i386/x86-tune.def (X86_TUNE_AVOID_256FMA_CHAINS: + Likewise. + * config/i386/znver1.md: Add new reservations for znver3. + * doc/extend.texi: Add details about znver3. + * doc/invoke.texi: Likewise. + +2020-12-05 Jakub Jelinek + + PR target/96226 + * config/i386/i386.md (splitter after *3_mask, + splitter after *3_mask_1): Drop the masking from + the patterns to split into. + 2020-12-04 Jason Merrill * vec.h (begin, end): Add overloads for vec*. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e4face1..4cbdc7e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20201205 +20201206 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6d5caf0..f0386a1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,59 @@ +2020-12-05 Patrick Palka + + PR c++/97093 + * constraint.cc (parameter_mapping_equivalent_p): Add some + sanity checks. Clarify comment. + (tsubst_nested_requirement): Always perform satisfaction + quietly first. If that yields an erroneous result, emit a + context message and replay satisfaction noisily with the + diagnostic normal form. + (finish_nested_requirement): Normalize the constraint-expression + twice, once with diagnostic information and once without. Store + them in a TREE_LIST within the TREE_TYPE. + (diagnose_nested_requirement): When replaying satisfaction, use + the diagnostic normal form instead of renormalizing on the spot. + +2020-12-05 Patrick Palka + + PR c++/97093 + * constraint.cc (struct sat_info): Define. + (tsubst_nested_requirement): Pass a sat_info object to + satisfy_constraint. + (satisfy_constraint_r): Take a sat_info argument instead of + subst_info. + (satisfy_conjunction): Likewise. + (satisfy_disjunction): Likewise. Instead of first evaluating + each branch quietly, evaluate each branch only with + unsatisfaction diagnostics disabled. Exit early if evaluation + of a branch returns error_mark_node. + (satisfy_atom): Take a sat_info argument instead of subst_info. + Fix a comment. Check diagnose_unsatisfaction_p() instead of + noisy() before replaying a substitution failure. + (satisfy_constraint): Take a sat_info argument instead of + subst_info. + (satisfy_associated_constraints): Likewise. + (satisfy_constraint_expression): Likewise. + (satisfy_declaration_constraints): Likewise. + (constraint_satisfaction_value): Likewise and adjust + accordingly. Fix formatting. + (constraints_satisfied_p): Pass a sat_info object to + constraint_satisfaction_value. + (evaluate_concept_check): Pass a sat_info object to + satisfy_constraint_expression. + (diagnose_nested_requirement): Likewise. + (diagnose_constraints): Pass an appropriate sat_info object to + constraint_satisfaction_value. + +2020-12-05 Jakub Jelinek + + PR c++/98122 + * constexpr.c (cxx_union_active_member): New function. + (cxx_fold_indirect_ref_1): Add ctx argument, pass it through to + recursive call. Handle UNION_TYPE. + (cxx_fold_indirect_ref): Add ctx argument, pass it to recursive calls + and cxx_fold_indirect_ref_1. + (cxx_eval_indirect_ref): Adjust cxx_fold_indirect_ref calls. + 2020-12-04 Jason Merrill PR c++/93083 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 1826640..8357d52 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2020-12-05 Paul Thomas + + PR fortran/98016 + * resolve.c (resolve_symbol): Set formal_arg_flag before + resolving an array spec and restore value afterwards. + 2020-12-03 Harald Anlauf PR fortran/95342 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5f39ce..a2ca0a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,304 @@ +2020-12-05 Patrick Palka + + PR c++/97093 + * g++.dg/cpp2a/concepts-requires22.C: New test. + +2020-12-05 Patrick Palka + + PR c++/97093 + * g++.dg/concepts/pr94252.C: Verify we no longer issue a + spurious unsatisfaction note when diagnosing ill-formed + satisfaction. + * g++.dg/cpp2a/concepts-requires18.C: No longer expect a + spurious unsatisfaction diagnostic when evaluating the + nested-requirement subst of a requires-expression that + appears outside of a template. + * g++.dg/cpp2a/concepts-requires21.C: Verify we no longer issue + a spurious unsatisfaction note when evaluating a + nested-requirement of a requires-expression that appears outside + of a template. + * g++.dg/cpp2a/concepts-nonbool3.C: New test. + * g++.dg/cpp2a/concepts-pr97093.C: New test. + +2020-12-05 Maciej W. Rozycki + + PR target/95294 + * gcc.target/vax/cmpelim-eq-adddf.c: New test. + * gcc.target/vax/cmpelim-eq-addhi.c: New test. + * gcc.target/vax/cmpelim-eq-addqi.c: New test. + * gcc.target/vax/cmpelim-eq-addsf.c: New test. + * gcc.target/vax/cmpelim-eq-addsi.c: New test. + * gcc.target/vax/cmpelim-eq-andhi.c: New test. + * gcc.target/vax/cmpelim-eq-andqi.c: New test. + * gcc.target/vax/cmpelim-eq-andsi.c: New test. + * gcc.target/vax/cmpelim-eq-ashlsi.c: New test. + * gcc.target/vax/cmpelim-eq-ashrsi.c: New test. + * gcc.target/vax/cmpelim-eq-divdf.c: New test. + * gcc.target/vax/cmpelim-eq-divhi.c: New test. + * gcc.target/vax/cmpelim-eq-divqi.c: New test. + * gcc.target/vax/cmpelim-eq-divsf.c: New test. + * gcc.target/vax/cmpelim-eq-divsi.c: New test. + * gcc.target/vax/cmpelim-eq-extendhisi.c: New test. + * gcc.target/vax/cmpelim-eq-extendqisi.c: New test. + * gcc.target/vax/cmpelim-eq-extvsi.c: New test. + * gcc.target/vax/cmpelim-eq-extzvsi.c: New test. + * gcc.target/vax/cmpelim-eq-fixdfhi.c: New test. + * gcc.target/vax/cmpelim-eq-fixdfqi.c: New test. + * gcc.target/vax/cmpelim-eq-fixdfsi.c: New test. + * gcc.target/vax/cmpelim-eq-fixsfhi.c: New test. + * gcc.target/vax/cmpelim-eq-fixsfqi.c: New test. + * gcc.target/vax/cmpelim-eq-fixsfsi.c: New test. + * gcc.target/vax/cmpelim-eq-floatsisf.c: New test. + * gcc.target/vax/cmpelim-eq-insvsi.c: New test. + * gcc.target/vax/cmpelim-eq-iorhi.c: New test. + * gcc.target/vax/cmpelim-eq-iorqi.c: New test. + * gcc.target/vax/cmpelim-eq-iorsi.c: New test. + * gcc.target/vax/cmpelim-eq-mova.c: New test. + * gcc.target/vax/cmpelim-eq-movdf.c: New test. + * gcc.target/vax/cmpelim-eq-movhi.c: New test. + * gcc.target/vax/cmpelim-eq-movqi.c: New test. + * gcc.target/vax/cmpelim-eq-movsf.c: New test. + * gcc.target/vax/cmpelim-eq-movsi.c: New test. + * gcc.target/vax/cmpelim-eq-muldf.c: New test. + * gcc.target/vax/cmpelim-eq-mulhi.c: New test. + * gcc.target/vax/cmpelim-eq-mulqi.c: New test. + * gcc.target/vax/cmpelim-eq-mulsf.c: New test. + * gcc.target/vax/cmpelim-eq-mulsi.c: New test. + * gcc.target/vax/cmpelim-eq-nothi.c: New test. + * gcc.target/vax/cmpelim-eq-notqi.c: New test. + * gcc.target/vax/cmpelim-eq-notsi.c: New test. + * gcc.target/vax/cmpelim-eq-rotlsi.c: New test. + * gcc.target/vax/cmpelim-eq-rotrsi.c: New test. + * gcc.target/vax/cmpelim-eq-subdf.c: New test. + * gcc.target/vax/cmpelim-eq-subhi.c: New test. + * gcc.target/vax/cmpelim-eq-subqi.c: New test. + * gcc.target/vax/cmpelim-eq-subsf.c: New test. + * gcc.target/vax/cmpelim-eq-subsi.c: New test. + * gcc.target/vax/cmpelim-eq-truncdfsf.c: New test. + * gcc.target/vax/cmpelim-eq-trunchiqi.c: New test. + * gcc.target/vax/cmpelim-eq-truncsihi.c: New test. + * gcc.target/vax/cmpelim-eq-truncsiqi.c: New test. + * gcc.target/vax/cmpelim-eq-zextendhisi.c: New test. + * gcc.target/vax/cmpelim-eq-zextendqihi.c: New test. + * gcc.target/vax/cmpelim-eq-zextendqisi.c: New test. + * gcc.target/vax/cmpelim-le-adddf.c: New test. + * gcc.target/vax/cmpelim-le-addhi.c: New test. + * gcc.target/vax/cmpelim-le-addqi.c: New test. + * gcc.target/vax/cmpelim-le-addsf.c: New test. + * gcc.target/vax/cmpelim-le-addsi.c: New test. + * gcc.target/vax/cmpelim-le-andhi.c: New test. + * gcc.target/vax/cmpelim-le-andqi.c: New test. + * gcc.target/vax/cmpelim-le-andsi.c: New test. + * gcc.target/vax/cmpelim-le-ashlsi.c: New test. + * gcc.target/vax/cmpelim-le-ashrsi.c: New test. + * gcc.target/vax/cmpelim-le-divdf.c: New test. + * gcc.target/vax/cmpelim-le-divhi.c: New test. + * gcc.target/vax/cmpelim-le-divqi.c: New test. + * gcc.target/vax/cmpelim-le-divsf.c: New test. + * gcc.target/vax/cmpelim-le-divsi.c: New test. + * gcc.target/vax/cmpelim-le-extendhisi.c: New test. + * gcc.target/vax/cmpelim-le-extendqisi.c: New test. + * gcc.target/vax/cmpelim-le-extvsi.c: New test. + * gcc.target/vax/cmpelim-le-extzvsi.c: New test. + * gcc.target/vax/cmpelim-le-fixdfhi.c: New test. + * gcc.target/vax/cmpelim-le-fixdfqi.c: New test. + * gcc.target/vax/cmpelim-le-fixdfsi.c: New test. + * gcc.target/vax/cmpelim-le-fixsfhi.c: New test. + * gcc.target/vax/cmpelim-le-fixsfqi.c: New test. + * gcc.target/vax/cmpelim-le-fixsfsi.c: New test. + * gcc.target/vax/cmpelim-le-floatsisf.c: New test. + * gcc.target/vax/cmpelim-le-insvsi.c: New test. + * gcc.target/vax/cmpelim-le-iorhi.c: New test. + * gcc.target/vax/cmpelim-le-iorqi.c: New test. + * gcc.target/vax/cmpelim-le-iorsi.c: New test. + * gcc.target/vax/cmpelim-le-movdf.c: New test. + * gcc.target/vax/cmpelim-le-movhi.c: New test. + * gcc.target/vax/cmpelim-le-movqi.c: New test. + * gcc.target/vax/cmpelim-le-movsf.c: New test. + * gcc.target/vax/cmpelim-le-movsi.c: New test. + * gcc.target/vax/cmpelim-le-muldf.c: New test. + * gcc.target/vax/cmpelim-le-mulhi.c: New test. + * gcc.target/vax/cmpelim-le-mulqi.c: New test. + * gcc.target/vax/cmpelim-le-mulsf.c: New test. + * gcc.target/vax/cmpelim-le-mulsi.c: New test. + * gcc.target/vax/cmpelim-le-nothi.c: New test. + * gcc.target/vax/cmpelim-le-notqi.c: New test. + * gcc.target/vax/cmpelim-le-notsi.c: New test. + * gcc.target/vax/cmpelim-le-rotlsi.c: New test. + * gcc.target/vax/cmpelim-le-rotrsi.c: New test. + * gcc.target/vax/cmpelim-le-subdf.c: New test. + * gcc.target/vax/cmpelim-le-subhi.c: New test. + * gcc.target/vax/cmpelim-le-subqi.c: New test. + * gcc.target/vax/cmpelim-le-subsf.c: New test. + * gcc.target/vax/cmpelim-le-subsi.c: New test. + * gcc.target/vax/cmpelim-le-truncdfsf.c: New test. + * gcc.target/vax/cmpelim-le-xorhi.c: New test. + * gcc.target/vax/cmpelim-le-xorqi.c: New test. + * gcc.target/vax/cmpelim-le-xorsi.c: New test. + * gcc.target/vax/cmpelim-leu-subhi.c: New test. + * gcc.target/vax/cmpelim-leu-subqi.c: New test. + * gcc.target/vax/cmpelim-leu-subsi.c: New test. + * gcc.target/vax/cmpelim-lt-adddf.c: New test. + * gcc.target/vax/cmpelim-lt-addhi.c: New test. + * gcc.target/vax/cmpelim-lt-addqi.c: New test. + * gcc.target/vax/cmpelim-lt-addsf.c: New test. + * gcc.target/vax/cmpelim-lt-addsi.c: New test. + * gcc.target/vax/cmpelim-lt-andhi.c: New test. + * gcc.target/vax/cmpelim-lt-andqi.c: New test. + * gcc.target/vax/cmpelim-lt-andsi.c: New test. + * gcc.target/vax/cmpelim-lt-ashlsi.c: New test. + * gcc.target/vax/cmpelim-lt-ashrsi.c: New test. + * gcc.target/vax/cmpelim-lt-divdf.c: New test. + * gcc.target/vax/cmpelim-lt-divhi.c: New test. + * gcc.target/vax/cmpelim-lt-divqi.c: New test. + * gcc.target/vax/cmpelim-lt-divsf.c: New test. + * gcc.target/vax/cmpelim-lt-divsi.c: New test. + * gcc.target/vax/cmpelim-lt-extendhisi.c: New test. + * gcc.target/vax/cmpelim-lt-extendqisi.c: New test. + * gcc.target/vax/cmpelim-lt-extvsi.c: New test. + * gcc.target/vax/cmpelim-lt-extzvsi.c: New test. + * gcc.target/vax/cmpelim-lt-fixdfhi.c: New test. + * gcc.target/vax/cmpelim-lt-fixdfqi.c: New test. + * gcc.target/vax/cmpelim-lt-fixdfsi.c: New test. + * gcc.target/vax/cmpelim-lt-fixsfhi.c: New test. + * gcc.target/vax/cmpelim-lt-fixsfqi.c: New test. + * gcc.target/vax/cmpelim-lt-fixsfsi.c: New test. + * gcc.target/vax/cmpelim-lt-floatsisf.c: New test. + * gcc.target/vax/cmpelim-lt-insvsi.c: New test. + * gcc.target/vax/cmpelim-lt-iorhi.c: New test. + * gcc.target/vax/cmpelim-lt-iorqi.c: New test. + * gcc.target/vax/cmpelim-lt-iorsi.c: New test. + * gcc.target/vax/cmpelim-lt-movdf.c: New test. + * gcc.target/vax/cmpelim-lt-movhi.c: New test. + * gcc.target/vax/cmpelim-lt-movqi.c: New test. + * gcc.target/vax/cmpelim-lt-movsf.c: New test. + * gcc.target/vax/cmpelim-lt-movsi.c: New test. + * gcc.target/vax/cmpelim-lt-muldf.c: New test. + * gcc.target/vax/cmpelim-lt-mulhi.c: New test. + * gcc.target/vax/cmpelim-lt-mulqi.c: New test. + * gcc.target/vax/cmpelim-lt-mulsf.c: New test. + * gcc.target/vax/cmpelim-lt-mulsi.c: New test. + * gcc.target/vax/cmpelim-lt-nothi.c: New test. + * gcc.target/vax/cmpelim-lt-notqi.c: New test. + * gcc.target/vax/cmpelim-lt-notsi.c: New test. + * gcc.target/vax/cmpelim-lt-rotlsi.c: New test. + * gcc.target/vax/cmpelim-lt-rotrsi.c: New test. + * gcc.target/vax/cmpelim-lt-subdf.c: New test. + * gcc.target/vax/cmpelim-lt-subhi.c: New test. + * gcc.target/vax/cmpelim-lt-subqi.c: New test. + * gcc.target/vax/cmpelim-lt-subsf.c: New test. + * gcc.target/vax/cmpelim-lt-subsi.c: New test. + * gcc.target/vax/cmpelim-lt-truncdfsf.c: New test. + * gcc.target/vax/cmpelim-lt-xorhi.c: New test. + * gcc.target/vax/cmpelim-lt-xorqi.c: New test. + * gcc.target/vax/cmpelim-lt-xorsi.c: New test. + * gcc.target/vax/cmpelim-ltu-subhi.c: New test. + * gcc.target/vax/cmpelim-ltu-subqi.c: New test. + * gcc.target/vax/cmpelim-ltu-subsi.c: New test. + * gcc.target/vax/cmpelim-xx-addsi.c: New test. + * gcc.target/vax/cmpelim-xx-insvsi.c: New test. + * gcc.target/vax/cmpelim-xxu-subsi.c: New test. + * gcc.target/vax/peephole2-eq-andhi.c: New test. + * gcc.target/vax/peephole2-eq-andqi.c: New test. + * gcc.target/vax/peephole2-eq-andsi.c: New test. + * gcc.target/vax/peephole2-eq-cmpvsi.c: New test. + * gcc.target/vax/peephole2-eq-cmpzvsi.c: New test. + * gcc.target/vax/peephole2-eq-ctzhi-0.c: New test. + * gcc.target/vax/peephole2-eq-ctzhi-1.c: New test. + * gcc.target/vax/peephole2-eq-ctzqi-0.c: New test. + * gcc.target/vax/peephole2-eq-ctzqi-1.c: New test. + * gcc.target/vax/peephole2-eq-ctzsi-0.c: New test. + * gcc.target/vax/peephole2-eq-ctzsi-1.c: New test. + * gcc.target/vax/peephole2-eq-ffshi.c: New test. + * gcc.target/vax/peephole2-eq-ffsqi.c: New test. + * gcc.target/vax/peephole2-eq-ffssi.c: New test. + * gcc.target/vax/peephole2-le-andhi.c: New test. + * gcc.target/vax/peephole2-le-andqi.c: New test. + * gcc.target/vax/peephole2-le-andsi.c: New test. + * gcc.target/vax/peephole2-le-cmpvsi.c: New test. + * gcc.target/vax/peephole2-le-cmpzvsi.c: New test. + * gcc.target/vax/peephole2-leu-cmpvsi.c: New test. + * gcc.target/vax/peephole2-leu-cmpzvsi.c: New test. + * gcc.target/vax/peephole2-lt-andhi.c: New test. + * gcc.target/vax/peephole2-lt-andqi.c: New test. + * gcc.target/vax/peephole2-lt-andsi.c: New test. + * gcc.target/vax/peephole2-lt-cmpvsi.c: New test. + * gcc.target/vax/peephole2-lt-cmpzvsi.c: New test. + * gcc.target/vax/peephole2-ltu-cmpvsi.c: New test. + * gcc.target/vax/peephole2-ltu-cmpzvsi.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/movmem.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/cpymem.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/ctzhi.c: New test. + * gcc.target/vax/ctzqi.c: New test. + * gcc.target/vax/ffshi.c: New test. + * gcc.target/vax/ffsqi.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/ctzsi.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/bbcci.c: New test. + * gcc.target/vax/bbssi.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/ffssi.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.dg/loop-8.c: Exclude for `vax-*-*'. + * gcc.target/vax/compare-add-zero.c: New test. + * gcc.target/vax/compare-mov-zero.c: New test. + +2020-12-05 Maciej W. Rozycki + + * gcc.target/vax/vax.exp: Use `gcc-dg-runtest' rather than + `dg-runtest'. + * gcc.target/vax/pr56875.c (dg-options): Make empty. + (a): Rewrite for calculations to make effect. Reformat. + +2020-12-05 Matt Thomas + Maciej W. Rozycki + + PR target/58901 + * gcc.c-torture/compile/pr58901-0.c: New test. + * gcc.c-torture/compile/pr58901-1.c: New test. + +2020-12-05 Roman Zhuykov + + PR rtl-optimization/97421 + * gcc.c-torture/execute/pr97421-1.c: New test. + * gcc.c-torture/execute/pr97421-2.c: New test. + * gcc.c-torture/execute/pr97421-3.c: New test. + +2020-12-05 Paul Thomas + + PR fortran/98016 + * gfortran.dg/pr98016.f90: New test. + +2020-12-05 Venkataramanan Kumar + Sharavan Kumar + + * gcc.target/i386/funcspec-56.inc: Handle new march. + * g++.target/i386/mv29.C: New file. + +2020-12-05 Jakub Jelinek + + PR c++/98122 + * g++.dg/cpp1y/constexpr-98122.C: New test. + * g++.dg/cpp2a/constexpr-98122.C: New test. + 2020-12-04 Jason Merrill PR c++/93083 -- cgit v1.1 From 1fab57f26ec24ce4e5672a7515c88611eba2483f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 29 Oct 2020 17:17:47 +1030 Subject: Re: testsuite: Adjust target requirements for sad-vectorize and signbit Fixes FAIL: gcc.target/powerpc/signbit-1.c scan-assembler-not stxvd2x FAIL: gcc.target/powerpc/signbit-1.c scan-assembler-times mfvsrd 3 FAIL: gcc.target/powerpc/signbit-1.c scan-assembler-times srdi 3 FAIL: gcc.target/powerpc/signbit-2.c scan-assembler-times ld 1 FAIL: gcc.target/powerpc/signbit-2.c scan-assembler-times srdi 1 on powerpc-linux (or powerpc64-linux biarch -m32). signbit-1.c is quite obviously a 64-bit only testcase given the scan-assembler directives, and the purpose of the testcase to verify the 64-bit only UNSPEC_SIGNBIT patterns. It could be made to pass for -m32 by adding -mpowerpc64, but that option that isn't very effective when bi-arch testing and results in errors on rs6000-aix. And it is pointless to match -m32 stores to the stack followed by loads, which is what we do at the moment. signbit-2.c on the other hand has more reasonable 32-bit output. * gcc.target/powerpc/signbit-1.c: Reinstate lp64 condition. * gcc.target/powerpc/signbit-2.c: Match 32-bit output too. --- gcc/testsuite/gcc.target/powerpc/signbit-1.c | 1 + gcc/testsuite/gcc.target/powerpc/signbit-2.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/powerpc/signbit-1.c b/gcc/testsuite/gcc.target/powerpc/signbit-1.c index eb4f53e..1642bf4 100644 --- a/gcc/testsuite/gcc.target/powerpc/signbit-1.c +++ b/gcc/testsuite/gcc.target/powerpc/signbit-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ /* { dg-require-effective-target ppc_float128_sw } */ /* { dg-require-effective-target powerpc_p8vector_ok } */ /* { dg-options "-mdejagnu-cpu=power8 -O2 -mfloat128" } */ diff --git a/gcc/testsuite/gcc.target/powerpc/signbit-2.c b/gcc/testsuite/gcc.target/powerpc/signbit-2.c index ff6af96..1b79291 100644 --- a/gcc/testsuite/gcc.target/powerpc/signbit-2.c +++ b/gcc/testsuite/gcc.target/powerpc/signbit-2.c @@ -13,5 +13,7 @@ int do_signbit_kf (__float128 *a) { return __builtin_signbit (*a); } /* { dg-final { scan-assembler-not "lxvw4x" } } */ /* { dg-final { scan-assembler-not "lxsd" } } */ /* { dg-final { scan-assembler-not "lxsdx" } } */ -/* { dg-final { scan-assembler-times "ld" 1 } } */ -/* { dg-final { scan-assembler-times "srdi" 1 } } */ +/* { dg-final { scan-assembler-times "ld" 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-times "srdi" 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-times "lwz" 1 { target ilp32 } } } */ +/* { dg-final { scan-assembler-times "rlwinm" 1 { target ilp32 } } } */ -- cgit v1.1 From bd0f0243869b3941a256ca0ea9c8aca141412f7e Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sun, 6 Dec 2020 10:14:13 +0100 Subject: Upper cobound is determined by num_images(), not this_image(). gcc/testsuite/ChangeLog: PR testsuite/98156 * gfortran.dg/coarray/alloc_comp_1.f90: Upper cobound is determined by num_images(), not this_image(). --- gcc/testsuite/gfortran.dg/coarray/alloc_comp_1.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/gfortran.dg/coarray/alloc_comp_1.f90 b/gcc/testsuite/gfortran.dg/coarray/alloc_comp_1.f90 index f809a5f..cf3ece2 100644 --- a/gcc/testsuite/gfortran.dg/coarray/alloc_comp_1.f90 +++ b/gcc/testsuite/gfortran.dg/coarray/alloc_comp_1.f90 @@ -10,7 +10,7 @@ allocate (a%caf[3:*]) a%caf = 7 if (a%caf /= 7) STOP 1 if (any (lcobound (a%caf) /= [ 3 ]) & - .or. ucobound (a%caf, dim=1) /= this_image ()+2) & + .or. ucobound (a%caf, dim=1) /= num_images ()+2) & STOP 2 deallocate (a%caf) end -- cgit v1.1 From 9e12b8b1819342ef7efac58cf7f4ba4294abe551 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 6 Dec 2020 10:55:12 +0100 Subject: match.pd: Improve conditional_replacement for x ? 0 : -1 [PR796232] As mentioned in the PR, for boolean x we currently optimize in phiopt x ? 0 : -1 into -(int)!x but it can be optimized as (int) x - 1 which is one less operation both in GIMPLE and in x86 assembly. This patch optimizes it in match.pd, by optimizing -(type)!x when x has boolean range into (type)x - 1. 2020-12-06 Jakub Jelinek PR tree-optimization/96232 * match.pd (-(type)!A -> (type)A - 1): New optimization. * gcc.dg/tree-ssa/pr96232-1.c: New test. --- gcc/match.pd | 10 ++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 68201ff..43bacb4 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3812,6 +3812,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cnd (logical_inverted_value truth_valued_p@0) @1 @2) (cnd @0 @2 @1))) +/* -(type)!A -> (type)A - 1. */ +(simplify + (negate (convert?:s (logical_inverted_value:s @0))) + (if (INTEGRAL_TYPE_P (type) + && TREE_CODE (type) != BOOLEAN_TYPE + && TYPE_PRECISION (type) > 1 + && TREE_CODE (@0) == SSA_NAME + && ssa_name_has_boolean_range (@0)) + (plus (convert:type @0) { build_all_ones_cst (type); }))) + /* A + (B vcmp C ? 1 : 0) -> A - (B vcmp C ? -1 : 0), since vector comparisons return all -1 or all 0 results. */ /* ??? We could instead convert all instances of the vec_cond to negate, diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c new file mode 100644 index 0000000..3170ffd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96232-1.c @@ -0,0 +1,11 @@ +/* PR tree-optimization/96232 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump " \\+ -1;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "~x_\[0-9]*\\\(D\\\)" "optimized" } } */ + +int +foo (_Bool x) +{ + return x ? 0 : -1; +} -- cgit v1.1 From 8c23434fdadcf4caa1f0e966294c5f67ccf4bcf9 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 6 Dec 2020 10:58:10 +0100 Subject: [PATCH] phiopt: Handle bool in two_value_replacement [PR796232] The following patch improves code generation on the included testcase by enabling two_value_replacement on booleans. It does that only for arg0/arg1 values that conditional_replacement doesn't handle. Additionally it limits two_value_replacement optimization to the late phiopt like conditional_replacement. 2020-12-06 Jakub Jelinek PR tree-optimization/96232 * tree-ssa-phiopt.c (two_value_replacement): Optimize even boolean lhs cases as long as arg0 has wider precision and conditional_replacement doesn't handle that case. (tree_ssa_phiopt_worker): Don't call two_value_replacement during early phiopt. * gcc.dg/tree-ssa/pr96232-2.c: New test. * gcc.dg/tree-ssa/pr88676-2.c: Check phiopt2 dump rather than phiopt1. --- gcc/testsuite/gcc.dg/tree-ssa/pr88676-2.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c | 18 ++++++++++++++++++ gcc/tree-ssa-phiopt.c | 23 +++++++++++++++++++---- 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88676-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88676-2.c index 0e61636..ea88407 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr88676-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88676-2.c @@ -1,7 +1,7 @@ /* PR tree-optimization/88676 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-phiopt1" } */ -/* { dg-final { scan-tree-dump-not " = PHI <" "phiopt1" { target le } } } */ +/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-final { scan-tree-dump-not " = PHI <" "phiopt2" { target le } } } */ struct foo1 { int i:1; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c new file mode 100644 index 0000000..9f51820 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96232-2.c @@ -0,0 +1,18 @@ +/* PR tree-optimization/96232 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump " 38 - " "optimized" } } */ +/* { dg-final { scan-tree-dump " \\+ 97;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "PHI <" "optimized" } } */ + +int +foo (_Bool x) +{ + return x ? 37 : 38; +} + +int +bar (_Bool x) +{ + return x ? 98 : 97; +} diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index e2758b2..21b88c0 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -337,7 +337,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) } /* Do the replacement of conditional if it can be done. */ - if (two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) + if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) cfgchanged = true; else if (!early_p && conditional_replacement (bb, bb1, e1, e2, phi, @@ -635,7 +635,6 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb, if (TREE_CODE (lhs) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)) - || TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE || TREE_CODE (rhs) != INTEGER_CST) return false; @@ -648,9 +647,25 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb, return false; } + /* Defer boolean x ? 0 : {1,-1} or x ? {1,-1} : 0 to + conditional_replacement. */ + if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE + && (integer_zerop (arg0) + || integer_zerop (arg1) + || TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE + || (TYPE_PRECISION (TREE_TYPE (arg0)) + <= TYPE_PRECISION (TREE_TYPE (lhs))))) + return false; + wide_int min, max; - if (get_range_info (lhs, &min, &max) != VR_RANGE - || min + 1 != max + if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE) + { + min = wi::to_wide (boolean_false_node); + max = wi::to_wide (boolean_true_node); + } + else if (get_range_info (lhs, &min, &max) != VR_RANGE) + return false; + if (min + 1 != max || (wi::to_wide (rhs) != min && wi::to_wide (rhs) != max)) return false; -- cgit v1.1 From 6643ca0be6f34786b686415e457de96d0d9fbd2d Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sun, 6 Dec 2020 10:43:16 -0800 Subject: x86: Check mode of pseudo register push commit 266f44a91c0c9705d3d18e82d7c5bab32927a18f Author: H.J. Lu Date: Sun May 17 10:10:34 2020 -0700 x86: Allow V1TI vector register pushes Add V1TI vector register push and split it after reload to a sequence of: (set (reg:P SP_REG) (plus:P SP_REG) (const_int -8))) (set (match_dup 0) (match_dup 1)) added a pseudo register push check. But (insn 13 12 14 3 (set (mem:SI (pre_dec:SI (reg/f:SI 7 sp)) [0 S4 A32]) (reg/v:SI 87 [ srclen ])) "x.c":37:16 54 {*pushsi2} (expr_list:REG_DEAD (reg/v:SI 87 [ srclen ]) (expr_list:REG_ARGS_SIZE (const_int 4 [0x4]) (nil)))) is not a pseudo register push. In 64-bit mode, mode of pseudo register push is TImode. In 32-bit mode, it is DImode. Add pseudo register push mode check to pseudo_reg_set. gcc/ PR target/98161 * config/i386/i386-features.c (pseudo_reg_set): Check mode of pseudo register push. gcc/testsuite/ * gcc.target/i386/pr98161.c: New test. --- gcc/config/i386/i386-features.c | 3 ++- gcc/testsuite/gcc.target/i386/pr98161.c | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr98161.c (limited to 'gcc') diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index ff6676f..c61685b 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -1266,9 +1266,10 @@ pseudo_reg_set (rtx_insn *insn) return NULL; /* Check pseudo register push first. */ + machine_mode mode = TARGET_64BIT ? TImode : DImode; if (REG_P (SET_SRC (set)) && !HARD_REGISTER_P (SET_SRC (set)) - && push_operand (SET_DEST (set), GET_MODE (SET_DEST (set)))) + && push_operand (SET_DEST (set), mode)) return set; df_ref ref; diff --git a/gcc/testsuite/gcc.target/i386/pr98161.c b/gcc/testsuite/gcc.target/i386/pr98161.c new file mode 100644 index 0000000..5825b9b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr98161.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msse4" } */ +/* { dg-require-effective-target sse4} */ + +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned char u8; + +u32 +__attribute__((__force_align_arg_pointer__)) +unreach(const u16 * pu16, u16 *dst, u32 dstlen, const u8 *src, u32 srclen) +{ + for (u32 i = dstlen; srclen && i; i--, srclen--, src++, dst++) + { + u16 off = pu16[*src]; + if (off) + { + src++; srclen--; + *dst = pu16[off + *src]; + } + } + return 56; +} + +u32 +__attribute__((__force_align_arg_pointer__)) +__attribute__((noipa)) +bug(const u16 * pu16, u16 *dst, u32 dstlen, const u8 *src, u32 srclen) +{ + if (pu16) + /* Branch should not execute, but stack realignment + * reads wrong 'pu16' value from stack. */ + return unreach(pu16, dst, dstlen, src, srclen); + + return (srclen < dstlen) ? srclen : dstlen; +} + +int +main() +{ + if (__builtin_cpu_supports ("sse4.1")) + { + /* Should return 12 */ + if (bug(0, 0, 12, 0, 34) != 12) + __builtin_abort (); + } + return 0; +} -- cgit v1.1 From 9da33826bb9b7d76f85057c18a0b65d0e14baa3d Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sun, 6 Dec 2020 07:07:26 -0800 Subject: doc: Remove -mcet -mcet was removed by commit 231baae28ef7ff784683fa5a80df119da2b9a99b Author: H.J. Lu Date: Tue Apr 24 16:56:04 2018 +0000 x86/CET: Remove the -mcet command-lint option PR target/98162 * doc/extend.texi: Remove -mcet. --- gcc/doc/extend.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 93529aa..fd282aa 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -24210,7 +24210,7 @@ void __builtin_ia32_wrpkru (unsigned int) unsigned int __builtin_ia32_rdpkru () @end smallexample -The following built-in functions are available when @option{-mcet} or +The following built-in functions are available when @option{-mshstk} option is used. They support shadow stack machine instructions from Intel Control-flow Enforcement Technology (CET). Each built-in function generates the machine instruction that is part -- cgit v1.1 From 0e49145550fe1284dc56e8e02ba1720c4f737a74 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 7 Dec 2020 00:16:22 +0000 Subject: Daily bump. --- gcc/ChangeLog | 25 +++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/testsuite/ChangeLog | 26 ++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a79a49..40af794 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2020-12-06 H.J. Lu + + PR target/98162 + * doc/extend.texi: Remove -mcet. + +2020-12-06 H.J. Lu + + PR target/98161 + * config/i386/i386-features.c (pseudo_reg_set): Check mode of + pseudo register push. + +2020-12-06 Jakub Jelinek + + PR tree-optimization/96232 + * tree-ssa-phiopt.c (two_value_replacement): Optimize even boolean lhs + cases as long as arg0 has wider precision and conditional_replacement + doesn't handle that case. + (tree_ssa_phiopt_worker): Don't call two_value_replacement during + early phiopt. + +2020-12-06 Jakub Jelinek + + PR tree-optimization/96232 + * match.pd (-(type)!A -> (type)A - 1): New optimization. + 2020-12-05 Rainer Orth David Edelsohn diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4cbdc7e..a4de7b0 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20201206 +20201207 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a2ca0a9..d65e539 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,29 @@ +2020-12-06 H.J. Lu + + * gcc.target/i386/pr98161.c: New test. + +2020-12-06 Jakub Jelinek + + PR tree-optimization/96232 + * gcc.dg/tree-ssa/pr96232-2.c: New test. + * gcc.dg/tree-ssa/pr88676-2.c: Check phiopt2 dump rather than phiopt1. + +2020-12-06 Jakub Jelinek + + PR tree-optimization/96232 + * gcc.dg/tree-ssa/pr96232-1.c: New test. + +2020-12-06 Thomas Koenig + + PR testsuite/98156 + * gfortran.dg/coarray/alloc_comp_1.f90: Upper cobound is + determined by num_images(), not this_image(). + +2020-12-06 Alan Modra + + * gcc.target/powerpc/signbit-1.c: Reinstate lp64 condition. + * gcc.target/powerpc/signbit-2.c: Match 32-bit output too. + 2020-12-05 Patrick Palka PR c++/97093 -- cgit v1.1 From 7b4ea2827d2003c8ffc76cd478f8974360cbd78f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 4 Dec 2020 11:13:48 +0100 Subject: tree-optimization/98137 - enhance split_constant_offset range handling split_constant_offset currently gives up looking at ranges when dealing with possibly wrapping operations for looking through conversions when the downstream analysis does not yield a SSA name. That's overly conservative and we have a nice helper that can deal with arbitrary expresssions. Use that. This helps data reference group analysis so the testcase is fully SLP vectorized, making use of the whole-function "BB" vectorization capabilities we now have. 2020-12-04 Richard Biener PR tree-optimization/98137 * tree-data-ref.c (split_constant_offset_1): Use determine_value_range instead of get_range_info to handle arbitrary expressions. * gcc.dg/vect/bb-slp-pr98137.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr98137.c | 27 +++++++++++++++++++++++++++ gcc/tree-data-ref.c | 24 ++++++++++++++---------- 2 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr98137.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr98137.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr98137.c new file mode 100644 index 0000000..ecf7df2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr98137.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ +/* { dg-require-effective-target vect_double } */ + +void +gemm (const double* __restrict__ A, const double* __restrict__ B, + double* __restrict__ C) +{ + unsigned int l_m = 0; + unsigned int l_n = 0; + unsigned int l_k = 0; + + for ( l_n = 0; l_n < 9; l_n++ ) { + /* Use -O3 so this loop is unrolled completely early. */ + for ( l_m = 0; l_m < 10; l_m++ ) { C[(l_n*10)+l_m] = 0.0; } + for ( l_k = 0; l_k < 17; l_k++ ) { + /* Use -O3 so this loop is unrolled completely early. */ + for ( l_m = 0; l_m < 10; l_m++ ) { + C[(l_n*10)+l_m] += A[(l_k*20)+l_m] * B[(l_n*20)+l_k]; + } + } + } +} + +/* Exact scanning is difficult but we expect all loads and stores + and computations to be vectorized. */ +/* { dg-final { scan-tree-dump "optimized: basic block" "slp1" } } */ diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 3bf460c..e8308ce 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -763,18 +763,22 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, tree tmp_var, tmp_off; split_constant_offset (op0, &tmp_var, &tmp_off, cache, limit); - /* See whether we have an SSA_NAME whose range is known - to be [A, B]. */ - if (TREE_CODE (tmp_var) != SSA_NAME) - return false; + /* See whether we have an known range [A, B] for tmp_var. */ wide_int var_min, var_max; - value_range_kind vr_type = get_range_info (tmp_var, &var_min, - &var_max); - wide_int var_nonzero = get_nonzero_bits (tmp_var); signop sgn = TYPE_SIGN (itype); - if (intersect_range_with_nonzero_bits (vr_type, &var_min, - &var_max, var_nonzero, - sgn) != VR_RANGE) + if (TREE_CODE (tmp_var) == SSA_NAME) + { + value_range_kind vr_type + = get_range_info (tmp_var, &var_min, &var_max); + wide_int var_nonzero = get_nonzero_bits (tmp_var); + if (intersect_range_with_nonzero_bits (vr_type, &var_min, + &var_max, + var_nonzero, + sgn) != VR_RANGE) + return false; + } + else if (determine_value_range (tmp_var, &var_min, &var_max) + != VR_RANGE) return false; /* See whether the range of OP0 (i.e. TMP_VAR + TMP_OFF) -- cgit v1.1 From 8441545d4f2afb9e9342e0dac378eafd03f00462 Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Mon, 7 Dec 2020 09:27:15 +0100 Subject: Don't build insn-extract.o with rtl checking As seen in PR98144, building insn-extract.o with rtl checking takes some memory, and it doesn't work on 32bit architectures at all (PR97314). Richard suggested on irc to disable rtl checking for this auto-generated file, like it's already done for genconditions.c. Patching it like done for genconditons.c. 2020-12-07 Matthias Klose * genextract.c (print_header): Undefine ENABLE_RTL_CHECKING and ENABLE_RTL_FLAG_CHECKING. --- gcc/genextract.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/genextract.c b/gcc/genextract.c index 63911e7..359681e 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -365,6 +365,8 @@ print_header (void) #define IN_TARGET_CODE 1\n\ #include \"config.h\"\n\ #include \"system.h\"\n\ +#undef ENABLE_RTL_CHECKING\n\ +#undef ENABLE_RTL_FLAG_CHECKING\n\ #include \"coretypes.h\"\n\ #include \"tm.h\"\n\ #include \"rtl.h\"\n\ -- cgit v1.1 From a6a0db7d1bc7ad640bab51769e53f1cb4ad4bb88 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 7 Dec 2020 09:35:09 +0100 Subject: ipa-cp: Avoid unwanted multiple propagations (PR 97816) When looking at the testcase of PR 97816 I realized that the reason why we were hitting overflows in size growth estimates in IPA-CP is not because the chains of how lattices feed values to each other are so long but mainly because we add estimates in callee lattices to caller lattices for each value source, which roughly corresponds to a call graph edge, and therefore if there are multiple calls between two functions passing the same value in a parameter we end up doing it more than once, sometimes actually quite many times. This patch avoids it by using a has_set to remember the source values we have already updated and not increasing their size again. Furhtermore, to improve estimation of times we scale the propagated time benefits with edge frequencies as we accumulate them. This should make any overflows very unlikely but not impossible, so I still included checks for overflows but decided to restructure the code to only need it in the propagate_effects function and modified it so that it does not need to perform the check before each sum. This is because I decided to add local estimates to propagated estimates already in propagate_effects and not at the evaluation time. The function can then do the sums in a wide type and discard them in the unlikely case of an overflow. I also decided to use the opportunity to make propagated effect stats now include stats from other values in the same SCCs. In the dumps I have seen this tended to increase size cost a tiny bit more than the estimated time benefit but both increases were small. Martin gcc/ChangeLog: 2020-11-20 Martin Jambor PR ipa/97816 * ipa-cp.c (safe_add): Removed. (good_cloning_opportunity_p): Remove special handling of INT_MAX. (value_topo_info::propagate_effects): Take care not to propagate from size one value to another through more sources. Scale propagated times with edge frequencies. Include local time and size in propagates ones here. Take care not to overflow size. (decide_about_value): Do not add local and propagated effects when passing them to good_cloning_opportunity_p. --- gcc/ipa-cp.c | 68 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'gcc') diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index a06b4d1..ac9bc23 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3272,13 +3272,6 @@ good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit, return false; gcc_assert (size_cost > 0); - if (size_cost == INT_MAX) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " good_cloning_opportunity_p returning " - "false because of size overflow.\n"); - return false; - } class ipa_node_params *info = IPA_NODE_REF (node); int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold); @@ -3848,20 +3841,6 @@ propagate_constants_topo (class ipa_topo_info *topo) } } - -/* Return the sum of A and B if none of them is bigger than INT_MAX/2, return - INT_MAX. */ - -static int -safe_add (int a, int b) -{ - if (a > INT_MAX/2 || b > INT_MAX/2) - return INT_MAX; - else - return a + b; -} - - /* Propagate the estimated effects of individual values along the topological from the dependent values to those they depend on. */ @@ -3870,30 +3849,51 @@ void value_topo_info::propagate_effects () { ipcp_value *base; + hash_set *> processed_srcvals; for (base = values_topo; base; base = base->topo_next) { ipcp_value_source *src; ipcp_value *val; sreal time = 0; - int size = 0; + HOST_WIDE_INT size = 0; for (val = base; val; val = val->scc_next) { time = time + val->local_time_benefit + val->prop_time_benefit; - size = safe_add (size, safe_add (val->local_size_cost, - val->prop_size_cost)); + size = size + val->local_size_cost + val->prop_size_cost; } for (val = base; val; val = val->scc_next) - for (src = val->sources; src; src = src->next) - if (src->val - && src->cs->maybe_hot_p ()) + { + processed_srcvals.empty (); + for (src = val->sources; src; src = src->next) + if (src->val + && src->cs->maybe_hot_p ()) + { + if (!processed_srcvals.add (src->val)) + { + HOST_WIDE_INT prop_size = size + src->val->prop_size_cost; + if (prop_size < INT_MAX) + src->val->prop_size_cost = prop_size; + else + continue; + } + src->val->prop_time_benefit + += time * src->cs->sreal_frequency (); + } + + if (size < INT_MAX) { - src->val->prop_time_benefit = time + src->val->prop_time_benefit; - src->val->prop_size_cost = safe_add (size, - src->val->prop_size_cost); + val->prop_time_benefit = time; + val->prop_size_cost = size; } + else + { + val->prop_time_benefit = 0; + val->prop_size_cost = 0; + } + } } } @@ -5508,12 +5508,8 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, if (!good_cloning_opportunity_p (node, val->local_time_benefit, freq_sum, count_sum, val->local_size_cost) - && !good_cloning_opportunity_p (node, - val->local_time_benefit - + val->prop_time_benefit, - freq_sum, count_sum, - safe_add (val->local_size_cost, - val->prop_size_cost))) + && !good_cloning_opportunity_p (node, val->prop_time_benefit, + freq_sum, count_sum, val->prop_size_cost)) return false; if (dump_file) -- cgit v1.1 From ad9c120a019ba4222bb062017da2db9711652dc3 Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Mon, 7 Dec 2020 09:40:53 +0100 Subject: Fix PR ada/97504 for mips*-linux 2020-12-07 Matthias Klose PR ada/97504 * Makefile.rtl (LIBGNAT_TARGET_PAIRS) : Use wraplf version of Aux_Long_Long_Float. --- gcc/ada/Makefile.rtl | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl index 544d0cf..64ddc26 100644 --- a/gcc/ada/Makefile.rtl +++ b/gcc/ada/Makefile.rtl @@ -2288,6 +2288,7 @@ endif ifeq ($(strip $(filter-out mips% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads Date: Mon, 7 Dec 2020 09:42:39 +0100 Subject: IBM Z: Change Pmode to word_mode for stack probes In s390.c we are still using Pmode for the stack probes. This breaks with -m31 -mzarch where Pmode != word_mode. The patch also adds a new target check to s390.exp which allows us to implement zarch specific checks in the testcases. gcc/ChangeLog: * config/s390/s390.c (s390_emit_stack_probe): Change Pmode to word_mode. gcc/testsuite/ChangeLog: * gcc.target/s390/s390.exp: New target check s390_zarch. * gcc.target/s390/stack-clash-1.c: Use s390_zarch instead of lp64. * gcc.target/s390/stack-clash-2.c: Likewise. * gcc.target/s390/stack-clash-3.c: Likewise. * gcc.target/s390/stack-clash-5.c: New test. --- gcc/config/s390/s390.c | 2 +- gcc/testsuite/gcc.target/s390/s390.exp | 7 +++++++ gcc/testsuite/gcc.target/s390/stack-clash-1.c | 4 ++-- gcc/testsuite/gcc.target/s390/stack-clash-2.c | 4 ++-- gcc/testsuite/gcc.target/s390/stack-clash-3.c | 4 ++-- gcc/testsuite/gcc.target/s390/stack-clash-5.c | 10 ++++++++++ 6 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/stack-clash-5.c (limited to 'gcc') diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index fb48102..2f83988 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -11082,7 +11082,7 @@ s390_prologue_plus_offset (rtx target, rtx reg, rtx offset, bool frame_related_p static void s390_emit_stack_probe (rtx addr) { - rtx mem = gen_rtx_MEM (Pmode, addr); + rtx mem = gen_rtx_MEM (word_mode, addr); MEM_VOLATILE_P (mem) = 1; emit_insn (gen_probe_stack (mem)); } diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp index 00e0555..d76d80d 100644 --- a/gcc/testsuite/gcc.target/s390/s390.exp +++ b/gcc/testsuite/gcc.target/s390/s390.exp @@ -202,6 +202,13 @@ proc check_effective_target_s390_z14_hw { } { } }] "-march=z14 -m64 -mzarch" ] } { return 0 } else { return 1 } } +# Return 1 if the default compiler options enable z/Architecture mode +proc check_effective_target_s390_zarch { } { + return [check_no_compiler_messages s390_zarch object { + int dummy[sizeof (int __attribute__((__mode__(__word__)))) == 8 + ? 1 : -1]; + }] +} # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-1.c b/gcc/testsuite/gcc.target/s390/stack-clash-1.c index 3d29cab..45221c4 100644 --- a/gcc/testsuite/gcc.target/s390/stack-clash-1.c +++ b/gcc/testsuite/gcc.target/s390/stack-clash-1.c @@ -13,5 +13,5 @@ void large_stack() { /* We use a compare for the stack probe. There needs to be one inside a loop and another for the remaining bytes. */ -/* { dg-final { scan-assembler-times "cg\t" 2 { target lp64 } } } */ -/* { dg-final { scan-assembler-times "c\t" 2 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times "cg\t" 2 { target s390_zarch } } } */ +/* { dg-final { scan-assembler-times "c\t" 2 { target { ! s390_zarch } } } } */ diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-2.c b/gcc/testsuite/gcc.target/s390/stack-clash-2.c index e554ad5..20f645d 100644 --- a/gcc/testsuite/gcc.target/s390/stack-clash-2.c +++ b/gcc/testsuite/gcc.target/s390/stack-clash-2.c @@ -13,5 +13,5 @@ foo () /* For alloca a common code routine emits the probes. Make sure the "probe_stack" expander is used in that case. We want to use mem compares instead of stores. */ -/* { dg-final { scan-assembler-times "cg\t" 5 { target lp64 } } } */ -/* { dg-final { scan-assembler-times "c\t" 5 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times "cg\t" 5 { target s390_zarch } } } */ +/* { dg-final { scan-assembler-times "c\t" 5 { target { ! s390_zarch } } } } */ diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-3.c b/gcc/testsuite/gcc.target/s390/stack-clash-3.c index 929d3fb..12a2d34 100644 --- a/gcc/testsuite/gcc.target/s390/stack-clash-3.c +++ b/gcc/testsuite/gcc.target/s390/stack-clash-3.c @@ -13,5 +13,5 @@ foo () /* For alloca a common code routine emits the probes. Make sure the "probe_stack" expander is used in that case. We want to use mem compares instead of stores. */ -/* { dg-final { scan-assembler-times "cg\t" 5 { target lp64 } } } */ -/* { dg-final { scan-assembler-times "c\t" 5 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times "cg\t" 5 { target s390_zarch } } } */ +/* { dg-final { scan-assembler-times "c\t" 5 { target { ! s390_zarch } } } } */ diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-5.c b/gcc/testsuite/gcc.target/s390/stack-clash-5.c new file mode 100644 index 0000000..81e202e --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/stack-clash-5.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -m31 -mzarch -fstack-clash-protection" } */ + +extern void bar (char*); + +void +foo() { + char a[4000]; + bar (a) ; +} -- cgit v1.1 From 090abb0f51b5cf8ce46fb686bc4b968f6e2055be Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:17:20 +0100 Subject: Fix problematic conversion to boolean type The new ranger exposed a problematic conversion to boolean type. gcc/ada/ChangeLog: * gcc-interface/utils.c (convert) : Call fold_convert in the cases where convert_to_integer is not called. : Call fold_convert instead of convert_to_integer. --- gcc/ada/gcc-interface/utils.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 013fccd..1d49db9 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -4930,10 +4930,6 @@ convert (tree type, tree expr) convert (TREE_TYPE (type), TYPE_MIN_VALUE (type)))); - /* ... fall through ... */ - - case ENUMERAL_TYPE: - case BOOLEAN_TYPE: /* If we are converting an additive expression to an integer type with lower precision, be wary of the optimization that can be applied by convert_to_integer. There are 2 problematic cases: @@ -4945,8 +4941,7 @@ convert (tree type, tree expr) intermediate conversion that changes the sign could be inserted and thus introduce an artificial overflow at compile time when the placeholder is substituted. */ - if (code == INTEGER_TYPE - && ecode == INTEGER_TYPE + if (ecode == INTEGER_TYPE && TYPE_PRECISION (type) < TYPE_PRECISION (etype) && (TREE_CODE (expr) == PLUS_EXPR || TREE_CODE (expr) == MINUS_EXPR)) { @@ -4955,11 +4950,18 @@ convert (tree type, tree expr) if ((TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (TREE_TYPE (op0))) || CONTAINS_PLACEHOLDER_P (expr)) - return build1 (NOP_EXPR, type, expr); + return fold_convert (type, expr); } + /* ... fall through ... */ + + case ENUMERAL_TYPE: return fold (convert_to_integer (type, expr)); + case BOOLEAN_TYPE: + /* Do not use convert_to_integer with boolean types. */ + return fold_convert_loc (EXPR_LOCATION (expr), type, expr); + case POINTER_TYPE: case REFERENCE_TYPE: /* If converting between two thin pointers, adjust if needed to account -- cgit v1.1 From 02221bed3c4912d59a865fa69bf12f54c980f957 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:30:05 +0100 Subject: Fix corner case issue with discriminated record type The compiler generates code that writes too much data into a component of a record subject to a representation clause, when the source of the assignment is a call to a function that returns a discriminated record type with default discriminants, variable size and a statically known upper bound for this size, and the size of the component given by the representation clause is lower than the value of this bound rounded up to the alignment. gcc/ada/ChangeLog: * gcc-interface/trans.c (Call_to_gnu): Also create a temporary for the return value if the LHS is a bit-field and the return type is a type padding a self-referential type. (gnat_to_gnu): Do not remove the padding on the result if it is too small with regard to the natural padding size. --- gcc/ada/gcc-interface/trans.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 0eec178..07e5a28 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -4513,7 +4513,11 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, and the return type has variable size, because the gimplifier doesn't handle these cases. - 4. There is no target and we have misaligned In Out or Out parameters + 4. There is a target which is a bit-field and the function returns an + unconstrained record type with default discriminant, because the + return may copy more data than the bit-field can contain. + + 5. There is no target and we have misaligned In Out or Out parameters passed by reference, because we need to preserve the return value before copying back the parameters. However, in this case, we'll defer creating the temporary, see below. @@ -4536,7 +4540,11 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target))) == INTEGER_CST)) - && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST))) + && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST) + || (gnu_target + && TREE_CODE (gnu_target) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (gnu_target, 1)) + && type_is_padding_self_referential (gnu_result_type)))) { gnu_retval = create_temporary ("R", gnu_result_type); DECL_RETURN_VALUE_P (gnu_retval) = 1; @@ -8249,8 +8257,10 @@ gnat_to_gnu (Node_Id gnat_node) /* Remove padding only if the inner object is of self-referential size: in that case it must be an object of unconstrained type with a default discriminant and we want to avoid copying too - much data. */ - if (type_is_padding_self_referential (TREE_TYPE (gnu_result))) + much data. But do not remove it if it is already too small. */ + if (type_is_padding_self_referential (TREE_TYPE (gnu_result)) + && !(TREE_CODE (gnu_result) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (gnu_result, 1)))) gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))), gnu_result); } -- cgit v1.1 From 6fb8da750ff53faec52aaa6cda31fbc510219926 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:34:31 +0100 Subject: Fix oversight in earlier change gcc/ada/ChangeLog: * gcc-interface/decl.c (gnat_to_gnu_entity) : Put back the "else" unduly removed. --- gcc/ada/gcc-interface/decl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index a0f17b1..7caca6a 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1764,6 +1764,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* Use the arbitrary scale factor description. Note that we support a Small_Value whose magnitude is larger than 64-bit even on 32-bit platforms, so we unconditionally use a (dummy) 128-bit type. */ + else { const Uint gnat_num = Norm_Num (gnat_small_value); const Uint gnat_den = Norm_Den (gnat_small_value); -- cgit v1.1 From 6a1e04b2f0c28d46e193d30aac00a32ba850bf0a Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:40:23 +0100 Subject: Fix assembler name collision Gigi uses a dummy global variable to register global types for debug info purposes and its name can now collide with user variables. gcc/ada/ChangeLog: * gcc-interface/trans.c (lvalue_for_aggregate_p): Also return true for return statements. * gcc-interface/utils.c (gnat_write_global_declarations): Use the maximum index for the dummy object to avoid a name collision. --- gcc/ada/gcc-interface/trans.c | 4 ++++ gcc/ada/gcc-interface/utils.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 07e5a28..bf8289b 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -970,6 +970,10 @@ lvalue_for_aggregate_p (Node_Id gnat_node, tree gnu_type) /* Even if the parameter is by copy, prefer an lvalue. */ return true; + case N_Simple_Return_Statement: + /* Likewise for a return value. */ + return true; + case N_Indexed_Component: case N_Selected_Component: /* If an elementary component is used, take it from the constant. */ diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 1d49db9..494f60e 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -5903,7 +5903,7 @@ gnat_write_global_declarations (void) struct varpool_node *node; char *label; - ASM_FORMAT_PRIVATE_NAME (label, first_global_object_name, 0); + ASM_FORMAT_PRIVATE_NAME (label, first_global_object_name, ULONG_MAX); dummy_global = build_decl (BUILTINS_LOCATION, VAR_DECL, get_identifier (label), void_type_node); -- cgit v1.1 From 67c4d1c7addc88c2d133731cf81ffad7d50fa8b9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:48:06 +0100 Subject: Fix internal error on library-level type extended locally The compiler aborts on the local extension of a tagged type declared at library level, with a progenitor given by an interface type having a primitive that is a homograph of a primitive of the tagged type. gcc/ada/ChangeLog: * gcc-interface/trans.c (maybe_make_gnu_thunk): Return false if the target is local and thunk and target do not have the same context. --- gcc/ada/gcc-interface/trans.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index bf8289b..4ab26d3 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -10730,8 +10730,11 @@ maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk) tree gnu_target = gnat_to_gnu_entity (gnat_target, NULL_TREE, false); - /* Thunk and target must have the same nesting level, if any. */ - gcc_assert (DECL_CONTEXT (gnu_thunk) == DECL_CONTEXT (gnu_target)); + /* If the target is local, then thunk and target must have the same context + because cgraph_node::expand_thunk can only forward the static chain. */ + if (DECL_STATIC_CHAIN (gnu_target) + && DECL_CONTEXT (gnu_thunk) != DECL_CONTEXT (gnu_target)) + return false; /* If the target returns by invisible reference and is external, apply the same transformation as Subprogram_Body_to_gnu here. */ -- cgit v1.1 From f8fb01fbb0c3c6b8ec0e5a301651b0824aaf880b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:56:05 +0100 Subject: Housekeeping work in gigi gcc/ada/ChangeLog: * gcc-interface/Make-lang.in: Remove ^L characters. * gcc-interface/decl.c (create_concat_name): Add cast. --- gcc/ada/gcc-interface/Make-lang.in | 7 +++---- gcc/ada/gcc-interface/decl.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 89b5750..d88c354 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -42,7 +42,7 @@ MV = mv MKDIR = mkdir -p RM = rm -f RMDIR = rm -rf - + # Extra flags to pass to recursive makes. COMMON_ADAFLAGS= -gnatpg @@ -814,7 +814,6 @@ doc/gnat_rm.pdf: ada/gnat_rm.texi $(gcc_docdir)/include/fdl.texi \ doc/gnat-style.pdf: ada/gnat-style.texi $(gcc_docdir)/include/fdl.texi $(TEXI2PDF) -c -I $(abs_docdir)/include -o $@ $< - # Install hooks: # gnat1 is installed elsewhere as part of $(COMPILERS). @@ -908,7 +907,7 @@ ada.maintainer-clean: -$(RM) ada/nmake.ads -$(RM) ada/treeprs.ads -$(RM) ada/snames.ads ada/snames.adb ada/snames.h - + # Stage hooks: # The main makefile has already created stage?/ada @@ -1005,7 +1004,7 @@ $(check_acats_targets): check-acats%: touch $$GCC_RUNTEST_PARALLELIZE_DIR/finished .PHONY: check-acats $(check_acats_targets) - + # Compiling object files from source files. # Ada language specific files. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 7caca6a..5ea1b16 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -10353,7 +10353,7 @@ create_concat_name (Entity_Id gnat_entity, const char *suffix) { const Entity_Kind kind = Ekind (gnat_entity); const bool has_suffix = (suffix != NULL); - String_Template temp = {1, has_suffix ? strlen (suffix) : 0}; + String_Template temp = {1, has_suffix ? (int) strlen (suffix) : 0}; String_Pointer sp = {suffix, &temp}; Get_External_Name (gnat_entity, has_suffix, sp); -- cgit v1.1 From cdcbef3c3310a14f2994982b44cb1f8e14c77232 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 7 Dec 2020 10:29:07 +0100 Subject: tree-optimization/98117 - fix range set by vectorization on niter IVs This avoids the degenerate case of a TYPE_MAX_VALUE latch iteration count value causing wrong range info for the vector IV. There's still the case of VF == 1 where if we don't know whether we hit the above case we cannot emit a range. 2020-12-07 Richard Biener PR tree-optimization/98117 * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Properly handle degenerate niter when setting the vector loop IV range. * gcc.dg/torture/pr98117.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr98117.c | 19 +++++++++++++++++++ gcc/tree-vect-loop-manip.c | 28 ++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr98117.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/torture/pr98117.c b/gcc/testsuite/gcc.dg/torture/pr98117.c new file mode 100644 index 0000000..f216025 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr98117.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-tree-scev-cprop" } */ + +unsigned char c; +void __attribute__((noipa)) +e() +{ + do + { + } + while (++c); +} +int main() +{ + e(); + if (c != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 3617918..2370b87 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -2034,13 +2034,29 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, niters_vector = force_gimple_operand (niters_vector, &stmts, true, var); gsi_insert_seq_on_edge_immediate (pe, stmts); /* Peeling algorithm guarantees that vector loop bound is at least ONE, - we set range information to make niters analyzer's life easier. */ + we set range information to make niters analyzer's life easier. + Note the number of latch iteration value can be TYPE_MAX_VALUE so + we have to represent the vector niter TYPE_MAX_VALUE + 1 >> log_vf. */ if (stmts != NULL && log_vf) - set_range_info (niters_vector, VR_RANGE, - wi::to_wide (build_int_cst (type, 1)), - wi::to_wide (fold_build2 (RSHIFT_EXPR, type, - TYPE_MAX_VALUE (type), - log_vf))); + { + if (niters_no_overflow) + set_range_info (niters_vector, VR_RANGE, + wi::one (TYPE_PRECISION (type)), + wi::rshift (wi::max_value (TYPE_PRECISION (type), + TYPE_SIGN (type)), + exact_log2 (const_vf), + TYPE_SIGN (type))); + /* For VF == 1 the vector IV might also overflow so we cannot + assert a minimum value of 1. */ + else if (const_vf > 1) + set_range_info (niters_vector, VR_RANGE, + wi::one (TYPE_PRECISION (type)), + wi::rshift (wi::max_value (TYPE_PRECISION (type), + TYPE_SIGN (type)) + - (const_vf - 1), + exact_log2 (const_vf), TYPE_SIGN (type)) + + 1); + } } *niters_vector_ptr = niters_vector; *step_vector_ptr = step_vector; -- cgit v1.1 From ebdfd1606da6b5aa586b0cd156b69b659235c9c2 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 3 Dec 2020 10:25:14 +0100 Subject: tree-optimization/98113 - vectorize a sequence of BIT_INSERT_EXPRs This adds the capability to handle a sequence of vector BIT_INSERT_EXPRs to be vectorized similar as to how we vectorize vector constructors. 2020-12-03 Richard Biener PR tree-optimization/98113 * tree-vectorizer.h (struct slp_root): New. (_bb_vec_info::roots): New member. * tree-vect-slp.c (vect_analyze_slp): Also walk BB info roots. (_bb_vec_info::_bb_vec_info): Adjust. (_bb_vec_info::~_bb_vec_info): Likewise. (vld_cmp): New. (vect_slp_is_lane_insert): Likewise. (vect_slp_check_for_constructors): Match a series of BIT_INSERT_EXPRs as vector constructor. (vect_slp_analyze_bb_1): Continue if BB info roots is not empty. (vect_slp_analyze_bb_1): Mark the whole BIT_INSERT_EXPR root sequence as pure_slp. * gcc.dg/vect/bb-slp-70.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-70.c | 17 +++ gcc/tree-vect-slp.c | 192 ++++++++++++++++++++++++++++++---- gcc/tree-vectorizer.h | 12 +++ 3 files changed, 200 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-70.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-70.c b/gcc/testsuite/gcc.dg/vect/bb-slp-70.c new file mode 100644 index 0000000..0eb7011 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-70.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mavx512vl -mavx512vpopcntdq" { target avx512vpopcntdq } } */ + +typedef unsigned uv4si __attribute__((vector_size(16))); + +uv4si __attribute__((noinline)) +vpopctf (uv4si a) +{ + uv4si r; + r[2] = __builtin_popcount (a[2]); + r[1] = __builtin_popcount (a[1]); + r[0] = __builtin_popcount (a[0]); + r[3] = __builtin_popcount (a[3]); + return r; +} + +/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target avx512vpopcntdq } } } */ diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 3bd40cb..2dccca0 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2578,6 +2578,19 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size) ? slp_inst_kind_store : slp_inst_kind_ctor, max_tree_size); + if (bb_vec_info bb_vinfo = dyn_cast (vinfo)) + { + for (unsigned i = 0; i < bb_vinfo->roots.length (); ++i) + { + vect_location = bb_vinfo->roots[i].root->stmt; + if (vect_build_slp_instance (bb_vinfo, bb_vinfo->roots[i].kind, + bb_vinfo->roots[i].stmts, + bb_vinfo->roots[i].root, + max_tree_size, bst_map, NULL)) + bb_vinfo->roots[i].stmts = vNULL; + } + } + if (loop_vec_info loop_vinfo = dyn_cast (vinfo)) { /* Find SLP sequences starting from reduction chains. */ @@ -3336,7 +3349,7 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo) /* Initialize a bb_vec_info struct for the statements in BBS basic blocks. */ _bb_vec_info::_bb_vec_info (vec _bbs, vec_info_shared *shared) - : vec_info (vec_info::bb, init_cost (NULL), shared), bbs (_bbs) + : vec_info (vec_info::bb, init_cost (NULL), shared), bbs (_bbs), roots (vNULL) { for (unsigned i = 0; i < bbs.length (); ++i) { @@ -3383,6 +3396,10 @@ _bb_vec_info::~_bb_vec_info () gimple_set_uid (stmt, -1); } } + + for (unsigned i = 0; i < roots.length (); ++i) + roots[i].stmts.release (); + roots.release (); } /* Subroutine of vect_slp_analyze_node_operations. Handle the root of NODE, @@ -4105,6 +4122,38 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo, return true; } +/* qsort comparator for lane defs. */ + +static int +vld_cmp (const void *a_, const void *b_) +{ + auto *a = (const std::pair *)a_; + auto *b = (const std::pair *)b_; + return a->first - b->first; +} + +/* Return true if USE_STMT is a vector lane insert into VEC and set + *THIS_LANE to the lane number that is set. */ + +static bool +vect_slp_is_lane_insert (gimple *use_stmt, tree vec, unsigned *this_lane) +{ + gassign *use_ass = dyn_cast (use_stmt); + if (!use_ass + || gimple_assign_rhs_code (use_ass) != BIT_INSERT_EXPR + || (vec + ? gimple_assign_rhs1 (use_ass) != vec + : ((vec = gimple_assign_rhs1 (use_ass)), false)) + || !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (vec)), + TREE_TYPE (gimple_assign_rhs2 (use_ass))) + || !constant_multiple_p + (tree_to_poly_uint64 (gimple_assign_rhs3 (use_ass)), + tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (TREE_TYPE (vec)))), + this_lane)) + return false; + return true; +} + /* Find any vectorizable constructors and add them to the grouped_store array. */ @@ -4116,28 +4165,114 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo) !gsi_end_p (gsi); gsi_next (&gsi)) { gassign *assign = dyn_cast (gsi_stmt (gsi)); - if (!assign || gimple_assign_rhs_code (assign) != CONSTRUCTOR) + if (!assign) continue; tree rhs = gimple_assign_rhs1 (assign); - if (!VECTOR_TYPE_P (TREE_TYPE (rhs)) - || maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)), - CONSTRUCTOR_NELTS (rhs)) - || VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value)) - || uniform_vector_p (rhs)) - continue; + if (gimple_assign_rhs_code (assign) == CONSTRUCTOR) + { + if (!VECTOR_TYPE_P (TREE_TYPE (rhs)) + || maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)), + CONSTRUCTOR_NELTS (rhs)) + || VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value)) + || uniform_vector_p (rhs)) + continue; - unsigned j; - tree val; - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val) - if (TREE_CODE (val) != SSA_NAME - || !bb_vinfo->lookup_def (val)) - break; - if (j != CONSTRUCTOR_NELTS (rhs)) - continue; + unsigned j; + tree val; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val) + if (TREE_CODE (val) != SSA_NAME + || !bb_vinfo->lookup_def (val)) + break; + if (j != CONSTRUCTOR_NELTS (rhs)) + continue; - stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (assign); - BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info); + stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (assign); + BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info); + } + else if (gimple_assign_rhs_code (assign) == BIT_INSERT_EXPR + && VECTOR_TYPE_P (TREE_TYPE (rhs)) + && TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)).is_constant () + && integer_zerop (gimple_assign_rhs3 (assign)) + && useless_type_conversion_p + (TREE_TYPE (TREE_TYPE (rhs)), + TREE_TYPE (gimple_assign_rhs2 (assign)))) + { + /* We start to match on insert to lane zero but since the + inserts need not be ordered we'd have to search both + the def and the use chains. */ + tree vectype = TREE_TYPE (rhs); + unsigned nlanes = TYPE_VECTOR_SUBPARTS (vectype).to_constant (); + auto_vec > lane_defs (nlanes); + auto_sbitmap lanes (nlanes); + bitmap_clear (lanes); + bitmap_set_bit (lanes, 0); + tree def = gimple_assign_lhs (assign); + lane_defs.quick_push + (std::make_pair (0, gimple_assign_rhs2 (assign))); + unsigned lanes_found = 1; + /* Start with the use chains, the last stmt will be the root. */ + stmt_vec_info last = bb_vinfo->lookup_stmt (assign); + do + { + use_operand_p use_p; + gimple *use_stmt; + if (!single_imm_use (def, &use_p, &use_stmt)) + break; + unsigned this_lane; + if (!bb_vinfo->lookup_stmt (use_stmt) + || !vect_slp_is_lane_insert (use_stmt, def, &this_lane) + || !bb_vinfo->lookup_def (gimple_assign_rhs2 (use_stmt))) + break; + if (bitmap_bit_p (lanes, this_lane)) + break; + lanes_found++; + bitmap_set_bit (lanes, this_lane); + gassign *use_ass = as_a (use_stmt); + lane_defs.quick_push (std::make_pair + (this_lane, gimple_assign_rhs2 (use_ass))); + last = bb_vinfo->lookup_stmt (use_ass); + def = gimple_assign_lhs (use_ass); + } + while (lanes_found < nlanes); + if (lanes_found < nlanes) + { + /* Now search the def chain. */ + def = gimple_assign_rhs1 (assign); + do + { + if (!has_single_use (def)) + break; + gimple *def_stmt = SSA_NAME_DEF_STMT (def); + unsigned this_lane; + if (!bb_vinfo->lookup_stmt (def_stmt) + || !vect_slp_is_lane_insert (def_stmt, + NULL_TREE, &this_lane) + || !bb_vinfo->lookup_def (gimple_assign_rhs2 (def_stmt))) + break; + if (bitmap_bit_p (lanes, this_lane)) + break; + lanes_found++; + bitmap_set_bit (lanes, this_lane); + lane_defs.quick_push (std::make_pair + (this_lane, + gimple_assign_rhs2 (def_stmt))); + def = gimple_assign_rhs1 (def_stmt); + } + while (lanes_found < nlanes); + } + if (lanes_found == nlanes) + { + /* Sort lane_defs after the lane index and register the root. */ + lane_defs.qsort (vld_cmp); + vec stmts; + stmts.create (nlanes); + for (unsigned i = 0; i < nlanes; ++i) + stmts.quick_push (bb_vinfo->lookup_def (lane_defs[i].second)); + bb_vinfo->roots.safe_push (slp_root (slp_inst_kind_ctor, + stmts, last)); + } + } } } @@ -4227,7 +4362,8 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, /* If there are no grouped stores and no constructors in the region there is no need to continue with pattern recog as vect_analyze_slp will fail anyway. */ - if (bb_vinfo->grouped_stores.is_empty ()) + if (bb_vinfo->grouped_stores.is_empty () + && bb_vinfo->roots.is_empty ()) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -4290,8 +4426,22 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, relevant. */ vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance)); vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance)); - if (SLP_INSTANCE_ROOT_STMT (instance)) - STMT_SLP_TYPE (SLP_INSTANCE_ROOT_STMT (instance)) = pure_slp; + if (stmt_vec_info root = SLP_INSTANCE_ROOT_STMT (instance)) + { + STMT_SLP_TYPE (root) = pure_slp; + if (is_gimple_assign (root->stmt) + && gimple_assign_rhs_code (root->stmt) == BIT_INSERT_EXPR) + { + /* ??? We should probably record the whole vector of + root stmts so we do not have to back-track here... */ + for (unsigned n = SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)); + n != 1; --n) + { + root = bb_vinfo->lookup_def (gimple_assign_rhs1 (root->stmt)); + STMT_SLP_TYPE (root) = pure_slp; + } + } + } i++; } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index c0f786c..95e8ea0 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -849,6 +849,16 @@ loop_vec_info_for_loop (class loop *loop) return (loop_vec_info) loop->aux; } +struct slp_root +{ + slp_root (slp_instance_kind kind_, vec stmts_, + stmt_vec_info root_) + : kind(kind_), stmts(stmts_), root(root_) {} + slp_instance_kind kind; + vec stmts; + stmt_vec_info root; +}; + typedef class _bb_vec_info : public vec_info { public: @@ -860,6 +870,8 @@ public: entry edge to cover bbs[0] PHI nodes and have a region entry insert location. */ vec bbs; + + vec roots; } *bb_vec_info; #define BB_VINFO_BB(B) (B)->bb -- cgit v1.1 From 724390745213d5192af04a51bb08cf44da7c396d Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Mon, 7 Dec 2020 14:26:46 +0000 Subject: doc: "used" attribute saves decls from linker garbage collection gcc/ChangeLog: * doc/extend.texi (used function attribute): Document saving the declaration from linker garbage collection. (used variable attribute): Likewise. --- gcc/doc/extend.texi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index fd282aa..0c96908 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3859,6 +3859,14 @@ When applied to a member function of a C++ class template, the attribute also means that the function is instantiated if the class itself is instantiated. +For ELF targets that support the GNU or FreeBSD OSABIs, this attribute +will also save the function from linker garbage collection. To support +this behavior, functions that have not been placed in specific sections +(e.g. by the @code{section} attribute, or the @code{-ffunction-sections} +option), will be placed in new, unique sections. + +This additional functionality requires Binutils version 2.36 or later. + @item visibility ("@var{visibility_type}") @cindex @code{visibility} function attribute This attribute affects the linkage of the declaration to which it is attached. @@ -7420,6 +7428,14 @@ When applied to a static data member of a C++ class template, the attribute also means that the member is instantiated if the class itself is instantiated. +For ELF targets that support the GNU or FreeBSD OSABIs, this attribute +will also save the variable from linker garbage collection. To support +this behavior, variables that have not been placed in specific sections +(e.g. by the @code{section} attribute, or the @code{-fdata-sections} option), +will be placed in new, unique sections. + +This additional functionality requires Binutils version 2.36 or later. + @item vector_size (@var{bytes}) @cindex @code{vector_size} variable attribute This attribute specifies the vector size for the type of the declared -- cgit v1.1 From 92e563d91b012f09da8fd152e934f6b964ae49cb Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 7 Dec 2020 16:00:00 +0100 Subject: Fix location info in ipa_param_body_adjustments::modify_call_stmt Copy the location info from the passed in call stmt to the newly built gimple call stmt. 2020-12-07 Bernd Edlinger * ipa-param-manipulation.c (ipa_param_body_adjustments::modify_call_stmt): Set location info. --- gcc/ipa-param-manipulation.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c index 2bbea21..9ab4a10 100644 --- a/gcc/ipa-param-manipulation.c +++ b/gcc/ipa-param-manipulation.c @@ -1681,6 +1681,8 @@ ipa_param_body_adjustments::modify_call_stmt (gcall **stmt_p) } } gcall *new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs); + if (gimple_has_location (stmt)) + gimple_set_location (new_stmt, gimple_location (stmt)); gimple_call_set_chain (new_stmt, gimple_call_chain (stmt)); gimple_call_copy_flags (new_stmt, stmt); if (tree lhs = gimple_call_lhs (stmt)) -- cgit v1.1 From 9d0eb0ae948f0fbee208cfb9a86133abea650f81 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 7 Dec 2020 07:02:58 -0800 Subject: c++: check alias match for specializations [PR98116] This fixes the underlying problem my recent (backedout) changes to array type creation uncovered. We had paths through structural_comptypes that ignored alias templates, even when significant. This adds the necessary checks. PR c++/98116 gcc/cp/ * typeck.c (structural_comptypes): Move early outs to comptype. Always check template-alias match when comparing_specializations. (comptypes): Do early out checking here. gcc/testsuite/ * g++.dg/template/pr98116.C: Remove dg-ice. * g++.dg/template/pr98116-2.C: New. --- gcc/cp/typeck.c | 61 ++++++++++++++++--------------- gcc/testsuite/g++.dg/template/pr98116-2.C | 34 +++++++++++++++++ gcc/testsuite/g++.dg/template/pr98116.C | 5 +-- 3 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/pr98116-2.C (limited to 'gcc') diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 267b284..4d499af 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1247,14 +1247,8 @@ cxx_safe_function_type_cast_p (tree t1, tree t2) static bool structural_comptypes (tree t1, tree t2, int strict) { - if (t1 == t2) - return true; - - /* Suppress errors caused by previously reported errors. */ - if (t1 == error_mark_node || t2 == error_mark_node) - return false; - - gcc_assert (TYPE_P (t1) && TYPE_P (t2)); + /* Both should be types that are not obviously the same. */ + gcc_checking_assert (t1 != t2 && TYPE_P (t1) && TYPE_P (t2)); if (!comparing_specializations) { @@ -1300,13 +1294,13 @@ structural_comptypes (tree t1, tree t2, int strict) /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type qualifiers (just above). */ - if (TREE_CODE (t1) != ARRAY_TYPE && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return true; - + goto check_alias; - /* Compare the types. Break out if they could be the same. */ + /* Compare the types. Return false on known not-same. Break on not + known. Never return true from this switch -- you'll break + specialization comparison. */ switch (TREE_CODE (t1)) { case VOID_TYPE: @@ -1332,7 +1326,11 @@ structural_comptypes (tree t1, tree t2, int strict) have identical properties, different TYPE_MAIN_VARIANTs, but represent the same type. The canonical type system keeps track of equivalence in this case, so we fall back on it. */ - return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2); + if (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2)) + return false; + + /* We don't need or want the attribute comparison. */ + goto check_alias; case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: @@ -1477,24 +1475,28 @@ structural_comptypes (tree t1, tree t2, int strict) return false; } - /* Don't treat an alias template specialization with dependent - arguments as equivalent to its underlying type when used as a - template argument; we need them to be distinct so that we - substitute into the specialization arguments at instantiation - time. And aliases can't be equivalent without being ==, so - we don't need to look any deeper. */ + /* If we get here, we know that from a target independent POV the + types are the same. Make sure the target attributes are also + the same. */ + if (!comp_type_attributes (t1, t2)) + return false; + + check_alias: if (comparing_specializations) { + /* Don't treat an alias template specialization with dependent + arguments as equivalent to its underlying type when used as a + template argument; we need them to be distinct so that we + substitute into the specialization arguments at instantiation + time. And aliases can't be equivalent without being ==, so + we don't need to look any deeper. */ tree dep1 = dependent_alias_template_spec_p (t1, nt_transparent); tree dep2 = dependent_alias_template_spec_p (t2, nt_transparent); if ((dep1 || dep2) && dep1 != dep2) return false; } - /* If we get here, we know that from a target independent POV the - types are the same. Make sure the target attributes are also - the same. */ - return comp_type_attributes (t1, t2); + return true; } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT @@ -1509,6 +1511,13 @@ comptypes (tree t1, tree t2, int strict) gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK && TREE_CODE (t2) != TYPE_ARGUMENT_PACK); + if (t1 == t2) + return true; + + /* Suppress errors caused by previously reported errors. */ + if (t1 == error_mark_node || t2 == error_mark_node) + return false; + if (strict == COMPARE_STRICT && comparing_specializations && (t1 != TYPE_CANONICAL (t1) || t2 != TYPE_CANONICAL (t2))) /* If comparing_specializations, treat dependent aliases as distinct. */ @@ -1516,12 +1525,6 @@ comptypes (tree t1, tree t2, int strict) if (strict == COMPARE_STRICT) { - if (t1 == t2) - return true; - - if (t1 == error_mark_node || t2 == error_mark_node) - return false; - if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2)) /* At least one of the types requires structural equality, so perform a deep check. */ diff --git a/gcc/testsuite/g++.dg/template/pr98116-2.C b/gcc/testsuite/g++.dg/template/pr98116-2.C new file mode 100644 index 0000000..fd12bb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr98116-2.C @@ -0,0 +1,34 @@ +// PR 98116, ICE with stripping typedef array type +// { dg-do compile { target c++11 } } +// { dg-additional-options {--param=hash-table-verification-limit=10000000 -fchecking=2} } + +// We got confused by alias templates that alias the same type. Their +// hashes were different (good), but they compared equal (bad) + +namespace std { +typedef int is_convertible; +template using remove_pointer_t = typename _Tp ::type; +template struct enable_if; +template void declval(); +template using enable_if_t = typename enable_if<_Cond>::type; +template class Trans_NS___cxx11_basic_string { + long _M_string_length; +}; +} // namespace std +struct string16_char_traits; +template class std::Trans_NS___cxx11_basic_string; +template using IsLegalDataConversion = std::is_convertible; +template +using ContainerHasConvertibleData = IsLegalDataConversion< + std::remove_pointer_t)>, T>; +template +using EnableIfSpanCompatibleArray = + std::enable_if_t)>; +template class span { + template [N], + std::Trans_NS___cxx11_basic_string, Extent>> + span(); +}; diff --git a/gcc/testsuite/g++.dg/template/pr98116.C b/gcc/testsuite/g++.dg/template/pr98116.C index 874c590..7d54314 100644 --- a/gcc/testsuite/g++.dg/template/pr98116.C +++ b/gcc/testsuite/g++.dg/template/pr98116.C @@ -1,10 +1,9 @@ // PR 98116, ICE with stripping typedef array type // { dg-do compile { target c++11 } } // { dg-additional-options {--param=hash-table-verification-limit=10000000 -fchecking=2} } -// { dg-ice "spec_hasher::equal" } -// We get confused by alias templates that alias the same type. -// { dg-prune-output "hash table checking failed" } +// We got confused by alias templates that alias the same type. Their +// hashes were different (good), but they compared equal (bad) namespace std { struct is_convertible; -- cgit v1.1 From ffb268ffcf9f21e2981a71887324eb0aec245eea Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 7 Dec 2020 08:47:24 -0800 Subject: c++: Adjust array type construction This restores the dependent array changes I reverted, now that pr98116 appears fixed. As mentioned before, when deserializing a module we need to construct arrays without using the dependent-type predicates themselves. gcc/cp/ * cp-tree.h (build_cplus_array_type): Add defaulted DEP parm. * tree.c (set_array_type_common): Add DEP parm. (build_cplus_array_type): Add DEP parm, determine dependency if needed. Mark dependency of new types. (cp_build_qualified_type_real): Adjust array-building call, assert no surprising dependency. (strip_typedefs): Likewise. --- gcc/cp/cp-tree.h | 2 +- gcc/cp/tree.c | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 00901fe..b72069e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7559,7 +7559,7 @@ extern bool is_local_temp (tree); extern tree build_aggr_init_expr (tree, tree); extern tree get_target_expr (tree); extern tree get_target_expr_sfinae (tree, tsubst_flags_t); -extern tree build_cplus_array_type (tree, tree); +extern tree build_cplus_array_type (tree, tree, int is_dep = -1); extern tree build_array_of_n_type (tree, int); extern bool array_of_runtime_bound_p (tree); extern bool vla_type_p (tree); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4e6bf9a..d9fa505 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -998,7 +998,7 @@ build_min_array_type (tree elt_type, tree index_type) build_cplus_array_type. */ static void -set_array_type_canon (tree t, tree elt_type, tree index_type) +set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep) { /* Set the canonical type for this new node. */ if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) @@ -1009,30 +1009,33 @@ set_array_type_canon (tree t, tree elt_type, tree index_type) TYPE_CANONICAL (t) = build_cplus_array_type (TYPE_CANONICAL (elt_type), index_type - ? TYPE_CANONICAL (index_type) : index_type); + ? TYPE_CANONICAL (index_type) : index_type, + dep); else TYPE_CANONICAL (t) = t; } /* Like build_array_type, but handle special C++ semantics: an array of a variant element type is a variant of the array of the main variant of - the element type. */ + the element type. IS_DEPENDENT is -ve if we should determine the + dependency. Otherwise its bool value indicates dependency. */ tree -build_cplus_array_type (tree elt_type, tree index_type) +build_cplus_array_type (tree elt_type, tree index_type, int dependent) { tree t; if (elt_type == error_mark_node || index_type == error_mark_node) return error_mark_node; - bool dependent = (uses_template_parms (elt_type) - || (index_type && uses_template_parms (index_type))); + if (dependent < 0) + dependent = (uses_template_parms (elt_type) + || (index_type && uses_template_parms (index_type))); if (elt_type != TYPE_MAIN_VARIANT (elt_type)) /* Start with an array of the TYPE_MAIN_VARIANT. */ t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type), - index_type); + index_type, dependent); else if (dependent) { /* Since type_hash_canon calls layout_type, we need to use our own @@ -1062,13 +1065,20 @@ build_cplus_array_type (tree elt_type, tree index_type) *e = t; /* Set the canonical type for this new node. */ - set_array_type_canon (t, elt_type, index_type); + set_array_type_canon (t, elt_type, index_type, dependent); + + /* Mark it as dependent now, this saves time later. */ + TYPE_DEPENDENT_P_VALID (t) = true; + TYPE_DEPENDENT_P (t) = true; } } else { bool typeless_storage = is_byte_access_type (elt_type); t = build_array_type (elt_type, index_type, typeless_storage); + + /* Mark as non-dependenty now, this will save time later. */ + TYPE_DEPENDENT_P_VALID (t) = true; } /* Now check whether we already have this array variant. */ @@ -1083,7 +1093,10 @@ build_cplus_array_type (tree elt_type, tree index_type) if (!t) { t = build_min_array_type (elt_type, index_type); - set_array_type_canon (t, elt_type, index_type); + /* Mark dependency now, this saves time later. */ + TYPE_DEPENDENT_P_VALID (t) = true; + TYPE_DEPENDENT_P (t) = dependent; + set_array_type_canon (t, elt_type, index_type, dependent); if (!dependent) { layout_type (t); @@ -1319,7 +1332,10 @@ cp_build_qualified_type_real (tree type, if (!t) { - t = build_cplus_array_type (element_type, TYPE_DOMAIN (type)); + gcc_checking_assert (TYPE_DEPENDENT_P_VALID (type) + || !dependent_type_p (type)); + t = build_cplus_array_type (element_type, TYPE_DOMAIN (type), + TYPE_DEPENDENT_P (type)); /* Keep the typedef name. */ if (TYPE_NAME (t) != TYPE_NAME (type)) @@ -1555,7 +1571,9 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) case ARRAY_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags); - result = build_cplus_array_type (type, t0); + gcc_checking_assert (TYPE_DEPENDENT_P_VALID (t) + || !dependent_type_p (t)); + result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t)); break; case FUNCTION_TYPE: case METHOD_TYPE: -- cgit v1.1 From 1cac89da2cb1f2a7c2d93f7f325484c2d1619ca8 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 3 Dec 2020 18:35:00 -0500 Subject: c-family: Fix hang with -Wsequence-point [PR98126] verify_sequence_points uses verify_tree to recursively walk the subexpressions of an expression, and while recursing, it also keeps lists of expressions found after/before a sequence point. For a large expression, the list can grow significantly. And merge_tlist is at least N(n^2): for a list of length n it will iterate n(n -1) times, and call candidate_equal_p each time, and that can recurse further. warn_for_collision also has to go through the whole list. With a large-enough expression, the compilation can easily get stuck here for 24 hours. This patch is a simple kludge: if we see that the expression is overly complex, don't even try. gcc/c-family/ChangeLog: PR c++/98126 * c-common.c (verify_tree_lim_r): New function. (verify_sequence_points): Use it. Use nullptr instead of 0. gcc/testsuite/ChangeLog: PR c++/98126 * g++.dg/warn/Wsequence-point-4.C: New test. --- gcc/c-family/c-common.c | 32 +++++++++++++--- gcc/testsuite/g++.dg/warn/Wsequence-point-4.C | 53 +++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wsequence-point-4.C (limited to 'gcc') diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index dda2352..0b348ae 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -2056,23 +2056,45 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp, } } +static constexpr size_t verify_sequence_points_limit = 1024; + +/* Called from verify_sequence_points via walk_tree. */ + +static tree +verify_tree_lim_r (tree *tp, int *walk_subtrees, void *data) +{ + if (++*((size_t *) data) > verify_sequence_points_limit) + return integer_zero_node; + + if (TYPE_P (*tp)) + *walk_subtrees = 0; + + return NULL_TREE; +} + /* Try to warn for undefined behavior in EXPR due to missing sequence points. */ void verify_sequence_points (tree expr) { - struct tlist *before_sp = 0, *after_sp = 0; + tlist *before_sp = nullptr, *after_sp = nullptr; + + /* verify_tree is highly recursive, and merge_tlist is O(n^2), + so we return early if the expression is too big. */ + size_t n = 0; + if (walk_tree (&expr, verify_tree_lim_r, &n, nullptr)) + return; - warned_ids = 0; - save_expr_cache = 0; - if (tlist_firstobj == 0) + warned_ids = nullptr; + save_expr_cache = nullptr; + if (!tlist_firstobj) { gcc_obstack_init (&tlist_obstack); tlist_firstobj = (char *) obstack_alloc (&tlist_obstack, 0); } - verify_tree (expr, &before_sp, &after_sp, 0); + verify_tree (expr, &before_sp, &after_sp, NULL_TREE); warn_for_collisions (after_sp); obstack_free (&tlist_obstack, tlist_firstobj); } diff --git a/gcc/testsuite/g++.dg/warn/Wsequence-point-4.C b/gcc/testsuite/g++.dg/warn/Wsequence-point-4.C new file mode 100644 index 0000000..b3d9cf1 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsequence-point-4.C @@ -0,0 +1,53 @@ +// PR c++/98126 +// { dg-do compile } +// { dg-options "-Wsequence-point" } +// Make sure we don't hang when verify_tree processes a large expression. + +struct T { bool operator==(const T &ot) const; }; + +#define CMP(M, N, L) t[100 * M + 10 * N + L] == ot.t[100 * M + 10 * N + L] && + +#define CMP1(M, N) \ + CMP(M, N, 0) \ + CMP(M, N, 1) \ + CMP(M, N, 2) \ + CMP(M, N, 3) \ + CMP(M, N, 4) \ + CMP(M, N, 5) \ + CMP(M, N, 6) \ + CMP(M, N, 7) \ + CMP(M, N, 8) \ + CMP(M, N, 9) + +#define CMP2(M) \ + CMP1(M, 0) \ + CMP1(M, 1) \ + CMP1(M, 2) \ + CMP1(M, 3) \ + CMP1(M, 4) \ + CMP1(M, 5) \ + CMP1(M, 6) \ + CMP1(M, 7) \ + CMP1(M, 8) \ + CMP1(M, 9) + +#define GENERATE_CMPS \ + CMP2(0) \ + CMP2(1) \ + CMP2(2) \ + CMP2(3) \ + CMP2(4) \ + CMP2(5) \ + CMP2(6) \ + CMP2(7) \ + CMP2(8) \ + CMP2(9) + +struct C { + bool operator==(const C &ot) const { + return + GENERATE_CMPS + true; + } + T t[999]; +}; -- cgit v1.1 From e9104775e3beceab247050733da97fbba5341cb7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 5 Dec 2020 08:09:53 -0800 Subject: compiler: don't name type descriptor for alias type The test case is https://golang.org/cl/275632. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/275652 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/names.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 019aafd..02083ed 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -342e5f0b349553a69d7c99a18162ae2a1e6e5775 +2184750d74d37580486e90df1284c07fdee91670 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc index 0097417..8e73e5e 100644 --- a/gcc/go/gofrontend/names.cc +++ b/gcc/go/gofrontend/names.cc @@ -1017,7 +1017,7 @@ Gogo::type_descriptor_backend_name(const Type* type, Named_type* nt, bool is_pointer = false; if (nt == NULL && type->points_to() != NULL) { - nt = type->points_to()->named_type(); + nt = type->points_to()->unalias()->named_type(); is_pointer = true; } -- cgit v1.1 From 16a2a458809103d1c382c09c62b09697aac9b935 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 7 Dec 2020 09:36:15 -0800 Subject: go-test.exp: don't quote already-quoted parentheses * go.test/go-test.exp (errchk): Don't backslash quote parentheses that are already backslash quoted. --- gcc/testsuite/go.test/go-test.exp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/go.test/go-test.exp b/gcc/testsuite/go.test/go-test.exp index 8f17cb3..d129e1c 100644 --- a/gcc/testsuite/go.test/go-test.exp +++ b/gcc/testsuite/go.test/go-test.exp @@ -131,11 +131,11 @@ proc errchk { test opts } { set index [string first "dg-error" $out_line] regsub -start $index -all "\(\[^\\\\]\)\}\(.\)" $out_line "\\1\\\\\[\\\}\\\\\]\\2" out_line } - if [string match "*dg-error*\(*" $out_line] { + if [string match "*dg-error*\\\[^\\\\\]\(*" $out_line] { set index [string first "dg-error" $out_line] regsub -start $index -all "\\\\\\\(" $out_line "\\\\\[\\\(\\\\\]" out_line } - if [string match "*dg-error*\)*\}" $out_line] { + if [string match "*dg-error*\\\[^\\\\\]\)*\}" $out_line] { set index [string first "dg-error" $out_line] regsub -start $index -all "\\\\\\\)\(.\)" $out_line "\\\\\[\\\)\\\\\]\\1" out_line } -- cgit v1.1 From 7482d5a3acb7a8a5564f5cddc4f9d2ebbaea75e4 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 2 Dec 2020 10:47:49 -0500 Subject: c++: ICE with switch and scoped enum bit-fields [PR98043] In this testcase we are crashing trying to gimplify a switch, because the types of the switch condition and case constants have different TYPE_PRECISIONs. This started with my r5-3726 fix: SWITCH_STMT_TYPE is supposed to be the original type of the switch condition before any conversions, so in the C++ FE we need to use unlowered_expr_type to get the unlowered type of enum bit-fields. Normally, the switch type is subject to integral promotions, but here we have a scoped enum type and those don't promote: enum class B { A }; struct C { B c : 8; }; switch (x.c) // type B case B::A: // type int, will be converted to B Here TREE_TYPE is "signed char" but SWITCH_STMT_TYPE is "B". When gimplifying this in gimplify_switch_expr, the index type is "B" and we convert all the case values to "B" in preprocess_case_label_vec, but SWITCH_COND is of type "signed char": gimple_switch_index should be the (possibly promoted) type, not the original type, so we gimplify the "x.c" SWITCH_COND to a SSA_NAME of type "signed char". And then we crash because the precision of the index type doesn't match the precision of the case value type. I think it makes sense to do the following; at the end of pop_switch we've already issued the switch warnings, and since scoped enums don't promote, it should be okay to use the type of SWITCH_STMT_COND. The r5-3726 change was about giving warnings for enum bit-fields anyway. gcc/cp/ChangeLog: PR c++/98043 * decl.c (pop_switch): If SWITCH_STMT_TYPE is a scoped enum type, set it to the type of SWITCH_STMT_COND. gcc/testsuite/ChangeLog: PR c++/98043 * g++.dg/cpp0x/enum41.C: New test. --- gcc/cp/decl.c | 17 +++++++++++++---- gcc/testsuite/g++.dg/cpp0x/enum41.C | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum41.C (limited to 'gcc') diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a28e792..7da8c65 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3690,17 +3690,17 @@ void pop_switch (void) { struct cp_switch *cs = switch_stack; - location_t switch_location; /* Emit warnings as needed. */ - switch_location = cp_expr_loc_or_input_loc (cs->switch_stmt); + location_t switch_location = cp_expr_loc_or_input_loc (cs->switch_stmt); + tree cond = SWITCH_STMT_COND (cs->switch_stmt); const bool bool_cond_p = (SWITCH_STMT_TYPE (cs->switch_stmt) && TREE_CODE (SWITCH_STMT_TYPE (cs->switch_stmt)) == BOOLEAN_TYPE); if (!processing_template_decl) c_do_switch_warnings (cs->cases, switch_location, - SWITCH_STMT_TYPE (cs->switch_stmt), - SWITCH_STMT_COND (cs->switch_stmt), bool_cond_p); + SWITCH_STMT_TYPE (cs->switch_stmt), cond, + bool_cond_p); /* For the benefit of block_may_fallthru remember if the switch body case labels cover all possible values and if there are break; stmts. */ @@ -3711,6 +3711,15 @@ pop_switch (void) SWITCH_STMT_ALL_CASES_P (cs->switch_stmt) = 1; if (!cs->break_stmt_seen_p) SWITCH_STMT_NO_BREAK_P (cs->switch_stmt) = 1; + /* Now that we're done with the switch warnings, set the switch type + to the type of the condition if the index type was of scoped enum type. + (Such types don't participate in the integer promotions.) We do this + because of bit-fields whose declared type is a scoped enum type: + gimplification will use the lowered index type, but convert the + case values to SWITCH_STMT_TYPE, which would have been the declared type + and verify_gimple_switch doesn't accept that. */ + if (is_bitfield_expr_with_lowered_type (cond)) + SWITCH_STMT_TYPE (cs->switch_stmt) = TREE_TYPE (cond); gcc_assert (!cs->in_loop_body_p); splay_tree_delete (cs->cases); switch_stack = switch_stack->next; diff --git a/gcc/testsuite/g++.dg/cpp0x/enum41.C b/gcc/testsuite/g++.dg/cpp0x/enum41.C new file mode 100644 index 0000000..5f6ef13 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum41.C @@ -0,0 +1,32 @@ +// PR c++/98043 +// { dg-do compile { target c++11 } } + +enum class B { A }; +struct C { B c : 8; }; + +bool +foo (C x) +{ + switch (x.c) + { + case B::A: + return false; + default: + return true; + } +} + +enum E { X }; +struct D { E c : 7; }; + +bool +bar (D x) +{ + switch (x.c) + { + case E::X: + return false; + default: + return true; + } +} -- cgit v1.1 From c3a1b3e6fb24ccf6f45e7d6ce904d5549bba01d6 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 5 Dec 2020 18:42:30 -0800 Subject: compiler: type of string index expression is byte To make this work from the do_type method, add "byte" and "rune" to the list of known integer types, and look them up that way rather than via gogo->lookup_global. For golang/go#8745 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/275653 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 4 ++-- gcc/go/gofrontend/gogo.cc | 12 +++-------- gcc/go/gofrontend/statements.cc | 4 ++-- gcc/go/gofrontend/types.cc | 43 +++++++++++++++++++++++++++++++--------- gcc/go/gofrontend/types.h | 8 ++++++++ gcc/go/gofrontend/wb.cc | 5 +++-- 7 files changed, 53 insertions(+), 25 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 02083ed..711353d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -2184750d74d37580486e90df1284c07fdee91670 +81687fccc568a088fee8f627ddde599e17c648c2 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index ebe1b36..6d484d9 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -13468,7 +13468,7 @@ Type* String_index_expression::do_type() { if (this->end_ == NULL) - return Type::lookup_integer_type("uint8"); + return Type::lookup_integer_type("byte"); else return this->string_->type(); } @@ -14021,7 +14021,7 @@ Field_reference_expression::do_lower(Gogo* gogo, Named_object* function, Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc); - Type* byte_type = gogo->lookup_global("byte")->type_value(); + Type* byte_type = Type::lookup_integer_type("byte"); Array_type* array_type = Type::make_array_type(byte_type, length_expr); array_type->set_is_array_incomparable(); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index a5e4521..e31a038 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -117,17 +117,11 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size) // "byte" is an alias for "uint8". uint8_type->integer_type()->set_is_byte(); - Named_object* byte_type = Named_object::make_type("byte", NULL, uint8_type, - loc); - byte_type->type_value()->set_is_alias(); - this->add_named_type(byte_type->type_value()); + this->add_named_type(Type::make_integer_type_alias("byte", uint8_type)); // "rune" is an alias for "int32". int32_type->integer_type()->set_is_rune(); - Named_object* rune_type = Named_object::make_type("rune", NULL, int32_type, - loc); - rune_type->type_value()->set_is_alias(); - this->add_named_type(rune_type->type_value()); + this->add_named_type(Type::make_integer_type_alias("rune", int32_type)); this->add_named_type(Type::make_named_bool_type()); @@ -765,7 +759,7 @@ Gogo::register_gc_vars(const std::vector& var_gc, Type* pvt = Type::make_pointer_type(Type::make_void_type()); Type* uintptr_type = Type::lookup_integer_type("uintptr"); - Type* byte_type = this->lookup_global("byte")->type_value(); + Type* byte_type = Type::lookup_integer_type("byte"); Type* pointer_byte_type = Type::make_pointer_type(byte_type); Struct_type* root_type = Type::make_builtin_struct_type(4, diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 25e2536..af82f36 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -6341,7 +6341,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing, else if (range_type->is_string_type()) { index_type = Type::lookup_integer_type("int"); - value_type = gogo->lookup_global("rune")->type_value(); + value_type = Type::lookup_integer_type("rune"); } else if (range_type->map_type() != NULL) { @@ -6812,7 +6812,7 @@ For_range_statement::lower_range_string(Gogo* gogo, rune_type = value_temp->type(); else { - rune_type = gogo->lookup_global("rune")->type_value(); + rune_type = Type::lookup_integer_type("rune"); value_temp = Statement::make_temporary(rune_type, NULL, loc); init->add_statement(value_temp); } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 23d1647..d2741f6 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2764,7 +2764,7 @@ class Ptrmask symname() const; Expression* - constructor(Gogo* gogo) const; + constructor() const; private: void @@ -2959,10 +2959,10 @@ Ptrmask::symname() const // initialize the runtime ptrmask value. Expression* -Ptrmask::constructor(Gogo* gogo) const +Ptrmask::constructor() const { Location bloc = Linemap::predeclared_location(); - Type* byte_type = gogo->lookup_global("byte")->type_value(); + Type* byte_type = Type::lookup_integer_type("byte"); Expression* len = Expression::make_integer_ul(this->bits_.size(), NULL, bloc); Array_type* at = Type::make_array_type(byte_type, len); @@ -3007,7 +3007,7 @@ Type::gc_ptrmask_var(Gogo* gogo, int64_t ptrsize, int64_t ptrdata) return ins.first->second; } - Expression* val = ptrmask.constructor(gogo); + Expression* val = ptrmask.constructor(); Translate_context context(gogo, NULL, NULL, NULL); context.set_is_const(); Bexpression* bval = val->get_backend(&context); @@ -3046,7 +3046,7 @@ class GCProg end(); Expression* - constructor(Gogo* gogo) const; + constructor() const; private: void @@ -3357,7 +3357,7 @@ GCProg::end() // Return an Expression for the bytes in a GC program. Expression* -GCProg::constructor(Gogo* gogo) const +GCProg::constructor() const { Location bloc = Linemap::predeclared_location(); @@ -3367,7 +3367,7 @@ GCProg::constructor(Gogo* gogo) const Type* uint32_type = Type::lookup_integer_type("uint32"); - Type* byte_type = gogo->lookup_global("byte")->type_value(); + Type* byte_type = Type::lookup_integer_type("byte"); Expression* len = Expression::make_integer_ul(this->bytes_.size(), NULL, bloc); Array_type* at = Type::make_array_type(byte_type, len); @@ -3414,7 +3414,7 @@ Type::gcprog_constructor(Gogo* gogo, int64_t ptrsize, int64_t ptrdata) go_assert(offset >= ptrdata && offset <= type_size); - return prog.constructor(gogo); + return prog.constructor(); } // Return a composite literal for the uncommon type information for @@ -4141,6 +4141,23 @@ Integer_type::create_abstract_character_type() return abstract_type; } +// Create an alias to an integer type. This is used for byte and rune. + +Named_type* +Integer_type::create_integer_type_alias(const char* name, + Named_type* real_type) +{ + std::string sname(name); + Named_object* no = Named_object::make_type(sname, NULL, real_type, + Linemap::predeclared_location()); + Named_type* nt = no->type_value(); + nt->set_is_alias(); + std::pair ins = + Integer_type::named_integer_types.insert(std::make_pair(sname, nt)); + go_assert(ins.second); + return nt; +} + // Integer type compatibility. bool @@ -4218,6 +4235,14 @@ Type::make_abstract_character_type() return Integer_type::create_abstract_character_type(); } +// Make an integer type alias. + +Named_type* +Type::make_integer_type_alias(const char* name, Named_type* real_type) +{ + return Integer_type::create_integer_type_alias(name, real_type); +} + // Look up an integer type. Named_type* @@ -4466,7 +4491,7 @@ String_type::do_get_backend(Gogo* gogo) { std::vector fields(2); - Type* b = gogo->lookup_global("byte")->type_value(); + Type* b = Type::lookup_integer_type("byte"); Type* pb = Type::make_pointer_type(b); // We aren't going to get back to this field to finish the diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index d097029..b7dd391 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -462,6 +462,10 @@ class Type make_integer_type(const char* name, bool is_unsigned, int bits, int runtime_type_kind); + // Make a named integer type alias. This is used for byte and rune. + static Named_type* + make_integer_type_alias(const char* name, Named_type* real_type); + // Look up a named integer type. static Named_type* lookup_integer_type(const char* name); @@ -1743,6 +1747,10 @@ class Integer_type : public Type static Integer_type* create_abstract_character_type(); + // Create an alias to an integer type. + static Named_type* + create_integer_type_alias(const char* name, Named_type* real_type); + // Whether this is an abstract integer type. bool is_abstract() const diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc index 1eadb3e..ac1f0a1 100644 --- a/gcc/go/gofrontend/wb.cc +++ b/gcc/go/gofrontend/wb.cc @@ -683,8 +683,9 @@ Gogo::write_barrier_variable() Location bloc = Linemap::predeclared_location(); Type* bool_type = Type::lookup_bool_type(); - Array_type* pad_type = Type::make_array_type(this->lookup_global("byte")->type_value(), - Expression::make_integer_ul(3, NULL, bloc)); + Array_type* pad_type = + Type::make_array_type(Type::lookup_integer_type("byte"), + Expression::make_integer_ul(3, NULL, bloc)); Type* uint64_type = Type::lookup_integer_type("uint64"); Type* wb_type = Type::make_builtin_struct_type(5, "enabled", bool_type, -- cgit v1.1 From b737b70fad398728f6006e8397d1bb31ccea4ce7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 7 Dec 2020 19:20:25 +0100 Subject: builtins: Avoid ICE with __builtin_clear_padding on POINTERS_EXTEND_UNSIGNED targets [PR98147] The function that calls targetm.emit_call_builtin___clear_cache asserts that each of the begin and end operands has either ptr_mode or Pmode. On most targets that is the same mode, but e.g. on aarch64 -mabi=ilp32 or a few others it is different. When a target has a clear cache non-library handler, it will use create_address_operand which will do the conversion to the right mode automatically, but when emitting a library call, we just say the operands are ptr_mode even when they can be Pmode too; in that case we need to convert explicitly. 2020-12-07 Jakub Jelinek PR target/98147 * builtins.c (default_emit_call_builtin___clear_cache): Call convert_memory_address to ptr_mode on both begin and end. * gcc.dg/pr98147.c: New test. --- gcc/builtins.c | 4 ++-- gcc/testsuite/gcc.dg/pr98147.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr98147.c (limited to 'gcc') diff --git a/gcc/builtins.c b/gcc/builtins.c index bd12659..faa5030 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7790,8 +7790,8 @@ default_emit_call_builtin___clear_cache (rtx begin, rtx end) emit_library_call (callee, LCT_NORMAL, VOIDmode, - begin, ptr_mode, - end, ptr_mode); + convert_memory_address (ptr_mode, begin), ptr_mode, + convert_memory_address (ptr_mode, end), ptr_mode); } /* Emit a call to __builtin___clear_cache, unless the target specifies diff --git a/gcc/testsuite/gcc.dg/pr98147.c b/gcc/testsuite/gcc.dg/pr98147.c new file mode 100644 index 0000000..3edc798 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98147.c @@ -0,0 +1,10 @@ +/* PR target/98147 */ + +char buffer[32] = "foo bar"; + +int +main () +{ + __builtin___clear_cache (buffer, buffer + 32); + return 0; +} -- cgit v1.1