diff options
author | Martin Liska <mliska@suse.cz> | 2021-06-04 13:36:59 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-06-04 13:36:59 +0200 |
commit | d67627857ce27d607c691308aa2b816aabb6cb32 (patch) | |
tree | acf805e89e365badcdb7f14c6aa7eeb72df5a5e0 /gcc | |
parent | 38dbface07d437b0fc3742f517a5d9dcf14ffdb8 (diff) | |
parent | 39e5a954c156f7af16aa1a8f87405433d8031c4e (diff) | |
download | gcc-d67627857ce27d607c691308aa2b816aabb6cb32.zip gcc-d67627857ce27d607c691308aa2b816aabb6cb32.tar.gz gcc-d67627857ce27d607c691308aa2b816aabb6cb32.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
60 files changed, 1305 insertions, 495 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d118a5..06e6dbe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,170 @@ +2021-06-03 Kewen Lin <linkw@linux.ibm.com> + + * config/cris/cris.md (*addi_reload): Fix empty split condition. + +2021-06-03 Jim Wilson <jimw@sifive.com> + + * config.gcc (riscv*-*-*): If --with-riscv-attribute not used, + turn it on for all riscv targets. + +2021-06-03 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100637 + * config/i386/i386-expand.c (ix86_expand_vector_set): + Handle V2HI and V4QI modes. + (ix86_expand_vector_extract): Ditto. + * config/i386/mmx.md (*pinsrw): New insn pattern. + (*pinsrb): Ditto. + (*pextrw): Ditto. + (*pextrw_zext): Ditto. + (*pextrb): Ditto. + (*pextrb_zext): Ditto. + (vec_setv2hi): New expander. + (vec_extractv2hihi): Ditto. + (vec_setv4qi): Ditto. + (vec_extractv4qiqi): Ditto. + (vec_setv8qi): Enable only for TARGET_SSE4_1. + (vec_extractv8qiqi): Ditto. + +2021-06-03 Aaron Sawdey <acsawdey@linux.ibm.com> + + * config/rs6000/genfusion.pl (gen_logical_addsubf): Fix input + order to subf instruction. + * config/rs6000/fusion.md: Regenerate. + +2021-06-03 Aldy Hernandez <aldyh@redhat.com> + + * calls.c (get_size_range): Use range_of_expr instead of + determine_value_range. + * tree-affine.c (expr_to_aff_combination): Same. + * tree-data-ref.c (split_constant_offset): Same. + * tree-vrp.c (determine_value_range_1): Remove. + (determine_value_range): Remove. + * tree-vrp.h (determine_value_range): Remove. + +2021-06-03 Aldy Hernandez <aldyh@redhat.com> + + * function-tests.c (test_ranges): Call gimple_range_tests. + * gimple-range-cache.cc (ranger_cache::range_of_expr): Pass stmt + to get_tree_range. + * gimple-range.cc (fur_source::get_operand): Do not call + get_tree_range or gimple_range_global. + get_tree_range. + (get_tree_range): Move to value-query.cc. + Call get_arith_expr_range. + (gimple_ranger::range_of_expr): Add argument to get_tree_range. + Include gimple-range-tests.cc. + * gimple-range.h (fold_range): Add argument. + (get_tree_range): Remove. + * selftest.h (gimple_range_tests): New. + * value-query.cc (global_range_query::range_of_expr): Add + stmt argument. + (range_query::get_tree_range): Move from gimple-range.cc. + * value-query.h (class range_query): Add get_tree_range and + get_arith_expr_range. Make fur_source a friend. + * vr-values.c (vr_values::range_of_expr): Pass stmt to + get_tree_range. + * gimple-range-tests.cc: New file. + +2021-06-03 Aldy Hernandez <aldyh@redhat.com> + + * gimple-range.cc (gimple_ranger::export_global_ranges): Call + update_global_range. + * value-query.cc (update_global_range): New. + * value-query.h (update_global_range): New. + +2021-06-03 David Malcolm <dmalcolm@redhat.com> + + * diagnostic-show-locus.c (diagnostic_show_locus): Don't reject + printing the same location twice if there are fix-it hints, + multiple locations, or a label. + +2021-06-03 Andre Vieira <andre.simoesdiasvieira@arm.com> + + * tree-vect-loop.c (vect_transform_loop): Use main loop's various' + thresholds to narrow the upper bound on epilogue iterations. + +2021-06-03 Christophe Lyon <christophe.lyon@linaro.org> + + * config/arm/mve.md (mve_vabsq_f<mode>): Use 'abs' instead of unspec. + (mve_vabsq_s<mode>): Likewise. + * config/arm/neon.md (abs<mode>2): Rename to neon_abs<mode>2. + * config/arm/unspecs.md (VABSQ_F, VABSQ_S): Delete. + * config/arm/vec-common.md (neg<mode>2): Rename to + <absneg_str><mode>2. + +2021-06-03 Claudiu Zissulescu <claziss@synopsys.com> + + * common/config/arc/arc-common.c (arc_option_optimization_table): + Remove malign-call. + * config/arc/arc.c (arc_unalign_branch_p): Remove unused function. + * config/arc/arc.h (TARGET_MIXED_CODE): Remove macro. + (INDEX_REG_CLASS): Only refer to GENERAL_REGS. + * config/arc/arc.md (abssi2_mixed): Remove pattern. + * config/arc/arc.opt (munalign-prob-threshold): Mark it obsolete. + (malign-call): Likewise. + (mmixed-code): Likewise. + * doc/invoke.texi (ARC): Update doc. + +2021-06-03 Martin Liska <mliska@suse.cz> + + * common.opt: Use proper Enum values. + * opts.c (COVERAGE_SANITIZER_OPT): Remove. + (parse_sanitizer_options): Handle only sanitizer_opts. + (common_handle_option): Just assign value. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + PR ipa/99122 + * tree-inline.c (inline_forbidden_p): Remove test on return type. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * dwarf2out.c (loc_list_from_tree_1) <FUNCTION_DECL>: Also generate + DW_OP_GNU_variable_value referencing an existing DIE at file scope. + (type_byte_size): Inline into... + (add_byte_size_attribute): ...this and call add_scalar_info. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * dwarf2out.c (mem_loc_descriptor) <UDIV>: Fix typo. + (typed_binop_from_tree): New function. + (loc_list_from_tree_1) <EXACT_DIV_EXPR>: For an unsigned type, + turn a divide by a power of 2 into a shift. + <CEIL_DIV_EXPR>: For an unsigned type, use a signed divide if the + size of the mode is lower than DWARF2_ADDR_SIZE; otherwise, do a + typed divide by calling typed_binop_from_tree. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * dwarf2out.c (scompare_loc_descriptor): Fix head comment. + (is_handled_procedure_type): Likewise. + (struct loc_descr_context): Add strict_signedness field. + (resolve_args_picking_1): Deal with DW_OP_[GNU_]deref_type, + DW_OP_[GNU_]convert and DW_OP_[GNU_]reinterpret. + (resolve_args_picking): Minor tweak. + (function_to_dwarf_procedure): Initialize strict_signedness field. + (type_byte_size): Likewise. + (field_byte_offset): Likewise. + (gen_descr_array_type_die): Likewise. + (gen_variant_part): Likewise. + (loc_list_from_tree_1) <CALL_EXPR>: Tidy up and set strict_signedness + to true when a context is present before evaluating the arguments. + <COND_EXPR>: Do not generate a useless comparison with zero. + When dereferencing an address, if strict_signedness is true and the + type is small and signed, use DW_OP_deref_type to do the dereference + and then DW_OP_convert to convert back to the generic type. + +2021-06-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/100859 + * tree-inline.c (copy_tree_body_r): Handle iterators on + OMP_CLAUSE_AFFINITY or OMP_CLAUSE_DEPEND. + +2021-06-03 Kewen Lin <linkw@linux.ibm.com> + + * config/arc/arc.md (*bbit_di): Remove. + 2021-06-02 Christoph Muellner <cmuellner@gcc.gnu.org> PR rtl-optimization/100264 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index d185478..8da0c6d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210603 +20210604 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 0641e60..9805f18 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Add PAT + local constant and use it throughout. If it is set, use a ref-all + pointer type for the pointer-to-array field of the fat pointer type. + <E_Array_Subtype>: Add PAT local constant and use it throughout. + 2021-05-26 Jakub Jelinek <jakub@redhat.com> * init.c (__gnat_error_handler): Remove register keyword. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index bc7046a..6fc94dd 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -2100,6 +2100,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) case E_Array_Type: { + const Entity_Id PAT = Packed_Array_Impl_Type (gnat_entity); const bool convention_fortran_p = (Convention (gnat_entity) == Convention_Fortran); const int ndim = Number_Dimensions (gnat_entity); @@ -2203,16 +2204,16 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) } /* If the GNAT encodings are used, give the fat pointer type a name. - If this is a packed array, tell the debugger how to interpret the - underlying bits by fetching that of the implementation type. But - in any case, mark it as artificial so the debugger can skip it. */ + If this is a packed type implemented specially, tell the debugger + how to interpret the underlying bits by fetching the name of the + implementation type. But, in any case, mark it as artificial so + the debugger can skip it. */ const Entity_Id gnat_name - = (Present (Packed_Array_Impl_Type (gnat_entity)) - && gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) - ? Packed_Array_Impl_Type (gnat_entity) + = Present (PAT) && gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL + ? PAT : gnat_entity; tree xup_name - = (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) + = gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL ? create_concat_name (gnat_name, "XUP") : gnu_entity_name; create_type_decl (xup_name, gnu_fat_type, true, debug_info_p, @@ -2347,9 +2348,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* If this is a packed type implemented specially, then process the implementation type so it is elaborated in the proper scope. */ - if (Present (Packed_Array_Impl_Type (gnat_entity))) - gnat_to_gnu_entity (Packed_Array_Impl_Type (gnat_entity), NULL_TREE, - false); + if (Present (PAT)) + gnat_to_gnu_entity (PAT, NULL_TREE, false); /* Otherwise, if an alignment is specified, use it if valid and, if the alignment was requested with an explicit clause, state so. */ @@ -2374,8 +2374,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) tem = change_qualified_type (tem, TYPE_QUAL_VOLATILE); /* Adjust the type of the pointer-to-array field of the fat pointer - and record the aliasing relationships if necessary. */ - TREE_TYPE (TYPE_FIELDS (gnu_fat_type)) = build_pointer_type (tem); + and record the aliasing relationships if necessary. If this is + a packed type implemented specially, then use a ref-all pointer + type since the implementation type may vary between constrained + subtypes and unconstrained base type. */ + if (Present (PAT)) + TREE_TYPE (TYPE_FIELDS (gnu_fat_type)) + = build_pointer_type_for_mode (tem, ptr_mode, true); + else + TREE_TYPE (TYPE_FIELDS (gnu_fat_type)) = build_pointer_type (tem); if (TYPE_ALIAS_SET_KNOWN_P (gnu_fat_type)) record_component_aliases (gnu_fat_type); @@ -2439,6 +2446,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) ; else { + const Entity_Id PAT = Packed_Array_Impl_Type (gnat_entity); Entity_Id gnat_index, gnat_base_index; const bool convention_fortran_p = (Convention (gnat_entity) == Convention_Fortran); @@ -2844,7 +2852,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* If this is a packed type implemented specially, then replace our type with the implementation type. */ - if (Present (Packed_Array_Impl_Type (gnat_entity))) + if (Present (PAT)) { /* First finish the type we had been making so that we output debugging information for it. */ @@ -2869,8 +2877,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) this type again. */ save_gnu_tree (gnat_entity, gnu_tmp_decl, false); - gnu_type - = gnat_to_gnu_type (Packed_Array_Impl_Type (gnat_entity)); + gnu_type = gnat_to_gnu_type (PAT); save_gnu_tree (gnat_entity, NULL_TREE, false); /* Set the ___XP suffix for GNAT encodings. */ diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 7396971..838d5f1 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,13 @@ +2021-06-03 David Malcolm <dmalcolm@redhat.com> + + * store.h (store::get_direct_binding): Remove unused decl. + (store::get_default_binding): Likewise. + +2021-06-03 David Malcolm <dmalcolm@redhat.com> + + * svalue.cc (poisoned_svalue::dump_to_pp): Dump type. + (compound_svalue::dump_to_pp): Dump any type. + 2021-05-18 David Malcolm <dmalcolm@redhat.com> PR analyzer/100615 diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h index dc22d96..d68513c 100644 --- a/gcc/analyzer/store.h +++ b/gcc/analyzer/store.h @@ -611,8 +611,6 @@ public: json::object *to_json () const; - const svalue *get_direct_binding (store_manager *mgr, const region *reg); - const svalue *get_default_binding (store_manager *mgr, const region *reg); const svalue *get_any_binding (store_manager *mgr, const region *reg) const; bool called_unknown_fn_p () const { return m_called_unknown_fn; } diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc index 897e84e..a16563d 100644 --- a/gcc/analyzer/svalue.cc +++ b/gcc/analyzer/svalue.cc @@ -735,9 +735,17 @@ void poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const { if (simple) - pp_printf (pp, "POISONED(%s)", poison_kind_to_str (m_kind)); + { + pp_string (pp, "POISONED("); + print_quoted_type (pp, get_type ()); + pp_printf (pp, ", %s)", poison_kind_to_str (m_kind)); + } else - pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind)); + { + pp_string (pp, "poisoned_svalue("); + print_quoted_type (pp, get_type ()); + pp_printf (pp, ", %s)", poison_kind_to_str (m_kind)); + } } /* Implementation of svalue::accept vfunc for poisoned_svalue. */ @@ -1228,17 +1236,26 @@ compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const if (simple) { pp_string (pp, "COMPOUND("); + if (get_type ()) + { + print_quoted_type (pp, get_type ()); + pp_string (pp, ", "); + } + pp_character (pp, '{'); m_map.dump_to_pp (pp, simple, false); - pp_character (pp, ')'); + pp_string (pp, "})"); } else { pp_string (pp, "compound_svalue ("); - pp_string (pp, ", "); + if (get_type ()) + { + print_quoted_type (pp, get_type ()); + pp_string (pp, ", "); + } pp_character (pp, '{'); m_map.dump_to_pp (pp, simple, false); - pp_string (pp, "}, "); - pp_character (pp, ')'); + pp_string (pp, "})"); } } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index cb2757c..968322f 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,40 @@ +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * c-ada-spec.c (dump_ada_macros): Minor tweaks. + (dump_ada_decl_name): Likewise. + (dump_anonymous_type_name): Remove parent parameter and adjust. + (dump_sloc): Minor tweak. + (dump_ada_array_type): Remove type parameter and adjust. + (dump_ada_enum_type): Remove parent parameter and adjust. + (dump_ada_node): Adjust calls to above functions. + (dumped_anonymous_types): New global variable. + (dump_nested_types_1): Rename into... + (dump_nested_types): ...this. + (dump_nested_type): Remove parent and dumped_types parameters. + <ARRAY_TYPE>: Replace dumped_types with dumped_anonymous_types. + Adjust calls to dump_anonymous_type_name and dump_ada_array_type. + (dump_ada_specs): Initialize and free dumped_anonymous_types. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * c-ada-spec.c (pp_ada_tree_identifier): Tidy up. + (dump_ada_node) <POINTER_TYPE>: Deal specially with external subtypes. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * c-ada-spec.c (dump_ada_enum_type): Dump a prefix for constants. + (htable_t): New typedef. + (overloaded_names): Use it. + (add_name): New function. + (init_overloaded_names): Use add_name to populate the table and add + special cases for sigaction and stat. + (overloaded_name_p): Rename into... + (overloading_index): ...this. Do not initialize overloaded_names table + here. Return the index or zero. + (dump_ada_declaration): Minor tweaks. Do not skip overloaded functions + but add an overloading suffix instead. + (dump_ada_specs): Initialize overloaded_names tables here. + 2021-06-01 Martin Liska <mliska@suse.cz> PR other/100759 diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index 29eb0b0..a2669c6 100644 --- a/gcc/c-family/c-ada-spec.c +++ b/gcc/c-family/c-ada-spec.c @@ -408,8 +408,8 @@ dump_ada_macros (pretty_printer *pp, const char* file) } else { - chars_seen = sprintf - ((char *) buffer, "Character'Val (%d)", (int) c); + chars_seen = sprintf ((char *) buffer, + "Character'Val (%d)", (int) c); buffer += chars_seen; } } @@ -611,7 +611,7 @@ dump_ada_macros (pretty_printer *pp, const char* file) pp_string (pp, "; -- "); pp_string (pp, sloc.file); pp_colon (pp); - pp_scalar (pp, "%d", sloc.line); + pp_decimal_int (pp, sloc.line); pp_newline (pp); } else @@ -1341,49 +1341,46 @@ pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type, char *s = to_ada_name (name, &space_found); tree decl = get_underlying_decl (type); - /* If the entity comes from another file, generate a package prefix. */ if (decl) { - expanded_location xloc = expand_location (decl_sloc (decl, false)); + /* If the entity comes from another file, generate a package prefix. */ + const expanded_location xloc = expand_location (decl_sloc (decl, false)); - if (xloc.file && xloc.line) + if (xloc.line && xloc.file && xloc.file != current_source_file) { - if (xloc.file != current_source_file) + switch (TREE_CODE (type)) { - switch (TREE_CODE (type)) - { - case ENUMERAL_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - case BOOLEAN_TYPE: - case REFERENCE_TYPE: - case POINTER_TYPE: - case ARRAY_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - case TYPE_DECL: - if (package_prefix) - { - char *s1 = get_ada_package (xloc.file); - append_withs (s1, limited_access); - pp_string (buffer, s1); - pp_dot (buffer); - free (s1); - } - break; - default: - break; - } + case ENUMERAL_TYPE: + case INTEGER_TYPE: + case REAL_TYPE: + case FIXED_POINT_TYPE: + case BOOLEAN_TYPE: + case REFERENCE_TYPE: + case POINTER_TYPE: + case ARRAY_TYPE: + case RECORD_TYPE: + case UNION_TYPE: + case TYPE_DECL: + if (package_prefix) + { + char *s1 = get_ada_package (xloc.file); + append_withs (s1, limited_access); + pp_string (buffer, s1); + pp_dot (buffer); + free (s1); + } + break; + default: + break; + } - /* Generate the additional package prefix for C++ classes. */ - if (separate_class_package (decl)) - { - pp_string (buffer, "Class_"); - pp_string (buffer, s); - pp_dot (buffer); - } - } + /* Generate the additional package prefix for C++ classes. */ + if (separate_class_package (decl)) + { + pp_string (buffer, "Class_"); + pp_string (buffer, s); + pp_dot (buffer); + } } } @@ -1467,28 +1464,21 @@ dump_ada_decl_name (pretty_printer *buffer, tree decl, bool limited_access) { pp_string (buffer, "anon"); if (TREE_CODE (decl) == FIELD_DECL) - pp_scalar (buffer, "%d", DECL_UID (decl)); + pp_decimal_int (buffer, DECL_UID (decl)); else - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (decl))); + pp_decimal_int (buffer, TYPE_UID (TREE_TYPE (decl))); } else if (TREE_CODE (type_name) == IDENTIFIER_NODE) pp_ada_tree_identifier (buffer, type_name, decl, limited_access); } } -/* Dump in BUFFER a name for the type T, which is a _TYPE without TYPE_NAME. - PARENT is the parent node of T. */ +/* Dump in BUFFER a name for the type T, which is a TYPE without TYPE_NAME. */ static void -dump_anonymous_type_name (pretty_printer *buffer, tree t, tree parent) +dump_anonymous_type_name (pretty_printer *buffer, tree t) { - if (DECL_NAME (parent)) - pp_ada_tree_identifier (buffer, DECL_NAME (parent), parent, false); - else - { - pp_string (buffer, "anon"); - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (parent))); - } + pp_string (buffer, "anon"); switch (TREE_CODE (t)) { @@ -1509,7 +1499,7 @@ dump_anonymous_type_name (pretty_printer *buffer, tree t, tree parent) break; } - pp_scalar (buffer, "%d", TYPE_UID (t)); + pp_decimal_int (buffer, TYPE_UID (t)); } /* Dump in BUFFER aspect Import on a given node T. SPC is the current @@ -1760,12 +1750,12 @@ dump_sloc (pretty_printer *buffer, tree node) { expanded_location xloc; - xloc.file = NULL; - if (DECL_P (node)) xloc = expand_location (DECL_SOURCE_LOCATION (node)); else if (EXPR_HAS_LOCATION (node)) xloc = expand_location (EXPR_LOCATION (node)); + else + xloc.file = NULL; if (xloc.file) { @@ -1793,11 +1783,11 @@ is_char_array (tree t) && id_equal (DECL_NAME (TYPE_NAME (t)), "char"); } -/* Dump in BUFFER an array type NODE of type TYPE in Ada syntax. SPC is the - indentation level. */ +/* Dump in BUFFER an array type NODE in Ada syntax. SPC is the indentation + level. */ static void -dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc) +dump_ada_array_type (pretty_printer *buffer, tree node, int spc) { const bool char_array = is_char_array (node); @@ -1826,8 +1816,8 @@ dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc) || (!RECORD_OR_UNION_TYPE_P (tmp) && TREE_CODE (tmp) != ENUMERAL_TYPE)) dump_ada_node (buffer, tmp, node, spc, false, true); - else if (type) - dump_anonymous_type_name (buffer, tmp, type); + else + dump_anonymous_type_name (buffer, tmp); } } @@ -1957,11 +1947,10 @@ is_simple_enum (tree node) } /* Dump in BUFFER the declaration of enumeral NODE of type TYPE in Ada syntax. - PARENT is the parent node of NODE. SPC is the indentation level. */ + SPC is the indentation level. */ static void -dump_ada_enum_type (pretty_printer *buffer, tree node, tree type, tree parent, - int spc) +dump_ada_enum_type (pretty_printer *buffer, tree node, tree type, int spc) { if (is_simple_enum (node)) { @@ -2003,7 +1992,15 @@ dump_ada_enum_type (pretty_printer *buffer, tree node, tree type, tree parent, pp_semicolon (buffer); newline_and_indent (buffer, spc); + if (TYPE_NAME (node)) + dump_ada_node (buffer, node, NULL_TREE, spc, false, true); + else if (type) + dump_ada_node (buffer, type, NULL_TREE, spc, false, true); + else + dump_anonymous_type_name (buffer, node); + pp_underscore (buffer); pp_ada_tree_identifier (buffer, TREE_PURPOSE (value), node, false); + pp_string (buffer, " : constant "); if (TYPE_NAME (node)) @@ -2011,7 +2008,7 @@ dump_ada_enum_type (pretty_printer *buffer, tree node, tree type, tree parent, else if (type) dump_ada_node (buffer, type, NULL_TREE, spc, false, true); else - dump_anonymous_type_name (buffer, node, parent); + dump_anonymous_type_name (buffer, node); pp_string (buffer, " := "); dump_ada_node (buffer, int_val, node, spc, false, true); @@ -2101,7 +2098,7 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc, if (name_only) dump_ada_node (buffer, TYPE_NAME (node), node, spc, false, true); else - dump_ada_enum_type (buffer, node, type, NULL_TREE, spc); + dump_ada_enum_type (buffer, node, type, spc); break; case REAL_TYPE: @@ -2111,6 +2108,7 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc, pp_string (buffer, "Extensions.Float_128"); break; } + /* fallthrough */ case INTEGER_TYPE: @@ -2212,6 +2210,24 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc, { tree type_name = TYPE_NAME (TREE_TYPE (node)); + /* Generate "access <type>" instead of "access <subtype>" + if the subtype comes from another file, because subtype + declarations do not contribute to the limited view of a + package and thus subtypes cannot be referenced through + a limited_with clause. */ + if (type_name + && TREE_CODE (type_name) == TYPE_DECL + && DECL_ORIGINAL_TYPE (type_name) + && TYPE_NAME (DECL_ORIGINAL_TYPE (type_name))) + { + const expanded_location xloc + = expand_location (decl_sloc (type_name, false)); + if (xloc.line + && xloc.file + && xloc.file != current_source_file) + type_name = DECL_ORIGINAL_TYPE (type_name); + } + /* For now, handle access-to-access as System.Address. */ if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE) { @@ -2233,8 +2249,8 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc, { if (!type || TREE_CODE (type) != FUNCTION_DECL) { - pp_string (buffer, "access "); is_access = true; + pp_string (buffer, "access "); if (quals & TYPE_QUAL_CONST) pp_string (buffer, "constant "); @@ -2275,7 +2291,7 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc, dump_ada_node (buffer, TYPE_NAME (node), node, spc, limited_access, true); else - dump_ada_array_type (buffer, node, type, spc); + dump_ada_array_type (buffer, node, spc); break; case RECORD_TYPE: @@ -2467,7 +2483,12 @@ dump_forward_type (pretty_printer *buffer, tree type, tree t, int spc) TREE_VISITED (decl) = 1; } -static void dump_nested_type (pretty_printer *, tree, tree, tree, bitmap, int); +/* Bitmap of anonymous types already dumped. Anonymous array types are shared + throughout the compilation so it needs to be global. */ + +static bitmap dumped_anonymous_types; + +static void dump_nested_type (pretty_printer *, tree, tree, int); /* Dump in BUFFER anonymous types nested inside T's definition. PARENT is the parent node of T. DUMPED_TYPES is the bitmap of already dumped types. SPC @@ -2483,8 +2504,7 @@ static void dump_nested_type (pretty_printer *, tree, tree, tree, bitmap, int); pass on the nested TYPE_DECLs and a second pass on the unnamed types. */ static void -dump_nested_types_1 (pretty_printer *buffer, tree t, tree parent, - bitmap dumped_types, int spc) +dump_nested_types (pretty_printer *buffer, tree t, int spc) { tree type, field; @@ -2498,31 +2518,18 @@ dump_nested_types_1 (pretty_printer *buffer, tree t, tree parent, && DECL_NAME (field) != DECL_NAME (t) && !DECL_ORIGINAL_TYPE (field) && TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (type)) - dump_nested_type (buffer, field, t, parent, dumped_types, spc); + dump_nested_type (buffer, field, t, spc); for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !TYPE_NAME (TREE_TYPE (field))) - dump_nested_type (buffer, field, t, parent, dumped_types, spc); -} - -/* Likewise, but to be invoked only at top level. We dump each anonymous type - nested inside T's definition exactly once, even if it is referenced several - times in it (typically an array type), with a name prefixed by that of T. */ - -static void -dump_nested_types (pretty_printer *buffer, tree t, int spc) -{ - auto_bitmap dumped_types; - dump_nested_types_1 (buffer, t, t, dumped_types, spc); + dump_nested_type (buffer, field, t, spc); } -/* Dump in BUFFER the anonymous type of FIELD inside T. PARENT is the parent - node of T. DUMPED_TYPES is the bitmap of already dumped types. SPC is the - indentation level. */ +/* Dump in BUFFER the anonymous type of FIELD inside T. SPC is the indentation + level. */ static void -dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, - bitmap dumped_types, int spc) +dump_nested_type (pretty_printer *buffer, tree field, tree t, int spc) { tree field_type = TREE_TYPE (field); tree decl, tmp; @@ -2536,7 +2543,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, case ARRAY_TYPE: /* Anonymous array types are shared. */ - if (!bitmap_set_bit (dumped_types, TYPE_UID (field_type))) + if (!bitmap_set_bit (dumped_anonymous_types, TYPE_UID (field_type))) return; /* Recurse on the element type if need be. */ @@ -2550,7 +2557,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, && !TREE_VISITED (decl)) { /* Generate full declaration. */ - dump_nested_type (buffer, decl, t, parent, dumped_types, spc); + dump_nested_type (buffer, decl, t, spc); TREE_VISITED (decl) = 1; } else if (!decl && TREE_CODE (tmp) == POINTER_TYPE) @@ -2562,9 +2569,9 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, else pp_string (buffer, "type "); - dump_anonymous_type_name (buffer, field_type, parent); + dump_anonymous_type_name (buffer, field_type); pp_string (buffer, " is "); - dump_ada_array_type (buffer, field_type, parent, spc); + dump_ada_array_type (buffer, field_type, spc); pp_semicolon (buffer); newline_and_indent (buffer, spc); break; @@ -2578,23 +2585,23 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, if (TYPE_NAME (field_type)) dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true); else - dump_anonymous_type_name (buffer, field_type, parent); + dump_anonymous_type_name (buffer, field_type); pp_string (buffer, " is "); - dump_ada_enum_type (buffer, field_type, NULL_TREE, parent, spc); + dump_ada_enum_type (buffer, field_type, NULL_TREE, spc); pp_semicolon (buffer); newline_and_indent (buffer, spc); break; case RECORD_TYPE: case UNION_TYPE: - dump_nested_types_1 (buffer, field, parent, dumped_types, spc); + dump_nested_types (buffer, field, spc); pp_string (buffer, "type "); if (TYPE_NAME (field_type)) dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true); else - dump_anonymous_type_name (buffer, field_type, parent); + dump_anonymous_type_name (buffer, field_type); if (TREE_CODE (field_type) == UNION_TYPE) pp_string (buffer, " (discr : unsigned := 0)"); @@ -2628,11 +2635,31 @@ struct overloaded_name_hasher : delete_ptr_hash<overloaded_name_hash> { return a->name == b->name; } }; -static hash_table<overloaded_name_hasher> *overloaded_names; +typedef hash_table<overloaded_name_hasher> htable_t; + +static htable_t *overloaded_names; + +/* Add an overloaded NAME with N occurrences to TABLE. */ + +static void +add_name (const char *name, unsigned int n, htable_t *table) +{ + struct overloaded_name_hash in, *h, **slot; + tree id = get_identifier (name); + hashval_t hash = htab_hash_pointer (id); + in.hash = hash; + in.name = id; + slot = table->find_slot_with_hash (&in, hash, INSERT); + h = new overloaded_name_hash; + h->hash = hash; + h->name = id; + h->n = n; + *slot = h; +} /* Initialize the table with the problematic overloaded names. */ -static hash_table<overloaded_name_hasher> * +static htable_t * init_overloaded_names (void) { static const char *names[] = @@ -2640,41 +2667,31 @@ init_overloaded_names (void) { "memchr", "rawmemchr", "memrchr", "strchr", "strrchr", "strchrnul", "strpbrk", "strstr", "strcasestr", "index", "rindex", "basename" }; - hash_table<overloaded_name_hasher> *table - = new hash_table<overloaded_name_hasher> (64); + htable_t *table = new htable_t (64); for (unsigned int i = 0; i < ARRAY_SIZE (names); i++) - { - struct overloaded_name_hash in, *h, **slot; - tree id = get_identifier (names[i]); - hashval_t hash = htab_hash_pointer (id); - in.hash = hash; - in.name = id; - slot = table->find_slot_with_hash (&in, hash, INSERT); - h = new overloaded_name_hash; - h->hash = hash; - h->name = id; - h->n = 0; - *slot = h; - } + add_name (names[i], 0, table); + + /* Consider that sigaction() is overloaded by struct sigaction for QNX. */ + add_name ("sigaction", 1, table); + + /* Consider that stat() is overloaded by struct stat for QNX. */ + add_name ("stat", 1, table); return table; } -/* Return whether NAME cannot be supported as overloaded name. */ +/* Return the overloading index of NAME or 0 if NAME is not overloaded. */ -static bool -overloaded_name_p (tree name) +static unsigned int +overloading_index (tree name) { - if (!overloaded_names) - overloaded_names = init_overloaded_names (); - struct overloaded_name_hash in, *h; hashval_t hash = htab_hash_pointer (name); in.hash = hash; in.name = name; h = overloaded_names->find_with_hash (&in, hash); - return h && ++h->n > 1; + return h ? ++h->n : 0; } /* Dump in BUFFER constructor spec corresponding to T for TYPE. */ @@ -2798,14 +2815,17 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) } /* Skip unnamed or anonymous structs/unions/enum types. */ - if (!orig && !decl_name && !name + if (!orig && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) - || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)) + || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE) + && !decl_name + && !name) return 0; - /* Skip anonymous enum types (duplicates of real types). */ + /* Skip duplicates of structs/unions/enum types built in C++. */ if (!orig - && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE + && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) + || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE) && decl_name && (*IDENTIFIER_POINTER (decl_name) == '.' || *IDENTIFIER_POINTER (decl_name) == '$')) @@ -2826,16 +2846,6 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) return 1; } - if (decl_name - && (*IDENTIFIER_POINTER (decl_name) == '.' - || *IDENTIFIER_POINTER (decl_name) == '$')) - { - pp_string (buffer, "-- skipped anonymous struct "); - dump_ada_node (buffer, t, type, spc, false, true); - TREE_VISITED (t) = 1; - return 1; - } - /* ??? Packed record layout is not supported. */ if (TYPE_PACKED (TREE_TYPE (t))) { @@ -2869,7 +2879,11 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) case POINTER_TYPE: case REFERENCE_TYPE: dump_forward_type (buffer, TREE_TYPE (TREE_TYPE (t)), t, spc); - /* fallthrough */ + if (orig && TYPE_NAME (orig)) + pp_string (buffer, "subtype "); + else + pp_string (buffer, "type "); + break; case ARRAY_TYPE: if ((orig && TYPE_NAME (orig)) || is_char_array (TREE_TYPE (t))) @@ -2923,7 +2937,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) if (orig && TYPE_NAME (orig)) dump_ada_node (buffer, TYPE_NAME (orig), type, spc, false, true); else - dump_ada_array_type (buffer, TREE_TYPE (t), type, spc); + dump_ada_array_type (buffer, TREE_TYPE (t), spc); } else { @@ -2938,16 +2952,16 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) if (TYPE_NAME (TREE_TYPE (t))) dump_ada_node (buffer, TREE_TYPE (t), type, spc, false, true); else if (type) - dump_anonymous_type_name (buffer, TREE_TYPE (t), type); + dump_anonymous_type_name (buffer, TREE_TYPE (t)); else - dump_ada_array_type (buffer, TREE_TYPE (t), type, spc); + dump_ada_array_type (buffer, TREE_TYPE (t), spc); } } else if (TREE_CODE (t) == FUNCTION_DECL) { + tree decl_name = DECL_NAME (t); bool is_abstract_class = false; bool is_method = TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE; - tree decl_name = DECL_NAME (t); bool is_abstract = false; bool is_assignment_operator = false; bool is_constructor = false; @@ -2955,7 +2969,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) bool is_copy_constructor = false; bool is_move_constructor = false; - if (!decl_name || overloaded_name_p (decl_name)) + if (!decl_name) return 0; if (cpp_check) @@ -3018,7 +3032,12 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) else if (is_assignment_operator) print_assignment_operator (buffer, t, type); else - dump_ada_decl_name (buffer, t, false); + { + const unsigned int suffix = overloading_index (decl_name); + pp_ada_tree_identifier (buffer, decl_name, t, false); + if (suffix > 1) + pp_decimal_int (buffer, suffix); + } dump_ada_function_declaration (buffer, t, is_method, is_constructor, is_destructor, spc); @@ -3171,7 +3190,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) && TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE)) dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true); else if (type) - dump_anonymous_type_name (buffer, TREE_TYPE (t), type); + dump_anonymous_type_name (buffer, TREE_TYPE (t)); } } @@ -3477,9 +3496,15 @@ dump_ada_specs (void (*collect_all_refs)(const char *), { bitmap_obstack_initialize (NULL); + overloaded_names = init_overloaded_names (); + /* Iterate over the list of files to dump specs for. */ for (int i = 0; i < source_refs_used; i++) - dump_ads (source_refs[i], collect_all_refs, check); + { + dumped_anonymous_types = BITMAP_ALLOC (NULL); + dump_ads (source_refs[i], collect_all_refs, check); + BITMAP_FREE (dumped_anonymous_types); + } /* Free various tables. */ free (source_refs); diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b6f76b3..3a7e3d4 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2021-06-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/100859 + * c-typeck.c (c_finish_omp_clauses): Move OMP_CLAUSE_AFFINITY + after depend only cases. + 2021-05-31 Richard Biener <rguenther@suse.de> PR c++/88601 diff --git a/gcc/calls.c b/gcc/calls.c index dd8ff2a..a7c78ed 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1276,19 +1276,20 @@ get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2], wide_int min, max; enum value_range_kind range_type; + if (!query) + query = get_global_range_query (); + if (integral) { value_range vr; - if (query && query->range_of_expr (vr, exp, stmt)) - { - if (vr.undefined_p ()) - vr.set_varying (TREE_TYPE (exp)); - range_type = vr.kind (); - min = wi::to_wide (vr.min ()); - max = wi::to_wide (vr.max ()); - } - else - range_type = determine_value_range (exp, &min, &max); + + query->range_of_expr (vr, exp, stmt); + + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (exp)); + range_type = vr.kind (); + min = wi::to_wide (vr.min ()); + max = wi::to_wide (vr.max ()); } else range_type = VR_VARYING; diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c index 86674dd..6a11902 100644 --- a/gcc/common/config/arc/arc-common.c +++ b/gcc/common/config/arc/arc-common.c @@ -62,7 +62,6 @@ static const struct default_options arc_option_optimization_table[] = { OPT_LEVELS_SIZE, OPT_fif_conversion, NULL, 0 }, { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, { OPT_LEVELS_3_PLUS_SPEED_ONLY, OPT_msize_level_, NULL, 0 }, - { OPT_LEVELS_3_PLUS_SPEED_ONLY, OPT_malign_call, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; diff --git a/gcc/config.gcc b/gcc/config.gcc index 92fad8e..6833a6c 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -4605,14 +4605,7 @@ case "${target}" in tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=0" ;; ""|default) - case "${target}" in - riscv*-*-elf*) - tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=1" - ;; - *) - tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=0" - ;; - esac + tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=1" ;; *) echo "--with-riscv-attribute=${with_riscv_attribute} is not supported. The argument must begin with yes, no or default." 1>&2 diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 9153f05..0d34c96 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -1451,8 +1451,10 @@ arc_override_options (void) if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX)) flag_delayed_branch = 0; - /* Millicode thunks doesn't work with long calls. */ - if (TARGET_LONG_CALLS_SET) + /* Millicode thunks doesn't work for long calls. */ + if (TARGET_LONG_CALLS_SET + /* neither for RF16. */ + || TARGET_RF16) target_flags &= ~MASK_MILLICODE_THUNK_SET; /* Set unaligned to all HS cpus. */ @@ -9868,29 +9870,6 @@ gen_acc2 (void) return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56); } -/* FIXME: a parameter should be added, and code added to final.c, - to reproduce this functionality in shorten_branches. */ -#if 0 -/* Return nonzero iff BRANCH should be unaligned if possible by upsizing - a previous instruction. */ -int -arc_unalign_branch_p (rtx branch) -{ - rtx note; - - if (!TARGET_UNALIGN_BRANCH) - return 0; - /* Do not do this if we have a filled delay slot. */ - if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES - && !NEXT_INSN (branch)->deleted ()) - return 0; - note = find_reg_note (branch, REG_BR_PROB, 0); - return (!note - || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note)) - || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold); -} -#endif - /* When estimating sizes during arc_reorg, when optimizing for speed, there are three reasons why we need to consider branches to be length 6: - annull-false delay slot insns are implemented using conditional execution, diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 252241a..0224ae6 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -115,8 +115,6 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); /* Run-time compilation parameters selecting different hardware subsets. */ -#define TARGET_MIXED_CODE (TARGET_MIXED_CODE_SET) - #define TARGET_SPFP (TARGET_SPFP_FAST_SET || TARGET_SPFP_COMPACT_SET) #define TARGET_DPFP (TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET \ || TARGET_FP_DP_AX) @@ -571,7 +569,7 @@ extern enum reg_class arc_regno_reg_class[]; a scale factor or added to another register (as well as added to a displacement). */ -#define INDEX_REG_CLASS (TARGET_MIXED_CODE ? ARCOMPACT16_REGS : GENERAL_REGS) +#define INDEX_REG_CLASS GENERAL_REGS /* The class value for valid base registers. A base register is one used in an address which is the register value plus a displacement. */ diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index a67bb58..de61b2b 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -2011,14 +2011,6 @@ core_3, archs4x, archs4xd, archs4xd_slow" ;; Absolute instructions -(define_insn "*abssi2_mixed" - [(set (match_operand:SI 0 "compact_register_operand" "=q") - (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))] - "TARGET_MIXED_CODE" - "abs%? %0,%1%&" - [(set_attr "type" "two_cycle_core") - (set_attr "iscompact" "true")]) - (define_insn "abssi2" [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w") (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))] diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt index 85688d5..a8935db 100644 --- a/gcc/config/arc/arc.opt +++ b/gcc/config/arc/arc.opt @@ -136,12 +136,8 @@ Target Mask(CODE_DENSITY) Enable code density instructions for ARCv2. mmixed-code -Target Mask(MIXED_CODE_SET) -Tweak register allocation to help 16-bit instruction generation. -; originally this was: -;Generate ARCompact 16-bit instructions intermixed with 32-bit instructions -; but we do that without -mmixed-code, too, it's just a different instruction -; count / size tradeoff. +Target Ignore +Does nothing. Preserved for backward compatibility. ; We use an explict definition for the negative form because that is the ; actually interesting option, and we want that to have its own comment. @@ -292,11 +288,9 @@ mmul32x16 Target Mask(MULMAC_32BY16_SET) Generate 32x16 multiply and mac instructions. -; the initializer is supposed to be: Init(REG_BR_PROB_BASE/2) , -; alas, basic-block.h is not included in options.c . munalign-prob-threshold= -Target RejectNegative Joined UInteger Var(arc_unalign_prob_threshold) Init(10000/2) -Set probability threshold for unaligning branches. +Target Ignore +Does nothing. Preserved for backward compatibility. mmedium-calls Target Var(TARGET_MEDIUM_CALLS) Init(TARGET_MMEDIUM_CALLS_DEFAULT) @@ -307,8 +301,8 @@ Target Var(TARGET_ANNOTATE_ALIGN) Explain what alignment considerations lead to the decision to make an insn short or long. malign-call -Target Var(TARGET_ALIGN_CALL) -Do alignment optimizations for call instructions. +Target Ignore +Does nothing. Preserved for backward compatibility. mRcq Target Var(TARGET_Rcq) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 0a6ba80..0bfa6a9 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -269,8 +269,7 @@ (define_insn "mve_vabsq_f<mode>" [ (set (match_operand:MVE_0 0 "s_register_operand" "=w") - (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w")] - VABSQ_F)) + (abs:MVE_0 (match_operand:MVE_0 1 "s_register_operand" "w"))) ] "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT" "vabs.f%#<V_sz_elem> %q0, %q1" @@ -481,8 +480,7 @@ (define_insn "mve_vabsq_s<mode>" [ (set (match_operand:MVE_2 0 "s_register_operand" "=w") - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w")] - VABSQ_S)) + (abs:MVE_2 (match_operand:MVE_2 1 "s_register_operand" "w"))) ] "TARGET_HAVE_MVE" "vabs.s%#<V_sz_elem>\t%q0, %q1" diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 6a65733..077c62f 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -739,7 +739,7 @@ [(set_attr "type" "neon_move<q>")] ) -(define_insn "abs<mode>2" +(define_insn "neon_abs<mode>2" [(set (match_operand:VDQW 0 "s_register_operand" "=w") (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))] "TARGET_NEON" diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 0778db1..ed1bc29 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -538,7 +538,6 @@ VRNDAQ_F VREV64Q_F VDUPQ_N_F - VABSQ_F VREV32Q_F VCVTTQ_F32_F16 VCVTBQ_F32_F16 @@ -562,7 +561,6 @@ VCLSQ_S VADDVQ_S VADDVQ_U - VABSQ_S VREV32Q_U VREV32Q_S VMOVLTQ_U diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md index 8e35151..80b2732 100644 --- a/gcc/config/arm/vec-common.md +++ b/gcc/config/arm/vec-common.md @@ -208,9 +208,9 @@ "ARM_HAVE_<MODE>_ARITH && !TARGET_REALLY_IWMMXT" ) -(define_expand "neg<mode>2" +(define_expand "<absneg_str><mode>2" [(set (match_operand:VDQWH 0 "s_register_operand" "") - (neg:VDQWH (match_operand:VDQWH 1 "s_register_operand" "")))] + (ABSNEG:VDQWH (match_operand:VDQWH 1 "s_register_operand" "")))] "ARM_HAVE_<MODE>_ARITH && !TARGET_REALLY_IWMMXT" ) diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index 7de0ec6..d5a3c70 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -1311,7 +1311,7 @@ && (INTVAL (operands[3]) == 2 || INTVAL (operands[3]) == 4) && (reload_in_progress || reload_completed)" "#" - "" + "&& 1" [(set (match_dup 0) (plus:SI (ashift:SI (match_dup 2) (match_dup 3)) (match_dup 1)))] "operands[3] = operands[3] == const2_rtx ? const1_rtx : const2_rtx;") diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 4185f58..eb7cdb0 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -14968,6 +14968,7 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) return; case E_V8HImode: + case E_V2HImode: use_vec_merge = TARGET_SSE2; break; case E_V4HImode: @@ -14975,6 +14976,7 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) break; case E_V16QImode: + case E_V4QImode: use_vec_merge = TARGET_SSE4_1; break; @@ -15274,6 +15276,7 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) break; case E_V8HImode: + case E_V2HImode: use_vec_extr = TARGET_SSE2; break; case E_V4HImode: @@ -15294,6 +15297,9 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) return; } break; + case E_V4QImode: + use_vec_extr = TARGET_SSE4_1; + break; case E_V8SFmode: if (TARGET_AVX) diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index f39e062..914e5e9 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -3092,7 +3092,7 @@ [(match_operand:V8QI 0 "register_operand") (match_operand:QI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX || TARGET_MMX_WITH_SSE" + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" { ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1], INTVAL (operands[2])); @@ -3103,7 +3103,7 @@ [(match_operand:QI 0 "register_operand") (match_operand:V8QI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX || TARGET_MMX_WITH_SSE" + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" { ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0], operands[1], INTVAL (operands[2])); @@ -3120,6 +3120,178 @@ DONE; }) +(define_insn "*pinsrw" + [(set (match_operand:V2HI 0 "register_operand" "=x,YW") + (vec_merge:V2HI + (vec_duplicate:V2HI + (match_operand:HI 2 "nonimmediate_operand" "rm,rm")) + (match_operand:V2HI 1 "register_operand" "0,YW") + (match_operand:SI 3 "const_int_operand")))] + "TARGET_SSE2 + && ((unsigned) exact_log2 (INTVAL (operands[3])) + < GET_MODE_NUNITS (V2HImode))" +{ + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); + switch (which_alternative) + { + case 1: + if (MEM_P (operands[2])) + return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}"; + else + return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}"; + case 0: + if (MEM_P (operands[2])) + return "pinsrw\t{%3, %2, %0|%0, %2, %3}"; + else + return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}"; + default: + gcc_unreachable (); + } +} + [(set_attr "isa" "noavx,avx") + (set_attr "type" "sselog") + (set_attr "length_immediate" "1") + (set_attr "mode" "TI")]) + +(define_insn "*pinsrb" + [(set (match_operand:V4QI 0 "register_operand" "=x,YW") + (vec_merge:V4QI + (vec_duplicate:V4QI + (match_operand:QI 2 "nonimmediate_operand" "rm,rm")) + (match_operand:V4QI 1 "register_operand" "0,YW") + (match_operand:SI 3 "const_int_operand")))] + "TARGET_SSE4_1 + && ((unsigned) exact_log2 (INTVAL (operands[3])) + < GET_MODE_NUNITS (V4QImode))" +{ + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); + switch (which_alternative) + { + case 1: + if (MEM_P (operands[2])) + return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}"; + else + return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}"; + case 0: + if (MEM_P (operands[2])) + return "pinsrb\t{%3, %2, %0|%0, %2, %3}"; + else + return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}"; + default: + gcc_unreachable (); + } +} + [(set_attr "isa" "noavx,avx") + (set_attr "type" "sselog") + (set_attr "prefix_data16" "1") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "orig,vex") + (set_attr "mode" "TI")]) + +(define_insn "*pextrw" + [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,m") + (vec_select:HI + (match_operand:V2HI 1 "register_operand" "YW,YW") + (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n,n")])))] + "TARGET_SSE2" + "@ + %vpextrw\t{%2, %1, %k0|%k0, %1, %2} + %vpextrw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,sse4") + (set_attr "type" "sselog1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "*pextrw_zext" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (zero_extend:SWI48 + (vec_select:HI + (match_operand:V2HI 1 "register_operand" "YW") + (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")]))))] + "TARGET_SSE2" + "%vpextrw\t{%2, %1, %k0|%k0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "*pextrb" + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m") + (vec_select:QI + (match_operand:V4QI 1 "register_operand" "YW,YW") + (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")])))] + "TARGET_SSE4_1" + "@ + %vpextrb\t{%2, %1, %k0|%k0, %1, %2} + %vpextrb\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_data16" "1") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "*pextrb_zext" + [(set (match_operand:SWI248 0 "register_operand" "=r") + (zero_extend:SWI248 + (vec_select:QI + (match_operand:V4QI 1 "register_operand" "YW") + (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))] + "TARGET_SSE4_1" + "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_data16" "1") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_expand "vec_setv2hi" + [(match_operand:V2HI 0 "register_operand") + (match_operand:HI 1 "register_operand") + (match_operand 2 "const_int_operand")] + "TARGET_SSE2" +{ + ix86_expand_vector_set (false, operands[0], operands[1], + INTVAL (operands[2])); + DONE; +}) + +(define_expand "vec_extractv2hihi" + [(match_operand:HI 0 "register_operand") + (match_operand:V2HI 1 "register_operand") + (match_operand 2 "const_int_operand")] + "TARGET_SSE2" +{ + ix86_expand_vector_extract (false, operands[0], + operands[1], INTVAL (operands[2])); + DONE; +}) + +(define_expand "vec_setv4qi" + [(match_operand:V4QI 0 "register_operand") + (match_operand:QI 1 "register_operand") + (match_operand 2 "const_int_operand")] + "TARGET_SSE4_1" +{ + ix86_expand_vector_set (false, operands[0], operands[1], + INTVAL (operands[2])); + DONE; +}) + +(define_expand "vec_extractv4qiqi" + [(match_operand:QI 0 "register_operand") + (match_operand:V4QI 1 "register_operand") + (match_operand 2 "const_int_operand")] + "TARGET_SSE4_1" +{ + ix86_expand_vector_extract (false, operands[0], + operands[1], INTVAL (operands[2])); + DONE; +}) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Miscellaneous diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md index 5191210..e642ff5 100644 --- a/gcc/config/rs6000/fusion.md +++ b/gcc/config/rs6000/fusion.md @@ -1733,10 +1733,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - and %3,%1,%0\;subf %3,%3,%2 - and %3,%1,%0\;subf %3,%3,%2 - and %3,%1,%0\;subf %3,%3,%2 - and %4,%1,%0\;subf %3,%4,%2" + and %3,%1,%0\;subf %3,%2,%3 + and %3,%1,%0\;subf %3,%2,%3 + and %3,%1,%0\;subf %3,%2,%3 + and %4,%1,%0\;subf %3,%2,%4" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1751,10 +1751,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - nand %3,%1,%0\;subf %3,%3,%2 - nand %3,%1,%0\;subf %3,%3,%2 - nand %3,%1,%0\;subf %3,%3,%2 - nand %4,%1,%0\;subf %3,%4,%2" + nand %3,%1,%0\;subf %3,%2,%3 + nand %3,%1,%0\;subf %3,%2,%3 + nand %3,%1,%0\;subf %3,%2,%3 + nand %4,%1,%0\;subf %3,%2,%4" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1769,10 +1769,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - nor %3,%1,%0\;subf %3,%3,%2 - nor %3,%1,%0\;subf %3,%3,%2 - nor %3,%1,%0\;subf %3,%3,%2 - nor %4,%1,%0\;subf %3,%4,%2" + nor %3,%1,%0\;subf %3,%2,%3 + nor %3,%1,%0\;subf %3,%2,%3 + nor %3,%1,%0\;subf %3,%2,%3 + nor %4,%1,%0\;subf %3,%2,%4" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1787,10 +1787,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - or %3,%1,%0\;subf %3,%3,%2 - or %3,%1,%0\;subf %3,%3,%2 - or %3,%1,%0\;subf %3,%3,%2 - or %4,%1,%0\;subf %3,%4,%2" + or %3,%1,%0\;subf %3,%2,%3 + or %3,%1,%0\;subf %3,%2,%3 + or %3,%1,%0\;subf %3,%2,%3 + or %4,%1,%0\;subf %3,%2,%4" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1805,10 +1805,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - and %3,%1,%0\;subf %3,%2,%3 - and %3,%1,%0\;subf %3,%2,%3 - and %3,%1,%0\;subf %3,%2,%3 - and %4,%1,%0\;subf %3,%2,%4" + and %3,%1,%0\;subf %3,%3,%2 + and %3,%1,%0\;subf %3,%3,%2 + and %3,%1,%0\;subf %3,%3,%2 + and %4,%1,%0\;subf %3,%4,%2" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1823,10 +1823,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - nand %3,%1,%0\;subf %3,%2,%3 - nand %3,%1,%0\;subf %3,%2,%3 - nand %3,%1,%0\;subf %3,%2,%3 - nand %4,%1,%0\;subf %3,%2,%4" + nand %3,%1,%0\;subf %3,%3,%2 + nand %3,%1,%0\;subf %3,%3,%2 + nand %3,%1,%0\;subf %3,%3,%2 + nand %4,%1,%0\;subf %3,%4,%2" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1841,10 +1841,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - nor %3,%1,%0\;subf %3,%2,%3 - nor %3,%1,%0\;subf %3,%2,%3 - nor %3,%1,%0\;subf %3,%2,%3 - nor %4,%1,%0\;subf %3,%2,%4" + nor %3,%1,%0\;subf %3,%3,%2 + nor %3,%1,%0\;subf %3,%3,%2 + nor %3,%1,%0\;subf %3,%3,%2 + nor %4,%1,%0\;subf %3,%4,%2" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) @@ -1859,10 +1859,10 @@ (clobber (match_scratch:GPR 4 "=X,X,X,&r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LOGADD)" "@ - or %3,%1,%0\;subf %3,%2,%3 - or %3,%1,%0\;subf %3,%2,%3 - or %3,%1,%0\;subf %3,%2,%3 - or %4,%1,%0\;subf %3,%2,%4" + or %3,%1,%0\;subf %3,%3,%2 + or %3,%1,%0\;subf %3,%3,%2 + or %3,%1,%0\;subf %3,%3,%2 + or %4,%1,%0\;subf %3,%4,%2" [(set_attr "type" "fused_arith_logical") (set_attr "cost" "6") (set_attr "length" "8")]) diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl index 1285dd4..577b955 100755 --- a/gcc/config/rs6000/genfusion.pl +++ b/gcc/config/rs6000/genfusion.pl @@ -166,7 +166,7 @@ sub gen_logical_addsubf $outer_op, $outer_comp, $outer_inv, $outer_rtl, $inner, @inner_ops, $inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4, $bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp, - $target_flag, $ftype, $insn, $is_rsubf, $outer_32, $outer_42, + $target_flag, $ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42, $outer_name, $fuse_type); KIND: foreach $kind ('scalar','vector') { @outer_ops = @logicals; @@ -188,11 +188,10 @@ sub gen_logical_addsubf $c4 = "${constraint},${constraint},${constraint},${constraint}"; OUTER: foreach $outer ( @outer_ops ) { $outer_name = "${vchr}${outer}"; - if ( $outer eq "rsubf" ) { - $is_rsubf = 1; + $is_subf = ( $outer eq "subf" ); + $is_rsubf = ( $outer eq "rsubf" ); + if ( $is_rsubf ) { $outer = "subf"; - } else { - $is_rsubf = 0; } $outer_op = "${vchr}${outer}"; $outer_comp = $complement{$outer}; @@ -241,16 +240,19 @@ sub gen_logical_addsubf if ( ($outer_comp & 2) == 2 ) { $inner_exp = "(not:${mode} $inner_exp)"; } + if ( $is_subf ) { + $outer_32 = "%2,%3"; + $outer_42 = "%2,%4"; + } else { + $outer_32 = "%3,%2"; + $outer_42 = "%4,%2"; + } if ( $is_rsubf == 1 ) { $outer_exp = "(${outer_rtl}:${mode} ${outer_arg2} ${inner_exp})"; - $outer_32 = "%2,%3"; - $outer_42 = "%2,%4"; } else { $outer_exp = "(${outer_rtl}:${mode} ${inner_exp} ${outer_arg2})"; - $outer_32 = "%3,%2"; - $outer_42 = "%4,%2"; } if ( $outer_inv == 1 ) { $outer_exp = "(not:${mode} $outer_exp)"; diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c index f271b0a..b4e13af 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ b/gcc/config/rs6000/rs6000-call.c @@ -6646,7 +6646,9 @@ rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, int *punsignedp ATTRIBUTE_UNUSED, const_tree, int for_return ATTRIBUTE_UNUSED) { - PROMOTE_MODE (mode, *punsignedp, type); + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < (TARGET_32BIT ? 4 : 8)) + mode = TARGET_32BIT ? SImode : DImode; return mode; } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 164d359..a5f7b1d 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -667,17 +667,6 @@ extern unsigned char rs6000_recip_bits[]; /* Target machine storage layout. */ -/* Define this macro if it is advisable to hold scalars in registers - in a wider mode than that declared by the program. In such cases, - the value is constrained to be within the bounds of the declared - type, but kept valid in the wider mode. The signedness of the - extension may differ from that of the type. */ - -#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < (TARGET_32BIT ? 4 : 8)) \ - (MODE) = TARGET_32BIT ? SImode : DImode; - /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ /* That is true on RS/6000. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e40cc6b..6c0f38c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,33 @@ +2021-06-03 Patrick Palka <ppalka@redhat.com> + + PR c++/100592 + * decl.c (make_typename_type): After calling + lookup_template_class, adjust the result to its TYPE_NAME and + then consider the tf_keep_type_decl flag. + +2021-06-03 Patrick Palka <ppalka@redhat.com> + + PR c++/100862 + * pt.c (set_current_access_from_decl): Move to ... + * class.c (set_current_access_from_decl): ... here. + (handle_using_decl): Use it to propagate the access of the + using-enum decl to the copy of the imported enumerator. + * cp-tree.h (set_current_access_from_decl): Declare. + * decl.c (build_enumerator): Simplify using make_temp_override + and set_current_access_from_decl. + +2021-06-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/100859 + * semantics.c (handle_omp_array_sections_1): For + OMP_CLAUSE_{AFFINITY,DEPEND} handle FIELD_DECL base using + finish_non_static_data_member and allow this as base. + (finish_omp_clauses): Move OMP_CLAUSE_AFFINITY + after depend only cases. Let this be diagnosed by !lvalue_p + case for OMP_CLAUSE_{AFFINITY,DEPEND} and remove useless + assert. + * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_AFFINITY. + 2021-06-02 Jason Merrill <jason@redhat.com> PR c++/100838 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 354addd..b53a4db 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -207,6 +207,19 @@ static bool type_maybe_constexpr_default_constructor (tree); static bool type_maybe_constexpr_destructor (tree); static bool field_poverlapping_p (tree); +/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */ + +void +set_current_access_from_decl (tree decl) +{ + if (TREE_PRIVATE (decl)) + current_access_specifier = access_private_node; + else if (TREE_PROTECTED (decl)) + current_access_specifier = access_protected_node; + else + current_access_specifier = access_public_node; +} + /* Return a COND_EXPR that executes TRUE_STMT if this execution of the 'structor is in charge of 'structing virtual bases, or FALSE_STMT otherwise. */ @@ -1359,6 +1372,8 @@ handle_using_decl (tree using_decl, tree t) CONST_DECL_USING_P is true. */ gcc_assert (TREE_CODE (decl) == CONST_DECL); + auto cas = make_temp_override (current_access_specifier); + set_current_access_from_decl (using_decl); tree copy = copy_decl (decl); DECL_CONTEXT (copy) = t; DECL_ARTIFICIAL (copy) = true; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c95a820..b1b7e61 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8186,6 +8186,7 @@ struct atom_hasher : default_hash_traits<tree> extern bool subsumes (tree, tree); /* In class.c */ +extern void set_current_access_from_decl (tree); extern void cp_finish_injected_record_type (tree); /* in vtable-class-hierarchy.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e7268d5..a3687db 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4136,10 +4136,15 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; if (want_template) - return lookup_template_class (t, TREE_OPERAND (fullname, 1), - NULL_TREE, context, - /*entering_scope=*/0, - complain | tf_user); + { + t = lookup_template_class (t, TREE_OPERAND (fullname, 1), + NULL_TREE, context, + /*entering_scope=*/0, + complain | tf_user); + if (t == error_mark_node) + return error_mark_node; + t = TYPE_NAME (t); + } if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) t = TREE_TYPE (t); @@ -16333,17 +16338,9 @@ incremented enumerator value is too large for %<long%>")); For which case we need to make sure that the access of `S::i' matches the access of `S::E'. */ - tree saved_cas = current_access_specifier; - if (TREE_PRIVATE (TYPE_NAME (enumtype))) - current_access_specifier = access_private_node; - else if (TREE_PROTECTED (TYPE_NAME (enumtype))) - current_access_specifier = access_protected_node; - else - current_access_specifier = access_public_node; - + auto cas = make_temp_override (current_access_specifier); + set_current_access_from_decl (TYPE_NAME (enumtype)); finish_member_declaration (decl); - - current_access_specifier = saved_cas; } else pushdecl (decl); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 15ef488..7211bdc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -190,7 +190,6 @@ static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); static bool check_specialization_scope (void); static tree process_partial_specialization (tree); -static void set_current_access_from_decl (tree); static enum template_base_result get_template_base (tree, tree, tree, tree, bool , tree *); static tree try_class_unification (tree, tree, tree, tree, bool); @@ -26432,19 +26431,6 @@ tsubst_initializer_list (tree t, tree argvec) return inits; } -/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */ - -static void -set_current_access_from_decl (tree decl) -{ - if (TREE_PRIVATE (decl)) - current_access_specifier = access_private_node; - else if (TREE_PROTECTED (decl)) - current_access_specifier = access_protected_node; - else - current_access_specifier = access_public_node; -} - /* Instantiate an enumerated type. TAG is the template type, NEWTAG is the instantiation (which should have been created with start_enum) and ARGS are the template arguments to use. */ diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c index 4111cd6..24bd031 100644 --- a/gcc/diagnostic-show-locus.c +++ b/gcc/diagnostic-show-locus.c @@ -2600,9 +2600,11 @@ diagnostic_show_locus (diagnostic_context * context, return; /* Don't print the same source location twice in a row, unless we have - fix-it hints. */ + fix-it hints, or multiple locations, or a label. */ if (loc == context->last_location - && richloc->get_num_fixit_hints () == 0) + && richloc->get_num_fixit_hints () == 0 + && richloc->get_num_locations () == 1 + && richloc->get_range (0)->m_label == NULL) return; context->last_location = loc; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 55e76d5..b0d17ef 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -19218,7 +19218,7 @@ The following options fine tune code generation: @table @gcctabopt @item -malign-call @opindex malign-call -Do alignment optimizations for call instructions. +Does nothing. Preserved for backward compatibility. @item -mauto-modify-reg @opindex mauto-modify-reg @@ -19313,9 +19313,7 @@ code-density feature. @item -mmixed-code @opindex mmixed-code -Tweak register allocation to help 16-bit instruction generation. -This generally has the effect of decreasing the average instruction size -while increasing the instruction count. +Does nothing. Preserved for backward compatibility. @item -mq-class @opindex mq-class @@ -19391,12 +19389,7 @@ normal instruction. @item -munalign-prob-threshold=@var{probability} @opindex munalign-prob-threshold -Set probability threshold for unaligning branches. -When tuning for @samp{ARC700} and optimizing for speed, branches without -filled delay slot are preferably emitted unaligned and long, unless -profiling indicates that the probability for the branch to be taken -is below @var{probability}. @xref{Cross-profiling}. -The default is (REG_BR_PROB_BASE/2), i.e.@: 5000. +Does nothing. Preserved for backward compatibility. @end table diff --git a/gcc/function-tests.c b/gcc/function-tests.c index 1b8f665..0ac1d37 100644 --- a/gcc/function-tests.c +++ b/gcc/function-tests.c @@ -581,6 +581,11 @@ test_ranges () push_cfun (fun); range_tests (); range_op_tests (); + + build_cfg (fndecl); + convert_to_ssa (fndecl); + gimple_range_tests (); + pop_cfun (); } diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index cc27574..c58acf4 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -827,7 +827,7 @@ ranger_cache::range_of_expr (irange &r, tree name, gimple *stmt) { if (!gimple_range_ssa_p (name)) { - get_tree_range (r, name); + get_tree_range (r, name, stmt); return true; } @@ -860,7 +860,7 @@ ranger_cache::range_of_expr (irange &r, tree name, gimple *stmt) } } else - get_tree_range (r, expr); + get_tree_range (r, expr, NULL); return false; } diff --git a/gcc/gimple-range-tests.cc b/gcc/gimple-range-tests.cc new file mode 100644 index 0000000..9ee4c5a --- /dev/null +++ b/gcc/gimple-range-tests.cc @@ -0,0 +1,72 @@ +/* Unit tests for GIMPLE range related routines. + Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#if CHECKING_P + +#include "selftest.h" + +namespace selftest { + +// Test ranges of tree expressions. +class test_expr_eval : public gimple_ranger +{ +public: + test_expr_eval () + { + type = integer_type_node; + op0 = make_ssa_name (type); + op1 = make_ssa_name (type); + + // [5,10] + [15,20] => [20, 30] + tree expr = fold_build2 (PLUS_EXPR, type, op0, op1); + int_range<2> expect (build_int_cst (type, 20), build_int_cst (type, 30)); + int_range_max r; + + ASSERT_TRUE (range_of_expr (r, expr)); + ASSERT_TRUE (r == expect); + } + + virtual bool range_of_expr (irange &r, tree expr, gimple * = NULL) OVERRIDE + { + if (expr == op0) + { + r.set (build_int_cst (type, 5), build_int_cst (type, 10)); + return true; + } + if (expr == op1) + { + r.set (build_int_cst (type, 15), build_int_cst (type, 20)); + return true; + } + return gimple_ranger::range_of_expr (r, expr); + } + +private: + tree op0, op1, type; +}; + +void +gimple_range_tests () +{ + test_expr_eval e; +} + +} // namespace selftest + +#endif // CHECKING_P diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index ed0a0c9..db8419b 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -54,16 +54,6 @@ along with GCC; see the file COPYING3. If not see bool fur_source::get_operand (irange &r, tree expr) { - if (!gimple_range_ssa_p (expr)) - return get_tree_range (r, expr); - - // If no query engine is present, simply get the global value. - if (!m_query) - { - r = gimple_range_global (expr); - return true; - } - // First look for a stmt. if (m_stmt) return m_query->range_of_expr (r, expr, m_stmt); @@ -168,56 +158,6 @@ gimple_range_adjustment (irange &res, const gimple *stmt) } } -// Return a range in R for the tree EXPR. Return true if a range is -// representable, and UNDEFINED/false if not. - -bool -get_tree_range (irange &r, tree expr) -{ - tree type; - if (TYPE_P (expr)) - type = expr; - else - type = TREE_TYPE (expr); - - // Return false if the type isn't suported. - if (!irange::supports_type_p (type)) - { - r.set_undefined (); - return false; - } - - switch (TREE_CODE (expr)) - { - case INTEGER_CST: - if (TREE_OVERFLOW_P (expr)) - expr = drop_tree_overflow (expr); - r.set (expr, expr); - return true; - - case SSA_NAME: - r = gimple_range_global (expr); - return true; - - case ADDR_EXPR: - { - // Handle &var which can show up in phi arguments. - bool ov; - if (tree_single_nonzero_warnv_p (expr, &ov)) - { - r = range_nonzero (type); - return true; - } - break; - } - - default: - break; - } - r.set_varying (type); - return true; -} - // Return the base of the RHS of an assignment. static tree @@ -961,7 +901,7 @@ bool gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt) { if (!gimple_range_ssa_p (expr)) - return get_tree_range (r, expr); + return get_tree_range (r, expr, stmt); // If there is no statement, just get the global value. if (!stmt) @@ -1115,7 +1055,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name) } // This routine will export whatever global ranges are known to GCC -// SSA_RANGE_NAME_INFO fields. +// SSA_RANGE_NAME_INFO and SSA_NAME_PTR_INFO fields. void gimple_ranger::export_global_ranges () @@ -1136,24 +1076,18 @@ gimple_ranger::export_global_ranges () && m_cache.get_global_range (r, name) && !r.varying_p()) { - // Make sure the new range is a subset of the old range. - int_range_max old_range; - old_range = gimple_range_global (name); - old_range.intersect (r); - /* Disable this while we fix tree-ssa/pr61743-2.c. */ - //gcc_checking_assert (old_range == r); - - // WTF? Can't write non-null pointer ranges?? stupid set_range_info! - if (!POINTER_TYPE_P (TREE_TYPE (name)) && !r.undefined_p ()) + bool updated = update_global_range (r, name); + + if (updated && dump_file) { value_range vr = r; - set_range_info (name, vr); - if (dump_file) + print_generic_expr (dump_file, name , TDF_SLIM); + fprintf (dump_file, " --> "); + vr.dump (dump_file); + fprintf (dump_file, "\n"); + int_range_max same = vr; + if (same != r) { - print_generic_expr (dump_file, name , TDF_SLIM); - fprintf (dump_file, " --> "); - vr.dump (dump_file); - fprintf (dump_file, "\n"); fprintf (dump_file, " irange : "); r.dump (dump_file); fprintf (dump_file, "\n"); @@ -1472,3 +1406,5 @@ disable_ranger (struct function *fun) fun->x_range_query = &global_ranges; } + +#include "gimple-range-tests.cc" diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 65f62e4..02b891f 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -159,6 +159,8 @@ inline bool fold_range (irange &r, gimple *s, range_query *q = NULL) { fold_using_range f; + if (q == NULL) + q = get_global_range_query (); fur_source src (q, s); return f.fold_stmt (r, s, src); } @@ -169,13 +171,12 @@ inline bool fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL) { fold_using_range f; + if (q == NULL) + q = get_global_range_query (); fur_source src (q, on_edge); return f.fold_stmt (r, s, src); } -// Calculate a basic range for a tree node expression. -extern bool get_tree_range (irange &r, tree expr); - // These routines provide a GIMPLE interface to the range-ops code. extern tree gimple_range_operand1 (const gimple *s); extern tree gimple_range_operand2 (const gimple *s); diff --git a/gcc/selftest.h b/gcc/selftest.h index e609117..80459d6 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -249,6 +249,7 @@ extern void predict_c_tests (); extern void pretty_print_c_tests (); extern void range_tests (); extern void range_op_tests (); +extern void gimple_range_tests (); extern void read_rtl_function_c_tests (); extern void rtl_tests_c_tests (); extern void sbitmap_c_tests (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8bb582..ac63a14 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,58 @@ +2021-06-03 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100637 + * gcc.target/i386/vperm-v2hi.c: New test. + * gcc.target/i386/vperm-v4qi.c: Ditto. + +2021-06-03 Aldy Hernandez <aldyh@redhat.com> + + * gcc.dg/pr80776-1.c: XFAIL and document the reason why. + +2021-06-03 Patrick Palka <ppalka@redhat.com> + + PR c++/100592 + * g++.dg/cpp0x/alias-decl-71.C: New test. + +2021-06-03 Patrick Palka <ppalka@redhat.com> + + PR c++/100862 + * g++.dg/cpp2a/using-enum-9.C: New test. + +2021-06-03 Andre Vieira <andre.simoesdiasvieira@arm.com> + + * gcc.target/aarch64/sve/part_vect_single_iter_epilog.c: New test. + +2021-06-03 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-vabs.c: New test. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/bit_packed_array6.adb: New test. + * gnat.dg/bit_packed_array6_pkg.ads: New helper. + +2021-06-03 Martin Liska <mliska@suse.cz> + + * gcc.dg/spellcheck-options-23.c: New test. + +2021-06-03 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/inline22.adb: New test. + +2021-06-03 Tamar Christina <tamar.christina@arm.com> + + * gcc.target/aarch64/cpunative/info_16: Update implementer. + * gcc.target/aarch64/cpunative/info_17: Likewise + +2021-06-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/100859 + * g++.dg/gomp/depend-iterator-3.C: New test. + * g++.dg/gomp/this-1.C: Don't expect any diagnostics for + this as base expression of depend array section, expect a different + error wording for this as depend locator and add testcases + for affinity clauses. + 2021-06-02 Jason Merrill <jason@redhat.com> PR c++/100838 diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C new file mode 100644 index 0000000..6a61f93 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C @@ -0,0 +1,13 @@ +// PR c++/100592 +// { dg-do compile { target c++11 } } + +template<bool> +struct meta { + template<class> using if_c = int&; +}; + +template<bool B> +typename meta<B>::template if_c<void> const f(); + +using type = decltype(f<true>()); +using type = int&; diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-9.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-9.C new file mode 100644 index 0000000..3e02605 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-9.C @@ -0,0 +1,28 @@ +// PR c++/100862 +// { dg-do compile { target c++20 } } + +enum class fruit { orange, apple }; + +struct A { +public: + using enum fruit; +private: +}; + +struct B { +protected: + using enum fruit; +public: +}; + +struct C { +private: + using enum fruit; +public: +}; + +int main() { + A::orange, A::apple; + B::orange, B::apple; // { dg-error "protected" } + C::orange, C::apple; // { dg-error "private" } +} diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index f3a120b..eca5e80 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,5 +17,15 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ + + /* Legacy evrp sets the range of i to [0, MAX] *before* the first conditional, + and to [0,999999] *before* the second conditional. This is because both + evrp and VRP use trickery to set global ranges when this particular use of + a __builtin_unreachable is in play (see uses of + assert_unreachable_fallthru_edge_p). + + Setting these ranges at the definition site, causes VRP to remove the + unreachable code altogether, leaving the following sprintf unguarded. This + causes the bogus warning below. */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ } diff --git a/gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c b/gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c new file mode 100644 index 0000000..a03229e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 --param vect-partial-vector-usage=1" } */ + +void +foo (short * __restrict__ a, short * __restrict__ b, short * __restrict__ c, int n) +{ + for (int i = 0; i < n; ++i) + c[i] = a[i] + b[i]; +} + +/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]+.h, wzr, [xw][0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c b/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c new file mode 100644 index 0000000..64cd1c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c @@ -0,0 +1,44 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O3 -funsafe-math-optimizations" } */ + +#include <stdint.h> +#include <arm_mve.h> + +#define ABS(a) ((a < 0) ? -a : a) + +#define FUNC(SIGN, TYPE, BITS, NB, NAME) \ + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, TYPE##BITS##_t *a) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = ABS(a[i]); \ + } \ +} + +#define FUNC_FLOAT(SIGN, TYPE, BITS, NB, NAME) \ + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE * __restrict__ dest, TYPE *a) { \ + int i; \ + for (i=0; i<NB; i++) { \ + dest[i] = ABS(a[i]); \ + } \ +} + +/* 128-bit vectors. */ +FUNC(s, int, 32, 4, vabs) +FUNC(u, uint, 32, 4, vabs) +FUNC(s, int, 16, 8, vabs) +FUNC(u, uint, 16, 8, vabs) +FUNC(s, int, 8, 16, vabs) +FUNC(u, uint, 8, 16, vabs) +FUNC_FLOAT(f, float, 32, 4, vabs) +FUNC(f, float, 16, 8, vabs) + +/* Taking the absolute value of an unsigned value is a no-op, so half of the + integer optimizations actually generate a call to memmove, the other ones a + 'vabs'. */ +/* { dg-final { scan-assembler-times {vabs.s[0-9]+\tq[0-9]+, q[0-9]+} 3 } } */ +/* { dg-final { scan-assembler-times {vabs.f[0-9]+ q[0-9]+, q[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {vldr[bhw].[0-9]+\tq[0-9]+} 5 } } */ +/* { dg-final { scan-assembler-times {vstr[bhw].[0-9]+\tq[0-9]+} 5 } } */ +/* { dg-final { scan-assembler-times {memmove} 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/vperm-v2hi.c b/gcc/testsuite/gcc.target/i386/vperm-v2hi.c new file mode 100644 index 0000000..0af94f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vperm-v2hi.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O -msse2" } */ +/* { dg-require-effective-target sse2 } */ + +#include "isa-check.h" +#include "sse-os-support.h" + +typedef short S; +typedef short V __attribute__((vector_size(4))); +typedef short IV __attribute__((vector_size(4))); +typedef union { S s[2]; V v; } U; + +static U i[2], b, c; + +extern int memcmp (const void *, const void *, __SIZE_TYPE__); +#define assert(T) ((T) || (__builtin_trap (), 0)) + +#define TEST(E0, E1) \ + b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1}); \ + c.s[0] = i[0].s[E0]; \ + c.s[1] = i[0].s[E1]; \ + __asm__("" : : : "memory"); \ + assert (memcmp (&b, &c, sizeof(c)) == 0); + +#include "vperm-2-2.inc" + +int main() +{ + check_isa (); + + if (!sse_os_support ()) + exit (0); + + i[0].s[0] = 0; + i[0].s[1] = 1; + i[0].s[2] = 2; + i[0].s[3] = 3; + + check(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/vperm-v4qi.c b/gcc/testsuite/gcc.target/i386/vperm-v4qi.c new file mode 100644 index 0000000..57fa547 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vperm-v4qi.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ +/* { dg-options "-O -msse2" } */ +/* { dg-require-effective-target sse2 } */ + +#include "isa-check.h" +#include "sse-os-support.h" + +typedef char S; +typedef char V __attribute__((vector_size(4))); +typedef char IV __attribute__((vector_size(4))); +typedef union { S s[4]; V v; } U; + +static U i[2], b, c; + +extern int memcmp (const void *, const void *, __SIZE_TYPE__); +#define assert(T) ((T) || (__builtin_trap (), 0)) + +#define TEST(E0, E1, E2, E3) \ + b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \ + c.s[0] = i[0].s[E0]; \ + c.s[1] = i[0].s[E1]; \ + c.s[2] = i[0].s[E2]; \ + c.s[3] = i[0].s[E3]; \ + __asm__("" : : : "memory"); \ + assert (memcmp (&b, &c, sizeof(c)) == 0); + +#include "vperm-4-2.inc" + +int main() +{ + check_isa (); + + if (!sse_os_support ()) + exit (0); + + i[0].s[0] = 0; + i[0].s[1] = 1; + i[0].s[2] = 2; + i[0].s[3] = 3; + i[0].s[4] = 4; + i[0].s[5] = 5; + i[0].s[6] = 6; + i[0].s[7] = 7; + + check(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/not-promote-mode.c b/gcc/testsuite/gcc.target/powerpc/not-promote-mode.c new file mode 100644 index 0000000..29af1f8 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/not-promote-mode.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O2" } */ + +extern void bar (); + +void foo () +{ + int i; + for (i = 0; i < 10000; i++) + bar (); +} + +/* { dg-final { scan-assembler-not {\mrldicl\M} } } */ diff --git a/gcc/testsuite/gnat.dg/bit_packed_array6.adb b/gcc/testsuite/gnat.dg/bit_packed_array6.adb new file mode 100644 index 0000000..84f7a4b --- /dev/null +++ b/gcc/testsuite/gnat.dg/bit_packed_array6.adb @@ -0,0 +1,10 @@ +-- { dg-do run } +-- { dg-options "-O2 -gnata -gnatVa" } + +with Bit_Packed_Array6_Pkg; use Bit_Packed_Array6_Pkg; + +procedure Bit_Packed_Array6 is + B : constant Boolean := Everywhere (K_Configuration); +begin + null; +end; diff --git a/gcc/testsuite/gnat.dg/bit_packed_array6_pkg.ads b/gcc/testsuite/gnat.dg/bit_packed_array6_pkg.ads new file mode 100644 index 0000000..4eb1516 --- /dev/null +++ b/gcc/testsuite/gnat.dg/bit_packed_array6_pkg.ads @@ -0,0 +1,13 @@ +package Bit_Packed_Array6_Pkg is + + type Project_Kind is + (K_Configuration, K_Abstract, + K_Standard, K_Library, K_Aggregate, K_Aggregate_Library); + + type Projects_Kind is array (Project_Kind) of Boolean + with Pack, + Dynamic_Predicate => Projects_Kind /= (Project_Kind => False); + + Everywhere : constant Projects_Kind := (others => True); + +end Bit_Packed_Array6_Pkg; diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c index b273adb..a65719d 100644 --- a/gcc/tree-affine.c +++ b/gcc/tree-affine.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "dumpfile.h" #include "cfgexpand.h" +#include "value-query.h" /* Extends CST as appropriate for the affine combinations COMB. */ @@ -345,11 +346,15 @@ expr_to_aff_combination (aff_tree *comb, tree_code code, tree type, for below case: (T1)(X *+- CST) -> (T1)X *+- (T1)CST if X *+- CST doesn't overflow by range information. */ + value_range vr; if (TYPE_UNSIGNED (itype) && TYPE_OVERFLOW_WRAPS (itype) && TREE_CODE (op1) == INTEGER_CST - && determine_value_range (op0, &minv, &maxv) == VR_RANGE) + && get_range_query (cfun)->range_of_expr (vr, op0) + && vr.kind () == VR_RANGE) { + wide_int minv = vr.lower_bound (); + wide_int maxv = vr.upper_bound (); wi::overflow_type overflow = wi::OVF_NONE; signop sign = UNSIGNED; if (icode == PLUS_EXPR) diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 09d4667..b1f6468 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1069,12 +1069,12 @@ split_constant_offset (tree exp, tree *var, tree *off, value_range *exp_range, if (INTEGRAL_TYPE_P (type)) *var = fold_convert (sizetype, *var); *off = ssize_int (0); - if (exp_range && code != SSA_NAME) - { - wide_int var_min, var_max; - if (determine_value_range (exp, &var_min, &var_max) == VR_RANGE) - *exp_range = value_range (type, var_min, var_max); - } + + value_range r; + if (exp_range && code != SSA_NAME + && get_range_query (cfun)->range_of_expr (r, exp) + && !r.undefined_p ()) + *exp_range = r; } /* Expresses EXP as VAR + OFF, where OFF is a constant. VAR has the same diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index ff7673d..ba36348 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -9740,12 +9740,31 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call) /* In these calculations the "- 1" converts loop iteration counts back to latch counts. */ if (loop->any_upper_bound) - loop->nb_iterations_upper_bound - = (final_iter_may_be_partial - ? wi::udiv_ceil (loop->nb_iterations_upper_bound + bias_for_lowest, - lowest_vf) - 1 - : wi::udiv_floor (loop->nb_iterations_upper_bound + bias_for_lowest, - lowest_vf) - 1); + { + loop_vec_info main_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo); + loop->nb_iterations_upper_bound + = (final_iter_may_be_partial + ? wi::udiv_ceil (loop->nb_iterations_upper_bound + bias_for_lowest, + lowest_vf) - 1 + : wi::udiv_floor (loop->nb_iterations_upper_bound + bias_for_lowest, + lowest_vf) - 1); + if (main_vinfo) + { + unsigned int bound; + poly_uint64 main_iters + = upper_bound (LOOP_VINFO_VECT_FACTOR (main_vinfo), + LOOP_VINFO_COST_MODEL_THRESHOLD (main_vinfo)); + main_iters + = upper_bound (main_iters, + LOOP_VINFO_VERSIONING_THRESHOLD (main_vinfo)); + if (can_div_away_from_zero_p (main_iters, + LOOP_VINFO_VECT_FACTOR (loop_vinfo), + &bound)) + loop->nb_iterations_upper_bound + = wi::umin ((widest_int) (bound - 1), + loop->nb_iterations_upper_bound); + } + } if (loop->any_likely_upper_bound) loop->nb_iterations_likely_upper_bound = (final_iter_may_be_partial diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 450926d..b9c0e65 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4606,59 +4606,3 @@ make_pass_vrp (gcc::context *ctxt) { return new pass_vrp (ctxt); } - - -/* Worker for determine_value_range. */ - -static void -determine_value_range_1 (value_range *vr, tree expr) -{ - if (BINARY_CLASS_P (expr)) - { - value_range vr0, vr1; - determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); - determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1)); - range_fold_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr), - &vr0, &vr1); - } - else if (UNARY_CLASS_P (expr)) - { - value_range vr0; - determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); - range_fold_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr), - &vr0, TREE_TYPE (TREE_OPERAND (expr, 0))); - } - else if (TREE_CODE (expr) == INTEGER_CST) - vr->set (expr); - else - { - value_range r; - /* For SSA names try to extract range info computed by VRP. Otherwise - fall back to varying. */ - if (TREE_CODE (expr) == SSA_NAME - && INTEGRAL_TYPE_P (TREE_TYPE (expr)) - && get_range_query (cfun)->range_of_expr (r, expr) - && !r.undefined_p ()) - *vr = r; - else - vr->set_varying (TREE_TYPE (expr)); - } -} - -/* Compute a value-range for EXPR and set it in *MIN and *MAX. Return - the determined range type. */ - -value_range_kind -determine_value_range (tree expr, wide_int *min, wide_int *max) -{ - value_range vr; - determine_value_range_1 (&vr, expr); - if (!vr.varying_p () && vr.constant_p ()) - { - *min = wi::to_wide (vr.min ()); - *max = wi::to_wide (vr.max ()); - return vr.kind (); - } - - return VR_VARYING; -} diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h index 989d843..3392ecc 100644 --- a/gcc/tree-vrp.h +++ b/gcc/tree-vrp.h @@ -62,7 +62,6 @@ extern bool find_case_label_index (gswitch *, size_t, tree, size_t *); extern bool overflow_comparison_p (tree_code, tree, tree, bool, tree *); extern tree get_single_symbol (tree, bool *, tree *); extern void maybe_set_nonzero_bits (edge, tree); -extern value_range_kind determine_value_range (tree, wide_int *, wide_int *); extern wide_int masked_increment (const wide_int &val_in, const wide_int &mask, const wide_int &sgnbit, unsigned int prec); diff --git a/gcc/value-query.cc b/gcc/value-query.cc index f8b457d..821f224 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -182,6 +182,86 @@ range_query::~range_query () delete equiv_alloc; } +// Return a range in R for the tree EXPR. Return true if a range is +// representable, and UNDEFINED/false if not. + +bool +range_query::get_tree_range (irange &r, tree expr, gimple *stmt) +{ + tree type; + if (TYPE_P (expr)) + type = expr; + else + type = TREE_TYPE (expr); + + if (!irange::supports_type_p (type)) + { + r.set_undefined (); + return false; + } + if (expr == type) + { + r.set_varying (type); + return true; + } + switch (TREE_CODE (expr)) + { + case INTEGER_CST: + if (TREE_OVERFLOW_P (expr)) + expr = drop_tree_overflow (expr); + r.set (expr, expr); + return true; + + case SSA_NAME: + r = gimple_range_global (expr); + return true; + + case ADDR_EXPR: + { + // Handle &var which can show up in phi arguments. + bool ov; + if (tree_single_nonzero_warnv_p (expr, &ov)) + { + r = range_nonzero (type); + return true; + } + break; + } + + default: + break; + } + if (BINARY_CLASS_P (expr)) + { + range_operator *op = range_op_handler (TREE_CODE (expr), type); + if (op) + { + int_range_max r0, r1; + range_of_expr (r0, TREE_OPERAND (expr, 0), stmt); + range_of_expr (r1, TREE_OPERAND (expr, 1), stmt); + op->fold_range (r, type, r0, r1); + } + else + r.set_varying (type); + return true; + } + if (UNARY_CLASS_P (expr)) + { + range_operator *op = range_op_handler (TREE_CODE (expr), type); + if (op) + { + int_range_max r0; + range_of_expr (r0, TREE_OPERAND (expr, 0), stmt); + op->fold_range (r, type, r0, int_range<1> (type)); + } + else + r.set_varying (type); + return true; + } + r.set_varying (type); + return true; +} + // Return the range for NAME from SSA_NAME_RANGE_INFO. static inline void @@ -224,6 +304,45 @@ get_ssa_name_ptr_info_nonnull (const_tree name) return !pi->pt.null; } +// Update the global range for NAME into the SSA_RANGE_NAME_INFO and +// SSA_NAME_PTR_INFO fields. Return TRUE if the range for NAME was +// updated. + +bool +update_global_range (irange &r, tree name) +{ + tree type = TREE_TYPE (name); + + if (r.undefined_p () || r.varying_p ()) + return false; + + if (INTEGRAL_TYPE_P (type)) + { + // If a global range already exists, incorporate it. + if (SSA_NAME_RANGE_INFO (name)) + { + value_range glob; + get_ssa_name_range_info (glob, name); + r.intersect (glob); + } + if (r.undefined_p ()) + return false; + + value_range vr = r; + set_range_info (name, vr); + return true; + } + else if (POINTER_TYPE_P (type)) + { + if (r.nonzero_p ()) + { + set_ptr_nonnull (name); + return true; + } + } + return false; +} + // Return the legacy global range for NAME if it has one, otherwise // return VARYING. @@ -316,12 +435,12 @@ get_global_range_query () } bool -global_range_query::range_of_expr (irange &r, tree expr, gimple *) +global_range_query::range_of_expr (irange &r, tree expr, gimple *stmt) { tree type = TREE_TYPE (expr); if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr)) - return get_tree_range (r, expr); + return get_tree_range (r, expr, stmt); get_range_global (r, expr); diff --git a/gcc/value-query.h b/gcc/value-query.h index 97da663..77e49e9 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -100,6 +100,8 @@ public: protected: class value_range_equiv *allocate_value_range_equiv (); void free_value_range_equiv (class value_range_equiv *); + bool get_tree_range (irange &r, tree expr, gimple *stmt); + bool get_arith_expr_range (irange &r, tree expr, gimple *stmt); private: class equiv_allocator *equiv_alloc; @@ -115,5 +117,6 @@ public: extern global_range_query global_ranges; extern value_range gimple_range_global (tree name); +extern bool update_global_range (irange &r, tree name); #endif // GCC_QUERY_H diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 3d0be8e..509c8b0 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -180,7 +180,7 @@ bool vr_values::range_of_expr (irange &r, tree expr, gimple *stmt) { if (!gimple_range_ssa_p (expr)) - return get_tree_range (r, expr); + return get_tree_range (r, expr, stmt); if (const value_range *vr = get_value_range (expr, stmt)) { |