diff options
-rw-r--r-- | gcc/c-family/c-attribs.cc | 30 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 6 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 7 | ||||
-rw-r--r-- | gcc/cfghooks.cc | 2 | ||||
-rw-r--r-- | gcc/config/riscv/predicates.md | 11 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.md | 39 | ||||
-rw-r--r-- | gcc/diagnostics/output-spec.cc | 585 | ||||
-rw-r--r-- | gcc/diagnostics/output-spec.h | 88 | ||||
-rw-r--r-- | gcc/libgdiagnostics.cc | 3 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2GCCDeclare.mod | 13 | ||||
-rw-r--r-- | gcc/m2/gm2-gcc/m2type.cc | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-gcc/m2type.def | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-gcc/m2type.h | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-libs/M2WIDESET.mod | 116 | ||||
-rw-r--r-- | gcc/opts-diagnostic.cc | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/start_unit_plugin.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/mv-error11.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/mv-error12.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr122051.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-nearbyint-1.c | 4 | ||||
-rw-r--r-- | gcc/tree-vect-loop.cc | 12 |
21 files changed, 610 insertions, 369 deletions
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index df9ff99..5bc5183 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -249,6 +249,29 @@ static const struct attribute_spec::exclusions attr_target_clones_exclusions[] = ATTR_EXCL ("always_inline", true, true, true), ATTR_EXCL ("target", TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE), + ATTR_EXCL ("omp declare simd", true, true, true), + ATTR_EXCL ("simd", true, true, true), + ATTR_EXCL (NULL, false, false, false), +}; + +static const struct attribute_spec::exclusions attr_target_version_exclusions[] = +{ + ATTR_EXCL ("omp declare simd", true, true, true), + ATTR_EXCL ("simd", true, true, true), + ATTR_EXCL (NULL, false, false, false), +}; + +static const struct attribute_spec::exclusions attr_omp_declare_simd_exclusions[] = +{ + ATTR_EXCL ("target_version", true, true, true), + ATTR_EXCL ("target_clones", true, true, true), + ATTR_EXCL (NULL, false, false, false), +}; + +static const struct attribute_spec::exclusions attr_simd_exclusions[] = +{ + ATTR_EXCL ("target_version", true, true, true), + ATTR_EXCL ("target_clones", true, true, true), ATTR_EXCL (NULL, false, false, false), }; @@ -536,7 +559,7 @@ const struct attribute_spec c_common_gnu_attributes[] = attr_target_exclusions }, { "target_version", 1, 1, true, false, false, false, handle_target_version_attribute, - NULL }, + attr_target_version_exclusions}, { "target_clones", 1, -1, true, false, false, false, handle_target_clones_attribute, attr_target_clones_exclusions }, @@ -563,7 +586,8 @@ const struct attribute_spec c_common_gnu_attributes[] = { "returns_nonnull", 0, 0, false, true, true, false, handle_returns_nonnull_attribute, NULL }, { "omp declare simd", 0, -1, true, false, false, false, - handle_omp_declare_simd_attribute, NULL }, + handle_omp_declare_simd_attribute, + attr_omp_declare_simd_exclusions }, { "omp declare variant base", 0, -1, true, false, false, false, handle_omp_declare_variant_attribute, NULL }, { "omp declare variant variant", 0, -1, true, false, false, false, @@ -572,7 +596,7 @@ const struct attribute_spec c_common_gnu_attributes[] = false, false, handle_omp_declare_variant_attribute, NULL }, { "simd", 0, 1, true, false, false, false, - handle_simd_attribute, NULL }, + handle_simd_attribute, attr_simd_exclusions }, { "omp declare target", 0, -1, true, false, false, false, handle_omp_declare_target_attribute, NULL }, { "omp declare target link", 0, 0, true, false, false, false, diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 8254875..632bbf0 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -2094,6 +2094,12 @@ maybe_mark_function_versioned (tree decl) { if (!DECL_FUNCTION_VERSIONED (decl)) { + /* Check if the name of the function has been overridden. */ + if (DECL_ASSEMBLER_NAME_SET_P (decl) + && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))[0] == '*') + error_at (DECL_SOURCE_LOCATION (decl), + "cannot use function multiversioning on a renamed function"); + /* We need to insert function version now to make sure the correct pre-mangled assembler name is recorded. */ cgraph_node *node = cgraph_node::get_create (decl); diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index df44a91..7c24526 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -27776,6 +27776,13 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, clauses[0].type = CPP_EOF; return; } + if (DECL_FUNCTION_VERSIONED (fndecl)) + { + error_at (DECL_SOURCE_LOCATION (fndecl), + "%<#pragma omp declare %s%> cannot be used with function " + "multi-versioning", kind); + return; + } if (parms == NULL_TREE) parms = DECL_ARGUMENTS (fndecl); diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc index 8b33468..25bc5d4 100644 --- a/gcc/cfghooks.cc +++ b/gcc/cfghooks.cc @@ -819,7 +819,7 @@ merge_blocks (basic_block a, basic_block b) /* Pick the more reliable count. If both qualities agrees, pick the larger one since turning mistakely hot code to cold is more harmful. */ - if (a->count.initialized_p ()) + if (!a->count.initialized_p ()) a->count = b->count; else if (a->count.quality () < b->count.quality ()) a->count = b->count; diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 777e71b..056f9e2 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -607,13 +607,12 @@ (define_predicate "ge_operator" (match_code "ge,geu")) -;; pmode_reg_or_uimm5_operand can be used by vsll.vx/vsrl.vx/vsra.vx instructions. -;; Since it has the same predicate with vector_length_operand which allows register -;; or immediate (0 ~ 31), we define this predicate same as vector_length_operand here. -;; We don't use vector_length_operand directly to predicate vsll.vx/vsrl.vx/vsra.vx -;; since it may be confusing. +;; pmode_reg_or_uimm5_operand can be used by vsll.vx/vsrl.vx/vsra.vx instructions +;; It is *not* equivalent to vector_length_operand due to the vector_length_operand +;; needing to conditionalize some behavior on XTHEADVECTOR. (define_special_predicate "pmode_reg_or_uimm5_operand" - (match_operand 0 "vector_length_operand")) + (ior (match_operand 0 "pmode_register_operand") + (match_operand 0 "const_csr_operand"))) (define_special_predicate "pmode_reg_or_0_operand" (ior (match_operand 0 "const_0_operand") diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 843a048..78a01ef 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2322,27 +2322,38 @@ else { rtx reg; - rtx label = gen_label_rtx (); + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx label3 = gen_label_rtx (); rtx end_label = gen_label_rtx (); rtx abs_reg = gen_reg_rtx (<ANYF:MODE>mode); rtx coeff_reg = gen_reg_rtx (<ANYF:MODE>mode); rtx tmp_reg = gen_reg_rtx (<ANYF:MODE>mode); - rtx fflags = gen_reg_rtx (SImode); riscv_emit_move (tmp_reg, operands[1]); + + if (flag_trapping_math) + { + /* Check if the input is a NaN. */ + riscv_expand_conditional_branch (label1, EQ, + operands[1], operands[1]); + + emit_jump_insn (gen_jump (label3)); + emit_barrier (); + + emit_label (label1); + } + riscv_emit_move (coeff_reg, riscv_vector::get_fp_rounding_coefficient (<ANYF:MODE>mode)); emit_insn (gen_abs<ANYF:mode>2 (abs_reg, operands[1])); - /* fp compare can set invalid flag for NaN, so backup fflags. */ - if (flag_trapping_math) - emit_insn (gen_riscv_frflags (fflags)); - riscv_expand_conditional_branch (label, LT, abs_reg, coeff_reg); + riscv_expand_conditional_branch (label2, LT, abs_reg, coeff_reg); emit_jump_insn (gen_jump (end_label)); emit_barrier (); - emit_label (label); + emit_label (label2); switch (<ANYF:MODE>mode) { case SFmode: @@ -2361,15 +2372,17 @@ emit_insn (gen_copysign<ANYF:mode>3 (tmp_reg, abs_reg, operands[1])); - emit_label (end_label); + emit_jump_insn (gen_jump (end_label)); + emit_barrier (); - /* Restore fflags, but after label. This is slightly different - than glibc implementation which only needs to restore under - the label, since it checks for NaN first, meaning following fp - compare can't raise fp exceptons and thus not clobber fflags. */ if (flag_trapping_math) - emit_insn (gen_riscv_fsflags (fflags)); + { + emit_label (label3); + /* Generate a qNaN from an sNaN if needed. */ + emit_insn (gen_add<ANYF:mode>3 (tmp_reg, operands[1], operands[1])); + } + emit_label (end_label); riscv_emit_move (operands[0], tmp_reg); } diff --git a/gcc/diagnostics/output-spec.cc b/gcc/diagnostics/output-spec.cc index 28ea044f..dfde7f0 100644 --- a/gcc/diagnostics/output-spec.cc +++ b/gcc/diagnostics/output-spec.cc @@ -73,171 +73,160 @@ struct scheme_name_and_params class output_factory { public: - output_factory (); + output_factory (diagnostics::context &dc); std::unique_ptr<sink> make_sink (const context &ctxt, diagnostics::context &dc, const scheme_name_and_params &scheme_and_kvs); - const scheme_handler *get_scheme_handler (const std::string &scheme_name); + scheme_handler *get_scheme_handler (const std::string &scheme_name); private: std::vector<std::unique_ptr<scheme_handler>> m_scheme_handlers; }; -class scheme_handler +enum key_handler::result +key_handler::parse_bool_value (const context &ctxt, + const std::string &key, + const std::string &value, + bool &out) const { -public: - scheme_handler (std::string scheme_name) - : m_scheme_name (std::move (scheme_name)) - {} - virtual ~scheme_handler () {} - - const std::string &get_scheme_name () const { return m_scheme_name; } - - virtual std::unique_ptr<sink> - make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const = 0; + if (value == "yes") + { + out = true; + return result::ok; + } + else if (value == "no") + { + out = false; + return result::ok; + } + else + { + ctxt.report_error + ("%<%s%s%>:" + " unexpected value %qs for key %qs; expected %qs or %qs", + ctxt.get_option_name (), ctxt.get_unparsed_spec (), + value.c_str (), + key.c_str (), + "yes", "no"); + return result::malformed_value; + } +} -protected: - bool - parse_bool_value (const context &ctxt, - const std::string &key, - const std::string &value, - bool &out) const - { - if (value == "yes") - { - out = true; - return true; - } - else if (value == "no") - { - out = false; - return true; - } - else +template <typename EnumType, size_t NumValues> +key_handler::result +key_handler::parse_enum_value (const context &ctxt, + const std::string &key, + const std::string &value, + const std::array<std::pair<const char *, + EnumType>, + NumValues> &value_names, + EnumType &out) const +{ + for (auto &iter : value_names) + if (value == iter.first) { - ctxt.report_error - ("%<%s%s%>:" - " unexpected value %qs for key %qs; expected %qs or %qs", - ctxt.get_option_name (), ctxt.get_unparsed_spec (), - value.c_str (), - key.c_str (), - "yes", "no"); - - return false; + out = iter.second; + return result::ok; } - } - template <typename EnumType, size_t NumValues> - bool - parse_enum_value (const context &ctxt, - const std::string &key, - const std::string &value, - const std::array<std::pair<const char *, EnumType>, NumValues> &value_names, - EnumType &out) const - { - for (auto &iter : value_names) - if (value == iter.first) - { - out = iter.second; - return true; - } - - auto_vec<const char *> known_values; - for (auto iter : value_names) - known_values.safe_push (iter.first); - pp_markup::comma_separated_quoted_strings e (known_values); - ctxt.report_error - ("%<%s%s%>:" - " unexpected value %qs for key %qs; known values: %e", - ctxt.get_option_name (), ctxt.get_unparsed_spec (), - value.c_str (), - key.c_str (), - &e); - return false; - } -private: - const std::string m_scheme_name; -}; + auto_vec<const char *> known_values; + for (auto iter : value_names) + known_values.safe_push (iter.first); + pp_markup::comma_separated_quoted_strings e (known_values); + ctxt.report_error + ("%<%s%s%>:" + " unexpected value %qs for key %qs; known values: %e", + ctxt.get_option_name (), ctxt.get_unparsed_spec (), + value.c_str (), + key.c_str (), + &e); + return result::malformed_value; +} class text_scheme_handler : public scheme_handler { public: - struct decoded_args + text_scheme_handler (diagnostics::context &dc) + : scheme_handler ("text"), + m_show_color (pp_show_color (dc.get_reference_printer ())), + m_show_nesting (true), + m_show_locations_in_nesting (true), + m_show_levels (false) { - bool m_show_color; - bool m_show_nesting; - bool m_show_locations_in_nesting; - bool m_show_levels; - }; - - text_scheme_handler () : scheme_handler ("text") {} + } std::unique_ptr<sink> make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const final override; + diagnostics::context &dc) final override; + + enum result + maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) final override; + + void + get_keys (auto_vec<const char *> &out) const final override; - bool - decode_kv (const context &ctxt, - const std::string &key, - const std::string &value, - decoded_args &out_opts) const; +private: + bool m_show_color; + bool m_show_nesting; + bool m_show_locations_in_nesting; + bool m_show_levels; }; class sarif_scheme_handler : public scheme_handler { public: - struct decoded_args + sarif_scheme_handler () + : scheme_handler ("sarif"), + m_serialization_kind (sarif_serialization_kind::json) { - label_text m_filename; - enum sarif_serialization_kind m_serialization_kind; - sarif_generation_options m_generation_opts; - }; - - sarif_scheme_handler () : scheme_handler ("sarif") {} + } std::unique_ptr<sink> make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const final override; + diagnostics::context &dc) final override; - bool - decode_kv (const context &ctxt, - const std::string &key, - const std::string &value, - decoded_args &out_opts) const; + enum result + maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) final override; + + void + get_keys (auto_vec<const char *> &out) const final override; private: static std::unique_ptr<sarif_serialization_format> make_sarif_serialization_object (enum sarif_serialization_kind); + + label_text m_filename; + enum sarif_serialization_kind m_serialization_kind; + sarif_generation_options m_generation_opts; }; class html_scheme_handler : public scheme_handler { public: - struct decoded_args - { - label_text m_filename; - html_generation_options m_html_gen_opts; - }; - html_scheme_handler () : scheme_handler ("experimental-html") {} std::unique_ptr<sink> make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const final override; + diagnostics::context &dc) final override; + + enum result + maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) final override; - bool - decode_kv (const context &ctxt, - const std::string &key, - const std::string &value, - decoded_args &opts_out) const; + void + get_keys (auto_vec<const char *> &out) const final override; + +private: + label_text m_filename; + html_generation_options m_html_gen_opts; }; /* struct context. */ @@ -253,15 +242,38 @@ context::report_error (const char *gmsgid, ...) const void context::report_unknown_key (const std::string &key, - const std::string &scheme_name, - auto_vec<const char *> &known_keys) const + const scheme_handler &scheme) const { - pp_markup::comma_separated_quoted_strings e (known_keys); + auto_vec<const char *> scheme_key_vec; + scheme.get_keys (scheme_key_vec); + + pp_markup::comma_separated_quoted_strings e_scheme_keys (scheme_key_vec); + + const char *scheme_name = scheme.get_scheme_name ().c_str (); + + if (m_client_keys) + { + auto_vec<const char *> client_key_vec; + m_client_keys->get_keys (client_key_vec); + if (!client_key_vec.is_empty ()) + { + pp_markup::comma_separated_quoted_strings e_client_keys + (client_key_vec); + report_error + ("%<%s%s%>:" + " unknown key %qs for output scheme %qs;" + " scheme keys: %e; client keys: %e", + get_option_name (), get_unparsed_spec (), + key.c_str (), scheme_name, + &e_scheme_keys, &e_client_keys); + } + } + report_error ("%<%s%s%>:" - " unknown key %qs for format %qs; known keys: %e", + " unknown key %qs for output scheme %qs; scheme keys: %e", get_option_name (), get_unparsed_spec (), - key.c_str (), scheme_name.c_str (), &e); + key.c_str (), scheme_name, &e_scheme_keys); } void @@ -348,7 +360,7 @@ context::parse_and_make_sink (diagnostics::context &dc) if (!parsed_arg) return nullptr; - output_factory factory; + output_factory factory (dc); return factory.make_sink (*this, dc, *parsed_arg); } @@ -356,14 +368,14 @@ context::parse_and_make_sink (diagnostics::context &dc) /* class output_factory. */ -output_factory::output_factory () +output_factory::output_factory (diagnostics::context &dc) { - m_scheme_handlers.push_back (std::make_unique<text_scheme_handler> ()); + m_scheme_handlers.push_back (std::make_unique<text_scheme_handler> (dc)); m_scheme_handlers.push_back (std::make_unique<sarif_scheme_handler> ()); m_scheme_handlers.push_back (std::make_unique<html_scheme_handler> ()); } -const scheme_handler * +scheme_handler * output_factory::get_scheme_handler (const std::string &scheme_name) { for (auto &iter : m_scheme_handlers) @@ -391,61 +403,91 @@ output_factory::make_sink (const context &ctxt, return nullptr; } - return scheme_handler->make_sink (ctxt, dc, scheme_and_kvs); -} - -/* class text_scheme_handler : public scheme_handler. */ - -std::unique_ptr<sink> -text_scheme_handler::make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const -{ - decoded_args opts; - opts.m_show_color = pp_show_color (dc.get_reference_printer ()); - opts.m_show_nesting = true; - opts.m_show_locations_in_nesting = true; - opts.m_show_levels = false; + /* Parse key/value pairs. */ for (auto& iter : scheme_and_kvs.m_kvs) { const std::string &key = iter.first; const std::string &value = iter.second; - if (!decode_kv (ctxt, key, value, opts)) + if (!ctxt.handle_kv (key, value, *scheme_handler)) return nullptr; } + return scheme_handler->make_sink (ctxt, dc); +} + +bool +context::handle_kv (const std::string &key, + const std::string &value, + scheme_handler &scheme) const +{ + auto result = scheme.maybe_handle_kv (*this, key, value); + switch (result) + { + default: gcc_unreachable (); + case key_handler::result::ok: + return true; + case key_handler::result::malformed_value: + return false; + case key_handler::result::unrecognized: + /* Key recognized by the scheme; try the client keys. */ + if (m_client_keys) + { + result = m_client_keys->maybe_handle_kv (*this, key, value); + switch (result) + { + default: gcc_unreachable (); + case key_handler::result::ok: + return true; + case key_handler::result::malformed_value: + return false; + case key_handler::result::unrecognized: + break; + } + } + report_unknown_key (key, scheme); + return false; + } +} + +/* class text_scheme_handler : public scheme_handler. */ + +std::unique_ptr<sink> +text_scheme_handler::make_sink (const context &, + diagnostics::context &dc) +{ auto sink = std::make_unique<diagnostics::text_sink> (dc); - sink->set_show_nesting (opts.m_show_nesting); - sink->set_show_locations_in_nesting (opts.m_show_locations_in_nesting); - sink->set_show_nesting_levels (opts.m_show_levels); - pp_show_color (sink->get_printer ()) = opts.m_show_color; + sink->set_show_nesting (m_show_nesting); + sink->set_show_locations_in_nesting (m_show_locations_in_nesting); + sink->set_show_nesting_levels (m_show_levels); + pp_show_color (sink->get_printer ()) = m_show_color; return sink; } -bool -text_scheme_handler::decode_kv (const context &ctxt, - const std::string &key, - const std::string &value, - decoded_args &opts_out) const +enum key_handler::result +text_scheme_handler::maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) { if (key == "color") - return parse_bool_value (ctxt, key, value, opts_out.m_show_color); + return parse_bool_value (ctxt, key, value, m_show_color); if (key == "show-nesting") - return parse_bool_value (ctxt, key, value, opts_out.m_show_nesting); + return parse_bool_value (ctxt, key, value, m_show_nesting); if (key == "show-nesting-locations") return parse_bool_value (ctxt, key, value, - opts_out.m_show_locations_in_nesting); + m_show_locations_in_nesting); if (key == "show-nesting-levels") - return parse_bool_value (ctxt, key, value, opts_out.m_show_levels); - - /* Key not found. */ - auto_vec<const char *> known_keys; - known_keys.safe_push ("color"); - known_keys.safe_push ("show-nesting"); - known_keys.safe_push ("show-nesting-locations"); - known_keys.safe_push ("show-nesting-levels"); - ctxt.report_unknown_key (key, get_scheme_name (), known_keys); - return false; + return parse_bool_value (ctxt, key, value, m_show_levels); + + return result::unrecognized; +} + +void +text_scheme_handler::get_keys (auto_vec<const char *> &out) const +{ + out.safe_push ("color"); + out.safe_push ("show-nesting"); + out.safe_push ("show-nesting-locations"); + out.safe_push ("show-nesting-levels"); } /* class sarif_scheme_handler : public scheme_handler. */ @@ -453,23 +495,11 @@ text_scheme_handler::decode_kv (const context &ctxt, std::unique_ptr<sink> sarif_scheme_handler:: make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const + diagnostics::context &dc) { - decoded_args opts; - opts.m_serialization_kind = sarif_serialization_kind::json; - - for (auto& iter : scheme_and_kvs.m_kvs) - { - const std::string &key = iter.first; - const std::string &value = iter.second; - if (!decode_kv (ctxt, key, value, opts)) - return nullptr; - } - output_file output_file_; - if (opts.m_filename.get ()) - output_file_ = ctxt.open_output_file (std::move (opts.m_filename)); + if (m_filename.get ()) + output_file_ = ctxt.open_output_file (std::move (m_filename)); else // Default filename { @@ -485,33 +515,32 @@ make_sink (const context &ctxt, = open_sarif_output_file (dc, ctxt.get_affected_location_mgr (), basename, - opts.m_serialization_kind); + m_serialization_kind); } if (!output_file_) return nullptr; auto serialization_obj - = make_sarif_serialization_object (opts.m_serialization_kind); + = make_sarif_serialization_object (m_serialization_kind); auto sink = make_sarif_sink (dc, *ctxt.get_affected_location_mgr (), std::move (serialization_obj), - opts.m_generation_opts, + m_generation_opts, std::move (output_file_)); return sink; } -bool -sarif_scheme_handler::decode_kv (const context &ctxt, - const std::string &key, - const std::string &value, - decoded_args &opts_out) const +enum key_handler::result +sarif_scheme_handler::maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) { if (key == "file") { - opts_out.m_filename = label_text::take (xstrdup (value.c_str ())); - return true; + m_filename = label_text::take (xstrdup (value.c_str ())); + return result::ok; } if (key == "serialization") { @@ -522,7 +551,7 @@ sarif_scheme_handler::decode_kv (const context &ctxt, (ctxt, key, value, value_names, - opts_out.m_serialization_kind); + m_serialization_kind); } if (key == "version") { @@ -534,20 +563,22 @@ sarif_scheme_handler::decode_kv (const context &ctxt, (ctxt, key, value, value_names, - opts_out.m_generation_opts.m_version); + m_generation_opts.m_version); } if (key == "state-graphs") return parse_bool_value (ctxt, key, value, - opts_out.m_generation_opts.m_state_graph); - - /* Key not found. */ - auto_vec<const char *> known_keys; - known_keys.safe_push ("file"); - known_keys.safe_push ("serialization"); - known_keys.safe_push ("state-graphs"); - known_keys.safe_push ("version"); - ctxt.report_unknown_key (key, get_scheme_name (), known_keys); - return false; + m_generation_opts.m_state_graph); + + return result::unrecognized; +} + +void +sarif_scheme_handler::get_keys (auto_vec<const char *> &out) const +{ + out.safe_push ("file"); + out.safe_push ("serialization"); + out.safe_push ("state-graphs"); + out.safe_push ("version"); } std::unique_ptr<sarif_serialization_format> @@ -569,21 +600,11 @@ make_sarif_serialization_object (enum sarif_serialization_kind kind) std::unique_ptr<sink> html_scheme_handler:: make_sink (const context &ctxt, - diagnostics::context &dc, - const scheme_name_and_params &scheme_and_kvs) const + diagnostics::context &dc) { - decoded_args opts; - for (auto& iter : scheme_and_kvs.m_kvs) - { - const std::string &key = iter.first; - const std::string &value = iter.second; - if (!decode_kv (ctxt, key, value, opts)) - return nullptr; - } - output_file output_file_; - if (opts.m_filename.get ()) - output_file_ = ctxt.open_output_file (std::move (opts.m_filename)); + if (m_filename.get ()) + output_file_ = ctxt.open_output_file (std::move (m_filename)); else // Default filename { @@ -606,49 +627,47 @@ make_sink (const context &ctxt, auto sink = make_html_sink (dc, *ctxt.get_affected_location_mgr (), - opts.m_html_gen_opts, + m_html_gen_opts, std::move (output_file_)); return sink; } -bool -html_scheme_handler::decode_kv (const context &ctxt, - const std::string &key, - const std::string &value, - decoded_args &opts_out) const +enum key_handler::result +html_scheme_handler::maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) { if (key == "css") - return parse_bool_value (ctxt, key, value, opts_out.m_html_gen_opts.m_css); + return parse_bool_value (ctxt, key, value, m_html_gen_opts.m_css); if (key == "file") { - opts_out.m_filename = label_text::take (xstrdup (value.c_str ())); - return true; + m_filename = label_text::take (xstrdup (value.c_str ())); + return result::ok; } if (key == "javascript") return parse_bool_value (ctxt, key, value, - opts_out.m_html_gen_opts.m_javascript); + m_html_gen_opts.m_javascript); if (key == "show-state-diagrams") return parse_bool_value (ctxt, key, value, - opts_out.m_html_gen_opts.m_show_state_diagrams); + m_html_gen_opts.m_show_state_diagrams); if (key == "show-state-diagrams-dot-src") - return parse_bool_value - (ctxt, key, value, - opts_out.m_html_gen_opts.m_show_state_diagrams_dot_src); + return parse_bool_value (ctxt, key, value, + m_html_gen_opts.m_show_state_diagrams_dot_src); if (key == "show-state-diagrams-sarif") - return parse_bool_value - (ctxt, key, value, - opts_out.m_html_gen_opts.m_show_state_diagrams_sarif); - - /* Key not found. */ - auto_vec<const char *> known_keys; - known_keys.safe_push ("css"); - known_keys.safe_push ("file"); - known_keys.safe_push ("javascript"); - known_keys.safe_push ("show-state-diagrams"); - known_keys.safe_push ("show-state-diagram-dot-src"); - known_keys.safe_push ("show-state-diagram-sarif"); - ctxt.report_unknown_key (key, get_scheme_name (), known_keys); - return false; + return parse_bool_value (ctxt, key, value, + m_html_gen_opts.m_show_state_diagrams_sarif); + return result::unrecognized; +} + +void +html_scheme_handler::get_keys (auto_vec<const char *> &out) const +{ + out.safe_push ("css"); + out.safe_push ("file"); + out.safe_push ("javascript"); + out.safe_push ("show-state-diagrams"); + out.safe_push ("show-state-diagrams-dot-src"); + out.safe_push ("show-state-diagrams-sarif"); } } // namespace output_spec @@ -685,17 +704,19 @@ struct parser_test class test_spec_context : public diagnostics::output_spec::dc_spec_context { public: - test_spec_context (diagnostics::context &dc, + test_spec_context (const char *option_name, + const char *unparsed_spec, + diagnostics::output_spec::key_handler *client_keys, line_maps *location_mgr, - location_t loc, - const char *option_name, - const char *unparsed_arg) - : dc_spec_context (dc, + diagnostics::context &dc, + location_t loc) + : dc_spec_context (option_name, + unparsed_spec, + client_keys, location_mgr, + dc, location_mgr, - loc, - option_name, - unparsed_arg) + loc) { } @@ -706,9 +727,15 @@ struct parser_test } }; - parser_test (const char *unparsed_spec) + parser_test (const char *unparsed_spec, + diagnostics::output_spec::key_handler *client_keys = nullptr) : m_dc (), - m_ctxt (m_dc, line_table, UNKNOWN_LOCATION, "-fOPTION=", unparsed_spec), + m_ctxt ("-fOPTION=", + unparsed_spec, + client_keys, + line_table, + m_dc, + UNKNOWN_LOCATION), m_fmt (m_dc.get_sink (0)) { pp_buffer (m_fmt.get_printer ())->m_flush_p = false; @@ -720,6 +747,12 @@ struct parser_test return diagnostics::output_spec::parse (m_ctxt); } + std::unique_ptr<diagnostics::sink> + parse_and_make_sink () + { + return m_ctxt.parse_and_make_sink (m_dc); + } + bool execution_failed_p () const { return m_dc.execution_failed_p (); @@ -742,9 +775,6 @@ private: static void test_output_arg_parsing () { - auto_fix_quotes fix_quotes; - auto_fix_progname fix_progname; - /* Minimal correct example. */ { parser_test pt ("foo"); @@ -831,12 +861,59 @@ test_output_arg_parsing () } } +class test_key_handler : public diagnostics::output_spec::key_handler +{ +public: + test_key_handler () + : m_verbose (false), + m_strict (false) + { + } + + enum result + maybe_handle_kv (const diagnostics::output_spec::context &ctxt, + const std::string &key, + const std::string &value) final override + { + if (key == "verbose") + return parse_bool_value (ctxt, key, value, m_verbose); + if (key == "strict") + return parse_bool_value (ctxt, key, value, m_strict); + return result::unrecognized; + } + + void + get_keys (auto_vec<const char *> &out_known_keys) const final override + { + out_known_keys.safe_push ("verbose"); + out_known_keys.safe_push ("strict"); + } + + bool m_verbose; + bool m_strict; +}; + +static void +test_client_arg_parsing () +{ + test_key_handler client_keys; + parser_test pt ("text:verbose=yes,strict=no", &client_keys); + auto result = pt.parse_and_make_sink (); + ASSERT_TRUE (result.get ()); + ASSERT_TRUE (client_keys.m_verbose); + ASSERT_FALSE (client_keys.m_strict); +} + /* Run all of the selftests within this file. */ void output_spec_cc_tests () { + auto_fix_quotes fix_quotes; + auto_fix_progname fix_progname; + test_output_arg_parsing (); + test_client_arg_parsing (); } } // namespace diagnostics::selftest diff --git a/gcc/diagnostics/output-spec.h b/gcc/diagnostics/output-spec.h index e24002b..bfc42c0 100644 --- a/gcc/diagnostics/output-spec.h +++ b/gcc/diagnostics/output-spec.h @@ -27,12 +27,71 @@ along with GCC; see the file COPYING3. If not see namespace diagnostics { namespace output_spec { +class context; + +/* An abstract base class for schemes, and for client-specific keys. */ + +class key_handler +{ +public: + enum class result + { + ok, + unrecognized, + malformed_value + }; + + /* Attempt to decode KEY and VALUE, storing the decoded value. */ + virtual enum result + maybe_handle_kv (const context &ctxt, + const std::string &key, + const std::string &value) = 0; + + virtual void + get_keys (auto_vec<const char *> &out) const = 0; + + enum result + parse_bool_value (const context &ctxt, + const std::string &key, + const std::string &value, + bool &out) const; + + template <typename EnumType, size_t NumValues> + enum result + parse_enum_value (const context &ctxt, + const std::string &key, + const std::string &value, + const std::array<std::pair<const char *, EnumType>, + NumValues> &value_names, + EnumType &out) const; +}; + +/* Abstract subclass for handling particular schemes and their keys. */ + +class scheme_handler : public key_handler +{ +public: + scheme_handler (std::string scheme_name) + : m_scheme_name (std::move (scheme_name)) + {} + virtual ~scheme_handler () {} + + const std::string &get_scheme_name () const { return m_scheme_name; } + + virtual std::unique_ptr<sink> + make_sink (const context &ctxt, + diagnostics::context &dc) = 0; + +private: + const std::string m_scheme_name; +}; + /* An abstract base class for handling the DSL of -fdiagnostics-add-output= and -fdiagnostics-set-output=. */ class context { - public: +public: std::unique_ptr<sink> parse_and_make_sink (diagnostics::context &dc); @@ -42,8 +101,7 @@ class context void report_unknown_key (const std::string &key, - const std::string &scheme_name, - auto_vec<const char *> &known_keys) const; + const scheme_handler &scheme) const; void report_missing_key (const std::string &key, @@ -70,12 +128,19 @@ class context virtual const char * get_base_filename () const = 0; + bool + handle_kv (const std::string &key, + const std::string &value, + scheme_handler &scheme) const; + protected: context (const char *option_name, const char *unparsed_spec, + key_handler *client_keys, line_maps *affected_location_mgr) : m_option_name (option_name), m_unparsed_spec (unparsed_spec), + m_client_keys (client_keys), m_affected_location_mgr (affected_location_mgr) { } @@ -86,6 +151,9 @@ protected: // e.g. "scheme:foo=bar,key=value" const char *m_unparsed_spec; + // Optional borrowed ptr to client-specific keys + key_handler *m_client_keys; + line_maps *m_affected_location_mgr; }; @@ -94,13 +162,17 @@ protected: struct dc_spec_context : public output_spec::context { public: - dc_spec_context (diagnostics::context &dc, + dc_spec_context (const char *option_name, + const char *unparsed_spec, + key_handler *client_keys, line_maps *affected_location_mgr, + diagnostics::context &dc, line_maps *control_location_mgr, - location_t loc, - const char *option_name, - const char *unparsed_spec) - : context (option_name, unparsed_spec, affected_location_mgr), + location_t loc) + : context (option_name, + unparsed_spec, + client_keys, + affected_location_mgr), m_dc (dc), m_control_location_mgr (control_location_mgr), m_loc (loc) diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc index 6b269a1..46714ff 100644 --- a/gcc/libgdiagnostics.cc +++ b/gcc/libgdiagnostics.cc @@ -2484,7 +2484,8 @@ public: const char *unparsed_spec, diagnostic_manager &affected_mgr, diagnostic_manager &control_mgr) - : context (option_name, unparsed_spec, affected_mgr.get_line_table ()), + : context (option_name, unparsed_spec, nullptr, + affected_mgr.get_line_table ()), m_control_mgr (control_mgr) {} diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod index 710976e..24634fd 100644 --- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod +++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod @@ -4447,19 +4447,6 @@ END PrintString ; (* - PrintKnown - -*) - -PROCEDURE PrintKnown (sym: CARDINAL) ; -BEGIN - IF GccKnowsAbout (sym) - THEN - printf0 ("[gcc]") - END -END PrintKnown ; - - -(* PrintVerboseFromList - prints the, i, th element in the list, l. *) diff --git a/gcc/m2/gm2-gcc/m2type.cc b/gcc/m2/gm2-gcc/m2type.cc index 535ab14..184b506 100644 --- a/gcc/m2/gm2-gcc/m2type.cc +++ b/gcc/m2/gm2-gcc/m2type.cc @@ -2213,7 +2213,7 @@ gm2_build_enumerator (location_t location, tree name, tree value) enumvalues, list. It returns a copy of the value. */ tree -m2type_BuildEnumerator (location_t location, char *name, tree value, +m2type_BuildEnumerator (location_t location, const char *name, tree value, tree *enumvalues) { tree id = get_identifier (name); diff --git a/gcc/m2/gm2-gcc/m2type.def b/gcc/m2/gm2-gcc/m2type.def index 8a72652..6f64c98 100644 --- a/gcc/m2/gm2-gcc/m2type.def +++ b/gcc/m2/gm2-gcc/m2type.def @@ -173,7 +173,7 @@ PROCEDURE BuildPointerType (totype: tree) : tree ; It returns a copy of the value. --fixme-- why do this? *) -PROCEDURE BuildEnumerator (location: location_t; name: CharStar; value: tree; +PROCEDURE BuildEnumerator (location: location_t; name: ConstCharStar; value: tree; VAR enumvalues: tree) : tree ; diff --git a/gcc/m2/gm2-gcc/m2type.h b/gcc/m2/gm2-gcc/m2type.h index afd97f7..68015a0 100644 --- a/gcc/m2/gm2-gcc/m2type.h +++ b/gcc/m2/gm2-gcc/m2type.h @@ -183,7 +183,7 @@ EXTERN tree m2type_BuildStartEnumeration (location_t location, char *name, bool ispacked); EXTERN tree m2type_BuildEndEnumeration (location_t location, tree enumtype, tree enumvalues); -EXTERN tree m2type_BuildEnumerator (location_t location, char *name, +EXTERN tree m2type_BuildEnumerator (location_t location, const char *name, tree value, tree *enumvalues); EXTERN tree m2type_BuildPointerType (tree totype); EXTERN tree m2type_BuildConstPointerType (tree totype); diff --git a/gcc/m2/gm2-libs/M2WIDESET.mod b/gcc/m2/gm2-libs/M2WIDESET.mod index f1b1bed..93df428 100644 --- a/gcc/m2/gm2-libs/M2WIDESET.mod +++ b/gcc/m2/gm2-libs/M2WIDESET.mod @@ -490,21 +490,21 @@ PROCEDURE ShiftLeftByteBit (VAR dest: ARRAY OF BYTE; src: ARRAY OF BYTE; highbit: CARDINAL; byteshift, bitshift: CARDINAL) ; VAR - top, bot, mid : BYTESET ; - i, h, from, to: CARDINAL ; + top, bot, mid : BYTESET ; + i, h, fromIdx, toIdx: CARDINAL ; BEGIN (* Copy the bytes into dest at the mostly correct position (modulo byte position). *) - to := 0 ; - from := 0 ; - WHILE to < byteshift DO - dest[to] := BYTE (0) ; - INC (to) + toIdx := 0 ; + fromIdx := 0 ; + WHILE toIdx < byteshift DO + dest[toIdx] := BYTE (0) ; + INC (toIdx) END ; - WHILE to <= HIGH (dest) DO - dest[to] := src[from] ; - INC (to) ; - INC (from) + WHILE toIdx <= HIGH (dest) DO + dest[toIdx] := src[fromIdx] ; + INC (toIdx) ; + INC (fromIdx) END ; (* And adjust by bit shifting. *) IF bitshift > 0 @@ -567,12 +567,12 @@ PROCEDURE ShiftRightByteBit (VAR dest: ARRAY OF BYTE; src: ARRAY OF BYTE; highbit: CARDINAL; byteshift, bitshift: CARDINAL) ; VAR - top, bot, mid : BYTESET ; - i, h, to, from: CARDINAL ; + top, bot, mid : BYTESET ; + i, h, toIdx, fromIdx: CARDINAL ; BEGIN (* Copy the bytes. *) - to := 0 ; - from := byteshift ; + toIdx := 0 ; + fromIdx := byteshift ; IF EnableDebugging THEN printf ("HIGH (dest) = %d\n", HIGH (dest)) @@ -580,15 +580,15 @@ BEGIN IF byteshift <= HIGH (dest) THEN h := HIGH (dest) - byteshift ; - WHILE to <= h DO - dest[to] := src[from] ; - INC (to) ; - INC (from) + WHILE toIdx <= h DO + dest[toIdx] := src[fromIdx] ; + INC (toIdx) ; + INC (fromIdx) END END ; - WHILE to <= HIGH (dest) DO - dest[to] := BYTE (0) ; - INC (to) + WHILE toIdx <= HIGH (dest) DO + dest[toIdx] := BYTE (0) ; + INC (toIdx) END ; (* And bit shift the remainder. *) IF EnableDebugging @@ -691,7 +691,7 @@ VAR next : BOOLEAN ; mask, unused, - set : BYTESET ; + setb : BYTESET ; BEGIN IF EnableDebugging THEN @@ -704,14 +704,14 @@ BEGIN bytes. *) i := 0 ; WHILE i < high DO - set := dest[i] ; - next := MSB IN set ; - set := SHIFT (set, 1) ; (* Shift left. *) + setb := dest[i] ; + next := MSB IN setb ; + setb := SHIFT (setb, 1) ; (* Shift left. *) IF carry THEN - INCL (set, 0) (* Set bit 0. *) + INCL (setb, 0) (* Set bit 0. *) END ; - dest[i] := set ; + dest[i] := setb ; carry := next ; IF EnableDebugging THEN @@ -722,27 +722,27 @@ BEGIN END ; (* Last byte special case as there may be some unused bits which must be preserved. *) - set := dest[high] ; + setb := dest[high] ; unused := BYTESET {} ; (* Will contain all top unused bits of dest[high]. *) mask := - BYTESET {} ; topbit := (highbit+1) MOD TBITSIZE (BYTE) ; WHILE topbit # 0 DO EXCL (mask, topbit) ; - IF topbit IN set + IF topbit IN setb THEN - EXCL (set, topbit) ; + EXCL (setb, topbit) ; INCL (unused, topbit) END ; topbit := (topbit+1) MOD TBITSIZE (BYTE) END ; - set := SHIFT (set, 1) ; (* Left shift. *) + setb := SHIFT (setb, 1) ; (* Left shift. *) IF carry THEN - INCL (set, 0) (* Set bit 0. *) + INCL (setb, 0) (* Set bit 0. *) END ; - set := set * mask ; (* Remove all unused bits. *) - set := set + unused ; (* Restore original unused bits. *) - dest[high] := set ; + setb := setb * mask ; (* Remove all unused bits. *) + setb := setb + unused ; (* Restore original unused bits. *) + dest[high] := setb ; IF EnableDebugging THEN printf ("ArithShiftLeft shifted byte dest[%d]\n", high); @@ -785,32 +785,32 @@ VAR next : BOOLEAN ; mask, unused, - set : BYTESET ; + setb : BYTESET ; BEGIN high := HIGH (dest) ; (* Clear any unused bits in the highest byte, but save them into unused. *) - set := dest[high] ; + setb := dest[high] ; unused := BYTESET {} ; topbit := (highbit+1) MOD TBITSIZE (BYTE) ; mask := - BYTESET {} ; WHILE topbit # 0 DO EXCL (mask, topbit) ; - IF topbit IN set + IF topbit IN setb THEN - EXCL (set, topbit) ; + EXCL (setb, topbit) ; INCL (unused, topbit) END ; topbit := (topbit+1) MOD TBITSIZE (BYTE) END ; (* Start at the top and work down to byte 0. *) - set := set * mask ; (* Ignore unused bits. *) - next := 0 IN set ; (* Next carry. *) - set := SHIFT (set, -1) ; (* Shift right by 1 bit. *) + setb := setb * mask ; (* Ignore unused bits. *) + next := 0 IN setb ; (* Next carry. *) + setb := SHIFT (setb, -1) ; (* Shift right by 1 bit. *) IF carry THEN - INCL (set, highbit MOD TBITSIZE (BYTE)) + INCL (setb, highbit MOD TBITSIZE (BYTE)) END ; - dest[high] := set + unused ; (* First byte is a special case as we + dest[high] := setb + unused ; (* First byte is a special case as we have to preserve the unused bits. *) (* Now we ripple through the remaining bytes, propagating local carry between bytes. *) @@ -818,14 +818,14 @@ BEGIN WHILE i > 0 DO prev := next ; DEC (i) ; - set := dest[i] ; - next := 0 IN set ; - set := SHIFT (set, -1) ; + setb := dest[i] ; + next := 0 IN setb ; + setb := SHIFT (setb, -1) ; IF prev THEN - INCL (set, MSB) + INCL (setb, MSB) END ; - dest[i] := set + dest[i] := setb END END ArithShiftRightBit ; @@ -914,7 +914,7 @@ VAR high, highplus1, highbitplus1, - from, to : CARDINAL ; + fromIdx, toIdx: CARDINAL ; BEGIN IF EnableDebugging THEN @@ -925,21 +925,21 @@ BEGIN (* Copy the contents rotating on byte granularity, then arithmetically shift the remaining number of bits. *) high := HIGH (dest) ; - from := 0 ; + fromIdx := 0 ; highplus1 := high + 1 ; highbitplus1 := highbit + 1 ; - to := RotateCount DIV TBITSIZE (BYTE) ; (* Byte level granularity. *) + toIdx := RotateCount DIV TBITSIZE (BYTE) ; (* Byte level granularity. *) REPEAT - dest[to] := src[from] ; + dest[toIdx] := src[fromIdx] ; IF EnableDebugging THEN printf ("RotateLeft after partial byte movement: dest[%d] := src[%d]\n", - to, from); + toIdx, fromIdx); DumpSet (dest, highbit) END ; - from := (from + 1) MOD highplus1 ; - to := (to + 1) MOD highplus1 ; - UNTIL from = 0 ; + fromIdx := (fromIdx + 1) MOD highplus1 ; + toIdx := (toIdx + 1) MOD highplus1 ; + UNTIL fromIdx = 0 ; IF EnableDebugging THEN diff --git a/gcc/opts-diagnostic.cc b/gcc/opts-diagnostic.cc index 6f459ec..a230c21 100644 --- a/gcc/opts-diagnostic.cc +++ b/gcc/opts-diagnostic.cc @@ -49,12 +49,13 @@ public: location_t loc, const char *option_name, const char *option_value) - : dc_spec_context (dc, + : dc_spec_context (option_name, + option_value, + nullptr, location_mgr, + dc, location_mgr, - loc, - option_name, - option_value), + loc), m_opts (opts) {} diff --git a/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.cc b/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.cc index 7b4f40e..3b3406e 100644 --- a/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.cc +++ b/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.cc @@ -2,7 +2,7 @@ * By the time a PLUGIN_START_UNIT callback is invoked, the frontend * initialization should have completed. At least the different *_type_nodes * should have been created. This plugin creates an artificial global - * interger variable. + * integer variable. * */ #include "gcc-plugin.h" diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error11.c b/gcc/testsuite/gcc.target/aarch64/mv-error11.c new file mode 100644 index 0000000..0fdd660 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error11.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +int fn () asm("name"); +int fn () { return 1; } /* { dg-error "cannot use function multiversioning on a renamed function" } */ +int fn [[gnu::target_version("sve")]] () { return 1; } + +int fn2 [[gnu::target_version("sve")]] () asm("name"); /* { dg-warning ".asm. declaration ignored due to conflict with previous rename" } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error12.c b/gcc/testsuite/gcc.target/aarch64/mv-error12.c new file mode 100644 index 0000000..45da85a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error12.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ +/* { dg-require-ifunc "" } */ + +#pragma omp declare simd +int fn [[gnu::target_version("sve")]] () { return 1; } /* { dg-error ".#pragma omp declare simd. cannot be used with function multi-versioning" } */ + +#pragma omp declare simd +int fn2 () { return 1; } + +int fn2 [[gnu::target_version("sve")]] (); /* { dg-warning "ignoring attribute .target_version. because it conflicts with attribute .omp declare simd." } */ + +int fn3 [[gnu::target_version("sve")]] [[gnu::simd]] () { return 1; } /* { dg-warning "ignoring attribute .simd. because it conflicts with attribute .target_version." } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr122051.c b/gcc/testsuite/gcc.target/riscv/pr122051.c new file mode 100644 index 0000000..c2f4b87 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr122051.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-additional-options "-mrvv-vector-bits=zvl -mcpu=xt-c920 -w" } */ + +typedef __attribute__((__vector_size__(4))) char B; +typedef __attribute__((__vector_size__(16))) long V; +typedef __attribute__((__vector_size__(32))) double W; +typedef __attribute__((__vector_size__(32))) char U; +unsigned u; +B o; +char *p; +int q; +V v; +W w; + +void +foo(__int128, __int128, __int128, __int128, B a, B b, B c, B d, B e, B f, B g, B h) { + do { + w -= q; + v ^= u; + } while (__builtin_memcmp(p, 1 + p, 7)); + o = ((U)w)[0] + c + d + e + f + g + h + a + b; +} + + diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-nearbyint-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-nearbyint-1.c index 89af160..bb62ce2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-nearbyint-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-nearbyint-1.c @@ -54,5 +54,5 @@ DEF_OP_V (nearbyint, 512, double, __builtin_nearbyint) /* { dg-final { scan-tree-dump-not "4096,4096" "optimized" } } */ /* { dg-final { scan-assembler-times {vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t} 30 } } */ /* { dg-final { scan-assembler-times {vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t} 30 } } */ -/* { dg-final { scan-assembler-times {frflags\s+[atx][0-9]+} 32 } } */ -/* { dg-final { scan-assembler-times {fsflags\s+[atx][0-9]+} 32 } } */ +/* { dg-final { scan-assembler-times {frflags\s+[atx][0-9]+} 30 } } */ +/* { dg-final { scan-assembler-times {fsflags\s+[atx][0-9]+} 30 } } */ diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 1d549e4..df45adb 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -7177,6 +7177,15 @@ vectorizable_reduction (loop_vec_info loop_vinfo, tree vectype_out = SLP_TREE_VECTYPE (slp_for_stmt_info); VECT_REDUC_INFO_VECTYPE (reduc_info) = vectype_out; + /* We do not handle mask reductions correctly in the epilogue. */ + if (VECTOR_BOOLEAN_TYPE_P (vectype_out)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "mask reduction not supported.\n"); + return false; + } + gimple_match_op op; if (!gimple_extract_op (stmt_info->stmt, &op)) gcc_unreachable (); @@ -7187,8 +7196,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, return false; /* Do not try to vectorize bit-precision reductions. */ - if (!VECTOR_BOOLEAN_TYPE_P (vectype_out) - && !type_has_mode_precision_p (op.type) + if (!type_has_mode_precision_p (op.type) && op.code != BIT_AND_EXPR && op.code != BIT_IOR_EXPR && op.code != BIT_XOR_EXPR) |