From 592ed7db12ed0d6c71bca0cbfef6dcdf383bc24f Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Thu, 3 Jun 2021 13:44:53 +0300 Subject: arc: Remove obsolete options Remove the following obsolete options: - munalign-prob-threshold - malign-call - mmixed-code The ARC's options are marked as obsolete and ignored for backwards compatibility. gcc/ 2021-06-03 Claudiu Zissulescu * 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. Signed-off-by: Claudiu Zissulescu --- gcc/common/config/arc/arc-common.c | 1 - gcc/config/arc/arc.c | 23 ----------------------- gcc/config/arc/arc.h | 4 +--- gcc/config/arc/arc.md | 8 -------- gcc/config/arc/arc.opt | 18 ++++++------------ gcc/doc/invoke.texi | 13 +++---------- 6 files changed, 10 insertions(+), 57 deletions(-) (limited to 'gcc') 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/arc/arc.c b/gcc/config/arc/arc.c index 9153f05..b77d056 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -9868,29 +9868,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/doc/invoke.texi b/gcc/doc/invoke.texi index 08c3206..eb8142f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -19255,7 +19255,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 @@ -19350,9 +19350,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 @@ -19428,12 +19426,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 -- cgit v1.1 From 1eff5289b273041c9d71a4829c2600d283186ab6 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 3 Jun 2021 13:29:32 +0200 Subject: Fix miscompilation of predicate on bit-packed array types This is a regression present on the mainline and 11 branch in the form of a miscompilation by the new mod/ref IPA pass of code that passes constrained bit-packed array objets in a call to a subprograms taking unconstrained bit-packed array parameters, which occurs for predicate on bit-packed array types for example. gcc/ada/ * gcc-interface/decl.c (gnat_to_gnu_entity) : 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. : Add PAT local constant and use it throughout. gcc/testsuite/ * gnat.dg/bit_packed_array6.adb: New test. * gnat.dg/bit_packed_array6_pkg.ads: New helper. --- gcc/ada/gcc-interface/decl.c | 37 +++++++++++++++---------- gcc/testsuite/gnat.dg/bit_packed_array6.adb | 10 +++++++ gcc/testsuite/gnat.dg/bit_packed_array6_pkg.ads | 13 +++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/bit_packed_array6.adb create mode 100644 gcc/testsuite/gnat.dg/bit_packed_array6_pkg.ads (limited to 'gcc') 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/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; -- cgit v1.1 From f4242710c7966a965bbd14cd50ecdba28fd5717e Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Thu, 3 Jun 2021 12:06:38 +0000 Subject: arm: Auto-vectorization for MVE: vabs This patch adds support for auto-vectorization of absolute value computation using vabs. We use a similar pattern to what is used in neon.md and extend the existing neg2 expander to match both 'neg' and 'abs'. This implies renaming the existing abs2 define_insn in neon.md to avoid a clash with the new expander with the same name. 2021-06-03 Christophe Lyon gcc/ * config/arm/mve.md (mve_vabsq_f): Use 'abs' instead of unspec. (mve_vabsq_s): Likewise. * config/arm/neon.md (abs2): Rename to neon_abs2. * config/arm/unspecs.md (VABSQ_F, VABSQ_S): Delete. * config/arm/vec-common.md (neg2): Rename to 2. gcc/testsuite/ * gcc.target/arm/simd/mve-vabs.c: New test. --- gcc/config/arm/mve.md | 6 ++-- gcc/config/arm/neon.md | 2 +- gcc/config/arm/unspecs.md | 2 -- gcc/config/arm/vec-common.md | 4 +-- gcc/testsuite/gcc.target/arm/simd/mve-vabs.c | 44 ++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/simd/mve-vabs.c (limited to 'gcc') 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" [ (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%# %q0, %q1" @@ -481,8 +480,7 @@ (define_insn "mve_vabsq_s" [ (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%#\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")] ) -(define_insn "abs2" +(define_insn "neon_abs2" [(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__ARITH && !TARGET_REALLY_IWMMXT" ) -(define_expand "neg2" +(define_expand "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__ARITH && !TARGET_REALLY_IWMMXT" ) 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 +#include + +#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 Date: Thu, 3 Jun 2021 13:55:24 +0100 Subject: vect: Use main loop's thresholds and VF to narrow upper_bound of epilogue This patch uses the knowledge of the conditions to enter an epilogue loop to help come up with a potentially more restricive upper bound. gcc/ChangeLog: * tree-vect-loop.c (vect_transform_loop): Use main loop's various' thresholds to narrow the upper bound on epilogue iterations. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve/part_vect_single_iter_epilog.c: New test. --- .../aarch64/sve/part_vect_single_iter_epilog.c | 11 ++++++++ gcc/tree-vect-loop.c | 31 +++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c (limited to 'gcc') 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/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 -- cgit v1.1 From 69f517ac20566a645ff41a9bfca535822205a538 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 3 Jun 2021 09:37:11 -0400 Subject: c++: using-enum and access specifiers [PR100862] When copying the enumerators imported by a class-scope using-enum declaration, we need to override current_access_specifier so that finish_member_declaration gives the copies the same access as the using-enum decl. (A class-scope using-enum is processed late, so current_access_specifier at this point is otherwise set to the last access specifier within the class.) To that end, this patch makes handle_using_decl call set_current_access_from_decl accordingly. For consistency, this patch makes build_enumerator use set_current_access_from_decl too. PR c++/100862 gcc/cp/ChangeLog: * 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. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/using-enum-9.C: New test. --- gcc/cp/class.c | 15 +++++++++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 12 ++---------- gcc/cp/pt.c | 14 -------------- gcc/testsuite/g++.dg/cpp2a/using-enum-9.C | 28 ++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/using-enum-9.C (limited to 'gcc') 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 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..fb21a3a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -16333,17 +16333,9 @@ incremented enumerator value is too large for %")); 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/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" } +} -- cgit v1.1 From d999d9b7e53b9a9cd2004a19e84c637e5e5013f5 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 3 Jun 2021 09:39:13 -0400 Subject: c++: cv-qualified dependent name of alias tmpl [PR100592] Here, the dependent template name in the return type of f() resolves to an alias of int& after substitution, and we end up complaining about qualifying this reference type with 'const' from cp_build_qualified_type rather than just silently dropping the qualification as per [dcl.ref]/1. The problem is ultimately that make_typename_type ignores the tf_keep_type_decl flag when the dependent name is a template-id. This in turn causes the TYPE_DECL check within tsubst to fail, and so we end up not passing tf_ignore_bad_quals to cp_build_qualified_type. This patch fixes this by making make_typename_type respect the tf_keep_type_decl flag in this situation. PR c++/100592 gcc/cp/ChangeLog: * 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. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-71.C: New test. --- gcc/cp/decl.c | 13 +++++++++---- gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C | 13 +++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C (limited to 'gcc') diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index fb21a3a..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); 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 +struct meta { + template using if_c = int&; +}; + +template +typename meta::template if_c const f(); + +using type = decltype(f()); +using type = int&; -- cgit v1.1 From 4bdc6e17c9dc621f9502a84abceb2e17ae0418f8 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 3 Jun 2021 10:32:40 -0400 Subject: diagnostic-show-locus: tweak rejection logic gcc/ChangeLog: * 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. Signed-off-by: David Malcolm --- gcc/diagnostic-show-locus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc') 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; -- cgit v1.1 From e84fe25f6386666efe1ead4304693d91d7555e7a Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 3 Jun 2021 10:35:27 -0400 Subject: analyzer: show types for poisoned_svalue and compound_svalue gcc/analyzer/ChangeLog: * svalue.cc (poisoned_svalue::dump_to_pp): Dump type. (compound_svalue::dump_to_pp): Dump any type. Signed-off-by: David Malcolm --- gcc/analyzer/svalue.cc | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'gcc') 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, "})"); } } -- cgit v1.1 From 981d98b883ed521c88c295ed82227c605d82add4 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 3 Jun 2021 10:37:41 -0400 Subject: analyzer: remove unused prototypes gcc/analyzer/ChangeLog: * store.h (store::get_direct_binding): Remove unused decl. (store::get_default_binding): Likewise. Signed-off-by: David Malcolm --- gcc/analyzer/store.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'gcc') 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; } -- cgit v1.1 From 160fe6034bd2ca0073a722b6774518bb9ea5ac02 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 1 Jun 2021 17:48:30 +0200 Subject: Use known global ranges in export_global_ranges This patch modifies export_global_ranges to take into account current global ranges. It also handles enhances said function to export pointer global ranges as well. gcc/ChangeLog: * 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. gcc/testsuite/ChangeLog: * gcc.dg/pr80776-1.c: XFAIL and document the reason why. --- gcc/gimple-range.cc | 26 ++++++++++---------------- gcc/testsuite/gcc.dg/pr80776-1.c | 12 +++++++++++- gcc/value-query.cc | 39 +++++++++++++++++++++++++++++++++++++++ gcc/value-query.h | 1 + 4 files changed, 61 insertions(+), 17 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index ed0a0c9..af42620 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1115,7 +1115,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 +1136,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"); 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/value-query.cc b/gcc/value-query.cc index f8b457d..070d706 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -224,6 +224,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. diff --git a/gcc/value-query.h b/gcc/value-query.h index 97da663..d0512e4 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -115,5 +115,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 -- cgit v1.1 From caa60c12715dd9b0cbb550a45e5878214a10a2fe Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 26 May 2021 08:40:17 +0200 Subject: Implement generic expression evaluator for range_query. Right now, range_of_expr only works with constants, SSA names, and pointers. Anything else gets returned as VARYING. This patch adds the capability to deal with arbitrary expressions, inasmuch as these tree codes are implemented in range-ops.cc. This will give us the ability to ask for the range of any tree expression, not just constants and SSA names, with range_of_expr(). This is a more generic implementation of determine_value_range in VRP. A follow-up patch will remove all uses of it in favor of the range_query API. gcc/ChangeLog: * 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. --- gcc/function-tests.c | 5 +++ gcc/gimple-range-cache.cc | 4 +-- gcc/gimple-range-tests.cc | 72 ++++++++++++++++++++++++++++++++++++++++ gcc/gimple-range.cc | 64 ++---------------------------------- gcc/gimple-range.h | 7 ++-- gcc/selftest.h | 1 + gcc/value-query.cc | 84 +++++++++++++++++++++++++++++++++++++++++++++-- gcc/value-query.h | 2 ++ gcc/vr-values.c | 2 +- 9 files changed, 172 insertions(+), 69 deletions(-) create mode 100644 gcc/gimple-range-tests.cc (limited to 'gcc') 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 +. */ + +#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 af42620..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) @@ -1466,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/value-query.cc b/gcc/value-query.cc index 070d706..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 @@ -355,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 d0512e4..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; 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)) { -- cgit v1.1 From 04affb328c6a7e29427287c5192da38864f0dbca Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 26 May 2021 08:53:07 +0200 Subject: Replace uses of determine_value_range with range_of_expr. The expression evaluator changes to the range_query API provide everything determine_value_range does. This patch replaces all uses with calls into the range_query API. gcc/ChangeLog: * 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. --- gcc/calls.c | 21 ++++++++++---------- gcc/tree-affine.c | 7 ++++++- gcc/tree-data-ref.c | 12 ++++++------ gcc/tree-vrp.c | 56 ----------------------------------------------------- gcc/tree-vrp.h | 1 - 5 files changed, 23 insertions(+), 74 deletions(-) (limited to 'gcc') 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/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-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); -- cgit v1.1 From 5f2ef25b08f782a9f72adb8e6389ce66d302594b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 3 Jun 2021 17:46:15 +0200 Subject: Fix duplicate name issues in output of -fdump-ada-spec The namespace rules are different in the C family of languages and in Ada, and a few adjustments are further needed in -fdump-ada-spec because of them. gcc/c-family/ * 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. --- gcc/c-family/c-ada-spec.c | 106 ++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 42 deletions(-) (limited to 'gcc') diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index 29eb0b0..ef0c74c 100644 --- a/gcc/c-family/c-ada-spec.c +++ b/gcc/c-family/c-ada-spec.c @@ -2003,7 +2003,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, parent); + pp_underscore (buffer); pp_ada_tree_identifier (buffer, TREE_PURPOSE (value), node, false); + pp_string (buffer, " : constant "); if (TYPE_NAME (node)) @@ -2628,11 +2636,31 @@ struct overloaded_name_hasher : delete_ptr_hash { return a->name == b->name; } }; -static hash_table *overloaded_names; +typedef hash_table 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 * +static htable_t * init_overloaded_names (void) { static const char *names[] = @@ -2640,41 +2668,31 @@ init_overloaded_names (void) { "memchr", "rawmemchr", "memrchr", "strchr", "strrchr", "strchrnul", "strpbrk", "strstr", "strcasestr", "index", "rindex", "basename" }; - hash_table *table - = new hash_table (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 +2816,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 +2847,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 +2880,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))) @@ -2945,9 +2960,9 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int 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 +2970,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 +3033,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); @@ -3477,6 +3497,8 @@ 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); -- cgit v1.1 From 517155ceb971d33881cfeecd767406f0801c6512 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 3 Jun 2021 17:50:44 +0200 Subject: Fix issue for external subtypes with -fdump-ada-spec This works around an irregularity of the language whereby subtypes, unlike types, are not visible through a limited_with clause. gcc/c-family/ * c-ada-spec.c (pp_ada_tree_identifier): Tidy up. (dump_ada_node) : Deal specially with external subtypes. --- gcc/c-family/c-ada-spec.c | 91 +++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 38 deletions(-) (limited to 'gcc') diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index ef0c74c..751cc0e 100644 --- a/gcc/c-family/c-ada-spec.c +++ b/gcc/c-family/c-ada-spec.c @@ -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); + } } } @@ -2220,6 +2217,24 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc, { tree type_name = TYPE_NAME (TREE_TYPE (node)); + /* Generate "access " instead of "access " + 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) { @@ -2241,8 +2256,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 "); -- cgit v1.1 From cd4dd47265f2bff89fbbfb6a12a98a7101fb5280 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 3 Jun 2021 17:54:45 +0200 Subject: Fix issue for nested record types with -fdump-ada-spec Ada does not support anonymous record declarations nested in other record declarations so -fdump-ada-spec needs to unnest them, and this contains a few fixes for this machinery. gcc/c-family/ * 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. : 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. --- gcc/c-family/c-ada-spec.c | 116 +++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 64 deletions(-) (limited to 'gcc') diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index 751cc0e..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 @@ -1464,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)) { @@ -1506,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 @@ -1757,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) { @@ -1790,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); @@ -1823,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); } } @@ -1954,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)) { @@ -2005,7 +1997,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_underscore (buffer); pp_ada_tree_identifier (buffer, TREE_PURPOSE (value), node, false); @@ -2016,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); @@ -2106,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: @@ -2116,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: @@ -2298,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: @@ -2490,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 @@ -2506,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; @@ -2521,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); + dump_nested_type (buffer, field, t, 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. */ +/* Dump in BUFFER the anonymous type of FIELD inside T. SPC is the indentation + level. */ 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 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. */ - -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; @@ -2559,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. */ @@ -2573,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) @@ -2585,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; @@ -2601,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)"); @@ -2953,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 { @@ -2968,9 +2952,9 @@ 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) @@ -3206,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)); } } @@ -3516,7 +3500,11 @@ dump_ada_specs (void (*collect_all_refs)(const char *), /* 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); -- cgit v1.1 From 52e130652a76ff3d14c0f572fcd79fa53637ce2c Mon Sep 17 00:00:00 2001 From: Aaron Sawdey Date: Wed, 2 Jun 2021 22:54:08 -0500 Subject: Fix operand order to subf for p10 fusion. This certainly causes a bootstrap miscompare, and might also be responsible for PR/100820. The operands to subf were reversed in the logical-add/sub fusion patterns, and I screwed up my bootstrap test which is how it ended up getting committed. gcc/ChangeLog * config/rs6000/genfusion.pl (gen_logical_addsubf): Fix input order to subf instruction. * config/rs6000/fusion.md: Regenerate. --- gcc/config/rs6000/fusion.md | 64 +++++++++++++++++++++--------------------- gcc/config/rs6000/genfusion.pl | 20 +++++++------ 2 files changed, 43 insertions(+), 41 deletions(-) (limited to 'gcc') 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)"; -- cgit v1.1 From 5883e567564c5b3caecba0c13e8a360a14cdc846 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 3 Jun 2021 20:05:31 +0200 Subject: i386: Add insert and extract patterns for 4-byte vectors [PR100637] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patch introduces insert and extract patterns for 4-byte vectors. It effectively only emits PINSR and PEXTR instructions when available, otherwise falls back to generic code that emulates these instructions via inserts, extracts, logic operations and shifts in integer registers. Please note that generic fallback produces better code than the current approach of constructing new vector in memory (due to store forwarding stall) so also enable QImode 8-byte vector inserts only with TARGET_SSE4_1. 2021-06-03 Uroš Bizjak gcc/ 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. gcc/testsuite/ PR target/100637 * gcc.target/i386/vperm-v2hi.c: New test. * gcc.target/i386/vperm-v4qi.c: Ditto. --- gcc/config/i386/i386-expand.c | 6 + gcc/config/i386/mmx.md | 176 ++++++++++++++++++++++++++++- gcc/testsuite/gcc.target/i386/vperm-v2hi.c | 41 +++++++ gcc/testsuite/gcc.target/i386/vperm-v4qi.c | 47 ++++++++ 4 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/vperm-v2hi.c create mode 100644 gcc/testsuite/gcc.target/i386/vperm-v4qi.c (limited to 'gcc') 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/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; +} -- cgit v1.1 From 3c70b3ca1ef58f302bf8c16d9e7c7bb8626408bf Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Thu, 3 Jun 2021 13:50:34 -0700 Subject: RISC-V: Enable riscv attributes by default for all riscv targets. These were only enabled for embedded elf originally because that was the safe option, and linux had no obvious use for them. But now that we have new extensions coming like V that affect process state and ABIs, the attributes are expected to be useful for linux, and may be required by the psABI. clang already emits them for all riscv targets. gcc/ * config.gcc (riscv*-*-*): If --with-riscv-attribute not used, turn it on for all riscv targets. --- gcc/config.gcc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'gcc') 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 -- cgit v1.1 From 47d25a0314d8f28d399cd93f673df5886ca81d78 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 2 Jun 2021 07:04:54 +0200 Subject: cris: Update unexpected empty split condition gcc/ChangeLog: * config/cris/cris.md (*addi_reload): Fix empty split condition. --- gcc/config/cris/cris.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') 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;") -- cgit v1.1 From 440c8a0a91b7ea1603e3e1eaae64fc0e12f0c4f1 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 4 Jun 2021 00:16:24 +0000 Subject: Daily bump. --- gcc/ChangeLog | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 7 ++ gcc/analyzer/ChangeLog | 10 +++ gcc/c-family/ChangeLog | 37 +++++++++++ gcc/c/ChangeLog | 6 ++ gcc/cp/ChangeLog | 30 +++++++++ gcc/testsuite/ChangeLog | 55 ++++++++++++++++ 8 files changed, 313 insertions(+), 1 deletion(-) (limited to 'gcc') 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 + + * config/cris/cris.md (*addi_reload): Fix empty split condition. + +2021-06-03 Jim Wilson + + * config.gcc (riscv*-*-*): If --with-riscv-attribute not used, + turn it on for all riscv targets. + +2021-06-03 Uroš Bizjak + + 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 + + * config/rs6000/genfusion.pl (gen_logical_addsubf): Fix input + order to subf instruction. + * config/rs6000/fusion.md: Regenerate. + +2021-06-03 Aldy Hernandez + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * config/arm/mve.md (mve_vabsq_f): Use 'abs' instead of unspec. + (mve_vabsq_s): Likewise. + * config/arm/neon.md (abs2): Rename to neon_abs2. + * config/arm/unspecs.md (VABSQ_F, VABSQ_S): Delete. + * config/arm/vec-common.md (neg2): Rename to + 2. + +2021-06-03 Claudiu Zissulescu + + * 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 + + * 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 + + PR ipa/99122 + * tree-inline.c (inline_forbidden_p): Remove test on return type. + +2021-06-03 Eric Botcazou + + * dwarf2out.c (loc_list_from_tree_1) : 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 + + * dwarf2out.c (mem_loc_descriptor) : Fix typo. + (typed_binop_from_tree): New function. + (loc_list_from_tree_1) : For an unsigned type, + turn a divide by a power of 2 into a shift. + : 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 + + * 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) : Tidy up and set strict_signedness + to true when a context is present before evaluating the arguments. + : 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 + + 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 + + * config/arc/arc.md (*bbit_di): Remove. + 2021-06-02 Christoph Muellner 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 + + * gcc-interface/decl.c (gnat_to_gnu_entity) : 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. + : Add PAT local constant and use it throughout. + 2021-05-26 Jakub Jelinek * init.c (__gnat_error_handler): Remove register keyword. 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 + + * store.h (store::get_direct_binding): Remove unused decl. + (store::get_default_binding): Likewise. + +2021-06-03 David Malcolm + + * svalue.cc (poisoned_svalue::dump_to_pp): Dump type. + (compound_svalue::dump_to_pp): Dump any type. + 2021-05-18 David Malcolm PR analyzer/100615 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 + + * 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. + : 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 + + * c-ada-spec.c (pp_ada_tree_identifier): Tidy up. + (dump_ada_node) : Deal specially with external subtypes. + +2021-06-03 Eric Botcazou + + * 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 PR other/100759 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 + + PR c++/100859 + * c-typeck.c (c_finish_omp_clauses): Move OMP_CLAUSE_AFFINITY + after depend only cases. + 2021-05-31 Richard Biener PR c++/88601 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 + + 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 + + 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 + + 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 PR c++/100838 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 + + PR target/100637 + * gcc.target/i386/vperm-v2hi.c: New test. + * gcc.target/i386/vperm-v4qi.c: Ditto. + +2021-06-03 Aldy Hernandez + + * gcc.dg/pr80776-1.c: XFAIL and document the reason why. + +2021-06-03 Patrick Palka + + PR c++/100592 + * g++.dg/cpp0x/alias-decl-71.C: New test. + +2021-06-03 Patrick Palka + + PR c++/100862 + * g++.dg/cpp2a/using-enum-9.C: New test. + +2021-06-03 Andre Vieira + + * gcc.target/aarch64/sve/part_vect_single_iter_epilog.c: New test. + +2021-06-03 Christophe Lyon + + * gcc.target/arm/simd/mve-vabs.c: New test. + +2021-06-03 Eric Botcazou + + * gnat.dg/bit_packed_array6.adb: New test. + * gnat.dg/bit_packed_array6_pkg.ads: New helper. + +2021-06-03 Martin Liska + + * gcc.dg/spellcheck-options-23.c: New test. + +2021-06-03 Eric Botcazou + + * gnat.dg/inline22.adb: New test. + +2021-06-03 Tamar Christina + + * gcc.target/aarch64/cpunative/info_16: Update implementer. + * gcc.target/aarch64/cpunative/info_17: Likewise + +2021-06-03 Jakub Jelinek + + 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 PR c++/100838 -- cgit v1.1 From a3f6bd7891495a0ed65f7da7a55d36c730328692 Mon Sep 17 00:00:00 2001 From: Haochen Gui Date: Fri, 4 Jun 2021 11:04:31 +0800 Subject: rs6000: Expand PROMOTE_MODE marco in rs6000_promote_function_mode This patch prepares for the patch which disables mode promotion of pseudos on rs6000. gcc/ChangeLog: * config/rs6000/rs6000-call.c (rs6000_promote_function_mode): Replace PROMOTE_MODE marco with its content. --- gcc/config/rs6000/rs6000-call.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc') 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; } -- cgit v1.1 From 9080a3bf23297885fdc47221da37a71d6dec93c5 Mon Sep 17 00:00:00 2001 From: Haochen Gui Date: Fri, 4 Jun 2021 14:38:53 +0800 Subject: rs6000: Disable mode promotion for pseudos rs6000 has instructions that can do almost everything 32 bit at least as efficiently as corresponding 64 bit things. The mode promotion can be defered to when a wide mode is necessary. So it helps a lot not promote mode for pseudos. SPECint test shows that the overall performance improvement (by geomean) is more than 2% with this patch. testsuite/gcc.target/powerpc/not-promote-mode.c illustrates how the patch eliminates the redundant extensions and do further optimization by disabling mode promotion for pseduos. gcc/ChangeLog * config/rs6000/rs6000.h (PROMOTE_MODE): Remove. gcc/testsuite/ChangeLog: * gcc.target/powerpc/not-promote-mode.c: New. --- gcc/config/rs6000/rs6000.h | 11 ----------- gcc/testsuite/gcc.target/powerpc/not-promote-mode.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/not-promote-mode.c (limited to 'gcc') 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/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} } } */ -- cgit v1.1 From 39e5a954c156f7af16aa1a8f87405433d8031c4e Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Fri, 4 Jun 2021 10:12:32 +0300 Subject: arc: Don't allow millicode thunks with reduced register set CPUs. The millicode thunks are not reduced register set safe. Disable them for CPUs having this option on. gcc/ 2021-06-04 Claudiu Zissulescu * config/arc/arc.c (arc_override_options): Disable millicode thunks when RF16 is on. Signed-off-by: Claudiu Zissulescu --- gcc/config/arc/arc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index b77d056..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. */ -- cgit v1.1