From a0d371a25148d113f7c3657f36fbf7dcb5e1f63d Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 26 May 2021 09:51:36 +0200 Subject: Fix C++ libgomp regressions This is only a stopgap fix. gcc/ * gimplify.c (gimplify_decl_expr): Do not clear TREE_READONLY on a DECL which is a reference for OMP. --- gcc/gimplify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/gimplify.c b/gcc/gimplify.c index ed825a9..54bf59a 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1829,7 +1829,7 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) gimplify_and_add (init, seq_p); ggc_free (init); /* Clear TREE_READONLY if we really have an initialization. */ - if (!DECL_INITIAL (decl)) + if (!DECL_INITIAL (decl) && !omp_is_reference (decl)) TREE_READONLY (decl) = 0; } else -- cgit v1.1 From 5f338210456bf4f142a2da6eb0a01ae8ffecaa88 Mon Sep 17 00:00:00 2001 From: Geng Qi Date: Fri, 30 Apr 2021 21:02:15 +0800 Subject: C-SKY: Delete TARGET_CAN_CHANGE_MODE_CLASS, use defualt definition. gcc/ChangeLog: * config/csky/csky.c (csky_can_change_mode_class): Delete. For csky, HF/SF mode use the low bits of VREGS. --- gcc/config/csky/csky.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'gcc') diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c index c0e42a2..e55821f 100644 --- a/gcc/config/csky/csky.c +++ b/gcc/config/csky/csky.c @@ -608,9 +608,6 @@ csky_default_logical_op_non_short_circuit (void) #undef TARGET_MODES_TIEABLE_P #define TARGET_MODES_TIEABLE_P csky_modes_tieable_p -#undef TARGET_CAN_CHANGE_MODE_CLASS -#define TARGET_CAN_CHANGE_MODE_CLASS csky_can_change_mode_class - #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE csky_conditional_register_usage @@ -2370,19 +2367,6 @@ csky_modes_tieable_p (machine_mode mode1, machine_mode mode2) && (mode1 == DFmode || mode2 == DFmode)); } -/* Implement TARGET_CAN_CHANGE_MODE_CLASS. - V_REG registers can't do subreg as all values are reformatted to - internal precision. */ - -static bool -csky_can_change_mode_class (machine_mode from, - machine_mode to, - reg_class_t rclass) -{ - return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to) - || !reg_classes_intersect_p (V_REGS, rclass)); -} - /* Implement TARGET_CLASS_LIKELY_SPILLED_P. We need to define this for MINI_REGS when we only use r0 - r7. Otherwise we can end up using r0-r4 for function arguments, and don't -- cgit v1.1 From 95d67762171f83277a5700b270c0d1e2756f83f4 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 26 May 2021 11:18:07 +0200 Subject: openmp: Fix up handling of target constructs in offloaded routines [PR100573] OpenMP Nesting of Regions restrictions say: - If a target update, target data, target enter data, or target exit data construct is encountered during execution of a target region, the behavior is unspecified. - If a target construct is encountered during execution of a target region and a device clause in which the ancestor device-modifier appears is not present on the construct, the behavior is unspecified. That wording is about the dynamic (runtime) behavior, not about lexical nesting, so while it is UB if omp target * is encountered in the target region, we need to make it compile and link (for lexical nesting of target * inside of target we actually emit a warning). To make this work, I had to do multiple changes. One was to mark .omp_data_{sizes,kinds}.* variables when static as "omp declare target". Another one was to add stub GOMP_target* entrypoints to nvptx and gcn libgomp.a. The entrypoint functions shouldn't be called or passed in the offload regions, otherwise libgomp: cuLaunchKernel error: too many resources requested for launch was reported; fixed by changing those arguments of calls to GOMP_target_ext to NULL. And we didn't mark the entrypoints "omp target entrypoint" when the caller has been "omp declare target". 2021-05-26 Jakub Jelinek PR libgomp/100573 gcc/ * omp-low.c: Include omp-offload.h. (create_omp_child_function): If current_function_decl has "omp declare target" attribute and is_gimple_omp_offloaded, remove that attribute from the copy of attribute list and add "omp target entrypoint" attribute instead. (lower_omp_target): Mark .omp_data_sizes.* and .omp_data_kinds.* variables for offloading if in omp_maybe_offloaded_ctx. * omp-offload.c (pass_omp_target_link::execute): Nullify second argument to GOMP_target_data_ext in offloaded code. libgomp/ * config/nvptx/target.c (GOMP_target_ext, GOMP_target_data_ext, GOMP_target_end_data, GOMP_target_update_ext, GOMP_target_enter_exit_data): New dummy entrypoints. * config/gcn/target.c (GOMP_target_ext, GOMP_target_data_ext, GOMP_target_end_data, GOMP_target_update_ext, GOMP_target_enter_exit_data): Likewise. * testsuite/libgomp.c-c++-common/for-3.c (DO_PRAGMA, OMPTEAMS, OMPFROM, OMPTO): Define. (main): Remove #pragma omp target teams around all the tests. * testsuite/libgomp.c-c++-common/target-41.c: New test. * testsuite/libgomp.c-c++-common/target-42.c: New test. --- gcc/omp-low.c | 39 +++++++++++++++++++++++++++++++++------ gcc/omp-offload.c | 12 ++++++++++-- 2 files changed, 43 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/omp-low.c b/gcc/omp-low.c index e00051b..2d5cdf6 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "stringpool.h" #include "attribs.h" +#include "omp-offload.h" /* Lowering of OMP parallel and workshare constructs proceeds in two phases. The first phase scans the function looking for OMP statements @@ -1944,16 +1945,25 @@ create_omp_child_function (omp_context *ctx, bool task_copy) g->have_offload = true; } - if (cgraph_node::get_create (decl)->offloadable - && !lookup_attribute ("omp declare target", - DECL_ATTRIBUTES (current_function_decl))) + if (cgraph_node::get_create (decl)->offloadable) { const char *target_attr = (is_gimple_omp_offloaded (ctx->stmt) ? "omp target entrypoint" : "omp declare target"); - DECL_ATTRIBUTES (decl) - = tree_cons (get_identifier (target_attr), - NULL_TREE, DECL_ATTRIBUTES (decl)); + if (lookup_attribute ("omp declare target", + DECL_ATTRIBUTES (current_function_decl))) + { + if (is_gimple_omp_offloaded (ctx->stmt)) + DECL_ATTRIBUTES (decl) + = remove_attribute ("omp declare target", + copy_list (DECL_ATTRIBUTES (decl))); + else + target_attr = NULL; + } + if (target_attr) + DECL_ATTRIBUTES (decl) + = tree_cons (get_identifier (target_attr), + NULL_TREE, DECL_ATTRIBUTES (decl)); } t = build_decl (DECL_SOURCE_LOCATION (decl), @@ -12960,6 +12970,23 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) gimple_build_assign (TREE_VEC_ELT (t, i), clobber)); } + else if (omp_maybe_offloaded_ctx (ctx->outer)) + { + tree id = get_identifier ("omp declare target"); + tree decl = TREE_VEC_ELT (t, i); + DECL_ATTRIBUTES (decl) + = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); + varpool_node *node = varpool_node::get (decl); + if (node) + { + node->offloadable = 1; + if (ENABLE_OFFLOADING) + { + g->have_offload = true; + vec_safe_push (offload_vars, t); + } + } + } tree clobber = build_clobber (ctx->record_type); gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl, diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c index e907827..0320ea6 100644 --- a/gcc/omp-offload.c +++ b/gcc/omp-offload.c @@ -2696,8 +2696,16 @@ pass_omp_target_link::execute (function *fun) { gimple_stmt_iterator gsi; for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - if (walk_gimple_stmt (&gsi, NULL, find_link_var_op, NULL)) - gimple_regimplify_operands (gsi_stmt (gsi), &gsi); + { + if (gimple_call_builtin_p (gsi_stmt (gsi), BUILT_IN_GOMP_TARGET)) + { + /* Nullify the second argument of __builtin_GOMP_target_ext. */ + gimple_call_set_arg (gsi_stmt (gsi), 1, null_pointer_node); + update_stmt (gsi_stmt (gsi)); + } + if (walk_gimple_stmt (&gsi, NULL, find_link_var_op, NULL)) + gimple_regimplify_operands (gsi_stmt (gsi), &gsi); + } } return 0; -- cgit v1.1 From b4329e3dd6fb7c78948fcf9d2f5b9d873deec284 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 26 May 2021 08:35:31 -0400 Subject: c++: Fix reference NTTP binding to noexcept fn [PR97420] Here, in C++17 mode, convert_nontype_argument_function is rejecting binding a non-noexcept function reference template parameter to a noexcept function (encoded as the template argument '*(int (&) (int)) &f'). The first roadblock to making this work is that the argument is wrapped an an implicit INDIRECT_REF, so we need to unwrap it before calling strip_fnptr_conv. The second roadblock is that the NOP_EXPR cast converts from a function pointer type to a reference type while simultaneously removing the noexcept qualification, and fnptr_conv_p doesn't consider this cast to be a function pointer conversion. This patch fixes this by making fnptr_conv_p treat REFERENCE_TYPEs and POINTER_TYPEs interchangeably. Finally, in passing, this patch also simplifies noexcept_conv_p by removing a bunch of redundant checks already performed by its only caller fnptr_conv_p. PR c++/97420 gcc/cp/ChangeLog: * cvt.c (noexcept_conv_p): Remove redundant checks and simplify. (fnptr_conv_p): Don't call non_reference. Use INDIRECT_TYPE_P instead of TYPE_PTR_P. * pt.c (convert_nontype_argument_function): Look through implicit INDIRECT_REFs before calling strip_fnptr_conv. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept68.C: New test. --- gcc/cp/cvt.c | 36 ++++++++++----------------------- gcc/cp/pt.c | 5 ++++- gcc/testsuite/g++.dg/cpp0x/noexcept68.C | 8 ++++++++ 3 files changed, 23 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept68.C (limited to 'gcc') diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 7fa6e8d..330d658 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -2081,7 +2081,8 @@ can_convert_tx_safety (tree to, tree from) && same_type_p (to, tx_unsafe_fn_variant (from))); } -/* Return true iff FROM can convert to TO by dropping noexcept. */ +/* Return true iff FROM can convert to TO by dropping noexcept. + This is just a subroutine of of fnptr_conv_p. */ static bool noexcept_conv_p (tree to, tree from) @@ -2089,30 +2090,15 @@ noexcept_conv_p (tree to, tree from) if (!flag_noexcept_type) return false; - tree t = non_reference (to); - tree f = from; - if (TYPE_PTRMEMFUNC_P (t) - && TYPE_PTRMEMFUNC_P (f)) - { - t = TYPE_PTRMEMFUNC_FN_TYPE (t); - f = TYPE_PTRMEMFUNC_FN_TYPE (f); - } - if (TYPE_PTR_P (t) - && TYPE_PTR_P (f)) - { - t = TREE_TYPE (t); - f = TREE_TYPE (f); - } - tree_code code = TREE_CODE (f); - if (TREE_CODE (t) != code) + if (TREE_CODE (to) != TREE_CODE (from)) return false; - if (code != FUNCTION_TYPE && code != METHOD_TYPE) + if (!FUNC_OR_METHOD_TYPE_P (from)) return false; - if (!type_throw_all_p (t) - || type_throw_all_p (f)) + if (!type_throw_all_p (to) + || type_throw_all_p (from)) return false; - tree v = build_exception_variant (f, NULL_TREE); - return same_type_p (t, v); + tree v = build_exception_variant (from, NULL_TREE); + return same_type_p (to, v); } /* Return true iff FROM can convert to TO by a function pointer conversion. */ @@ -2120,7 +2106,7 @@ noexcept_conv_p (tree to, tree from) bool fnptr_conv_p (tree to, tree from) { - tree t = non_reference (to); + tree t = to; tree f = from; if (TYPE_PTRMEMFUNC_P (t) && TYPE_PTRMEMFUNC_P (f)) @@ -2128,8 +2114,8 @@ fnptr_conv_p (tree to, tree from) t = TYPE_PTRMEMFUNC_FN_TYPE (t); f = TYPE_PTRMEMFUNC_FN_TYPE (f); } - if (TYPE_PTR_P (t) - && TYPE_PTR_P (f)) + if (INDIRECT_TYPE_P (t) + && INDIRECT_TYPE_P (f)) { t = TREE_TYPE (t); f = TREE_TYPE (f); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 99a9ee5..f3fa9c1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6622,7 +6622,10 @@ convert_nontype_argument_function (tree type, tree expr, if (value_dependent_expression_p (fn)) goto accept; - fn_no_ptr = strip_fnptr_conv (fn); + fn_no_ptr = fn; + if (REFERENCE_REF_P (fn_no_ptr)) + fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0); + fn_no_ptr = strip_fnptr_conv (fn_no_ptr); if (TREE_CODE (fn_no_ptr) == ADDR_EXPR) fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0); if (BASELINK_P (fn_no_ptr)) diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept68.C b/gcc/testsuite/g++.dg/cpp0x/noexcept68.C new file mode 100644 index 0000000..086899a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept68.C @@ -0,0 +1,8 @@ +// PR c++/97420 +// { dg-do compile { target c++11 } } + +int f(int) noexcept; +template void A(); +int main() { + A(); +} -- cgit v1.1 From 88834c7d05acf5ce4eaccda56fb04436595e2a52 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 26 May 2021 08:37:30 -0400 Subject: c++: constexpr and copy elision within mem init [PR100368] In the testcase below, the member initializer b(f()) inside C's default constructor is encoded as a TARGET_EXPR wrapping the CALL_EXPR f() in C++17 mode. During massaging of this constexpr constructor, build_target_expr_with_type called from bot_manip on this initializer tries to add an extra copy using B's implicitly deleted copy constructor rather than just preserving the copy elision. Since it's wrong to introduce an extra copy when initializing a temporary from a CALL_EXPR, this patch makes build_target_expr_with_type avoid calling force_rvalue in this case. Additionally, bot_manip should be copying TARGET_EXPRs in a more oblivious manner, so this patch makes bot_manip use force_target_expr instead of build_target_expr_with_type. And since bot_manip is now no longer a caller, we can remove the void initializer handling in build_target_expr_with_type. PR c++/100368 gcc/cp/ChangeLog: * tree.c (build_target_expr_with_type): Don't call force_rvalue on CALL_EXPR initializer. Simplify now that bot_manip is no longer a caller. (bot_manip): Use force_target_expr instead of build_target_expr_with_type. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/elide6.C: New test. --- gcc/cp/tree.c | 15 ++++++++------- gcc/testsuite/g++.dg/cpp1z/elide6.C | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/elide6.C (limited to 'gcc') diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 72f498f..372d89f 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -843,21 +843,22 @@ tree build_target_expr_with_type (tree init, tree type, tsubst_flags_t complain) { gcc_assert (!VOID_TYPE_P (type)); + gcc_assert (!VOID_TYPE_P (TREE_TYPE (init))); if (TREE_CODE (init) == TARGET_EXPR || init == error_mark_node) return init; else if (CLASS_TYPE_P (type) && type_has_nontrivial_copy_init (type) - && !VOID_TYPE_P (TREE_TYPE (init)) && TREE_CODE (init) != COND_EXPR && TREE_CODE (init) != CONSTRUCTOR - && TREE_CODE (init) != VA_ARG_EXPR) - /* We need to build up a copy constructor call. A void initializer - means we're being called from bot_manip. COND_EXPR is a special + && TREE_CODE (init) != VA_ARG_EXPR + && TREE_CODE (init) != CALL_EXPR) + /* We need to build up a copy constructor call. COND_EXPR is a special case because we already have copies on the arms and we don't want another one here. A CONSTRUCTOR is aggregate initialization, which is handled separately. A VA_ARG_EXPR is magic creation of an - aggregate; there's no additional work to be done. */ + aggregate; there's no additional work to be done. A CALL_EXPR + already creates a prvalue. */ return force_rvalue (init, complain); return force_target_expr (type, init, complain); @@ -3112,8 +3113,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_) AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true; } else - u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t), - tf_warning_or_error); + u = force_target_expr (TREE_TYPE (t), TREE_OPERAND (t, 1), + tf_warning_or_error); TARGET_EXPR_IMPLICIT_P (u) = TARGET_EXPR_IMPLICIT_P (t); TARGET_EXPR_LIST_INIT_P (u) = TARGET_EXPR_LIST_INIT_P (t); diff --git a/gcc/testsuite/g++.dg/cpp1z/elide6.C b/gcc/testsuite/g++.dg/cpp1z/elide6.C new file mode 100644 index 0000000..399e1a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/elide6.C @@ -0,0 +1,16 @@ +// PR c++/100368 +// { dg-do compile { target c++11 } } + +struct A { + A() = default; + A(const A&) = delete; +}; + +struct B { A a; }; // { dg-error "deleted" "" { target c++14_down } } + +constexpr B f() { return {}; } + +struct C { + constexpr C() : b(f()) {} // { dg-error "deleted" "" { target c++14_down } } + B b; +}; -- cgit v1.1 From 74045879770ace0b14f0f809c8e795069044cf41 Mon Sep 17 00:00:00 2001 From: Jan-Benedict Glaw Date: Wed, 26 May 2021 15:22:11 +0200 Subject: arc: Remove useless register keyword The "register" keyword was removed in C++17, remove them to get the backend to build again. gcc/ * config/arc/arc.c (arc_address_cost, arc_print_operand_address, arc_ccfsm_advance, symbolic_reference_mentioned_p, arc_raw_symbolic_reference_mentioned_p): Remove register keyword. --- gcc/config/arc/arc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index ec7328e..9153f05 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -2488,8 +2488,8 @@ arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed) case PLUS : { - register rtx plus0 = XEXP (addr, 0); - register rtx plus1 = XEXP (addr, 1); + rtx plus0 = XEXP (addr, 0); + rtx plus1 = XEXP (addr, 1); if (GET_CODE (plus0) != REG && (GET_CODE (plus0) != MULT @@ -5032,7 +5032,7 @@ arc_print_operand (FILE *file, rtx x, int code) void arc_print_operand_address (FILE *file , rtx addr) { - register rtx base, index = 0; + rtx base, index = 0; switch (GET_CODE (addr)) { @@ -5157,7 +5157,7 @@ static void arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state) { /* BODY will hold the body of INSN. */ - register rtx body; + rtx body; /* This will be 1 if trying to repeat the trick (ie: do the `else' part of an if/then/else), and things need to be reversed. */ @@ -6130,8 +6130,8 @@ arc_legitimate_pic_addr_p (rtx addr) static bool symbolic_reference_mentioned_p (rtx op) { - register const char *fmt; - register int i; + const char *fmt; + int i; if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) return true; @@ -6141,7 +6141,7 @@ symbolic_reference_mentioned_p (rtx op) { if (fmt[i] == 'E') { - register int j; + int j; for (j = XVECLEN (op, i) - 1; j >= 0; j--) if (symbolic_reference_mentioned_p (XVECEXP (op, i, j))) @@ -6163,8 +6163,8 @@ symbolic_reference_mentioned_p (rtx op) bool arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local) { - register const char *fmt; - register int i; + const char *fmt; + int i; if (GET_CODE(op) == UNSPEC) return false; @@ -6184,7 +6184,7 @@ arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local) { if (fmt[i] == 'E') { - register int j; + int j; for (j = XVECLEN (op, i) - 1; j >= 0; j--) if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j), -- cgit v1.1 From 76898cec437561a5e74d92b98f4631b80300409d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 26 May 2021 15:54:17 +0200 Subject: Remove useless register keywords This patch removes useless register keywords from several backends and one spot in the Ada FE. 2021-05-26 Jakub Jelinek gcc/ * config/epiphany/epiphany.c (epiphany_print_operand_address): Remove register keywords. * config/microblaze/microblaze.c (microblaze_legitimize_address, call_internal1, microblaze_option_override, print_operand): Likewise. * config/microblaze/microblaze.md (call_internal_plt, call_value_intern_plt, call_value_intern): Likewise. * config/arm/aout.h (ASM_OUTPUT_ALIGN): Likewise. * config/iq2000/iq2000.md (call_internal1, call_value_internal1, call_value_multiple_internal1): Likewise. * config/bfin/bfin.c (symbolic_reference_mentioned_p): Likewise. gcc/ada/ * init.c (__gnat_error_handler): Remove register keyword. --- gcc/ada/init.c | 2 +- gcc/config/arm/aout.h | 2 +- gcc/config/bfin/bfin.c | 6 +++--- gcc/config/epiphany/epiphany.c | 2 +- gcc/config/iq2000/iq2000.md | 6 +++--- gcc/config/microblaze/microblaze.c | 26 +++++++++++++------------- gcc/config/microblaze/microblaze.md | 18 ++++++++++-------- 7 files changed, 32 insertions(+), 30 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/init.c b/gcc/ada/init.c index 08ff8d7..c48e244 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -1989,7 +1989,7 @@ __gnat_error_handler (int sig, siginfo_t *si, void *sc) anything else. This mechanism is only need in kernel mode. */ #if !(defined (__RTP__) || defined (VTHREADS)) && ((CPU == PPCE500V2) || (CPU == PPC85XX)) - register unsigned msr; + unsigned msr; /* Read the MSR value */ asm volatile ("mfmsr %0" : "=r" (msr)); /* Force the SPE bit if not set. */ diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h index 9688fb6..25a2812 100644 --- a/gcc/config/arm/aout.h +++ b/gcc/config/arm/aout.h @@ -257,7 +257,7 @@ #define ASM_OUTPUT_ALIGN(STREAM, POWER) \ do \ { \ - register int amount = 1 << (POWER); \ + int amount = 1 << (POWER); \ \ if (amount == 2) \ fprintf (STREAM, "\t.even\n"); \ diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index a000b7a..698dd87 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -1773,8 +1773,8 @@ function_arg_regno_p (int n) int symbolic_reference_mentioned_p (rtx op) { - register const char *fmt; - register int i; + const char *fmt; + int i; if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) return 1; @@ -1784,7 +1784,7 @@ symbolic_reference_mentioned_p (rtx op) { if (fmt[i] == 'E') { - register int j; + int j; for (j = XVECLEN (op, i) - 1; j >= 0; j--) if (symbolic_reference_mentioned_p (XVECEXP (op, i, j))) diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index b60daa7..f248294 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -1394,7 +1394,7 @@ epiphany_print_operand (FILE *file, rtx x, int code) static void epiphany_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr) { - register rtx base, index = 0; + rtx base, index = 0; int offset = 0; switch (GET_CODE (addr)) diff --git a/gcc/config/iq2000/iq2000.md b/gcc/config/iq2000/iq2000.md index fd25e05..4637703 100644 --- a/gcc/config/iq2000/iq2000.md +++ b/gcc/config/iq2000/iq2000.md @@ -1553,7 +1553,7 @@ "" "* { - register rtx target = operands[0]; + rtx target = operands[0]; if (GET_CODE (target) == CONST_INT) return \"li\\t%@,%0\\n\\tjalr\\t%2,%@\"; @@ -1641,7 +1641,7 @@ "" "* { - register rtx target = operands[1]; + rtx target = operands[1]; if (GET_CODE (target) == CONST_INT) return \"li\\t%@,%1\\n\\tjalr\\t%3,%@\"; @@ -1678,7 +1678,7 @@ "" "* { - register rtx target = operands[1]; + rtx target = operands[1]; if (GET_CODE (target) == CONST_INT) return \"li\\t%@,%1\\n\\tjalr\\t%4,%@\"; diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index b444db1..6e8f367 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -991,7 +991,7 @@ static rtx microblaze_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, machine_mode mode ATTRIBUTE_UNUSED) { - register rtx xinsn = x, result; + rtx xinsn = x, result; if (GET_CODE (xinsn) == CONST && flag_pic && pic_address_needs_scratch (xinsn)) @@ -1011,10 +1011,10 @@ microblaze_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, if (GET_CODE (xinsn) == PLUS) { - register rtx xplus0 = XEXP (xinsn, 0); - register rtx xplus1 = XEXP (xinsn, 1); - register enum rtx_code code0 = GET_CODE (xplus0); - register enum rtx_code code1 = GET_CODE (xplus1); + rtx xplus0 = XEXP (xinsn, 0); + rtx xplus1 = XEXP (xinsn, 1); + enum rtx_code code0 = GET_CODE (xplus0); + enum rtx_code code1 = GET_CODE (xplus1); if (code0 != REG && code1 == REG) { @@ -1736,9 +1736,9 @@ microblaze_version_to_int (const char *version) static void microblaze_option_override (void) { - register int i, start; - register int regno; - register machine_mode mode; + int i, start; + int regno; + machine_mode mode; int ver; microblaze_section_threshold = (global_options_set.x_g_switch_value @@ -1891,11 +1891,11 @@ microblaze_option_override (void) for (mode = VOIDmode; mode != MAX_MACHINE_MODE; mode = (machine_mode) ((int) mode + 1)) { - register int size = GET_MODE_SIZE (mode); + int size = GET_MODE_SIZE (mode); for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - register int ok; + int ok; if (mode == CCmode) { @@ -2267,7 +2267,7 @@ microblaze_initial_elimination_offset (int from, int to) void print_operand (FILE * file, rtx op, int letter) { - register enum rtx_code code; + enum rtx_code code; if (PRINT_OPERAND_PUNCT_VALID_P (letter)) { @@ -2406,7 +2406,7 @@ print_operand (FILE * file, rtx op, int letter) else if (code == REG || code == SUBREG) { - register int regnum; + int regnum; if (code == REG) regnum = REGNO (op); @@ -2431,7 +2431,7 @@ print_operand (FILE * file, rtx op, int letter) rtx mem_reg = XEXP (op, 0); if (GET_CODE (mem_reg) == REG) { - register int regnum = REGNO (mem_reg); + int regnum = REGNO (mem_reg); fprintf (file, "%s", reg_names[regnum]); } } diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md index 472ef4c..6d77752 100644 --- a/gcc/config/microblaze/microblaze.md +++ b/gcc/config/microblaze/microblaze.md @@ -2107,8 +2107,8 @@ (use (reg:SI R_GOT))] "flag_pic" { - register rtx target2 = gen_rtx_REG (Pmode, - GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); + rtx target2 + = gen_rtx_REG (Pmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); gen_rtx_CLOBBER (VOIDmode, target2); return "brlid\tr15,%0\;%#"; } @@ -2122,9 +2122,9 @@ (clobber (reg:SI R_SR))] "" { - register rtx target = operands[0]; - register rtx target2 = gen_rtx_REG (Pmode, - GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); + rtx target = operands[0]; + rtx target2 + = gen_rtx_REG (Pmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); if (GET_CODE (target) == SYMBOL_REF) { if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) { gen_rtx_CLOBBER (VOIDmode, target2); @@ -2216,7 +2216,8 @@ (use (match_operand:SI 4 "register_operand"))] "flag_pic" { - register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); + rtx target2 + = gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); gen_rtx_CLOBBER (VOIDmode,target2); return "brlid\tr15,%1\;%#"; @@ -2232,8 +2233,9 @@ (clobber (match_operand:SI 3 "register_operand" "=d"))] "" { - register rtx target = operands[1]; - register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); + rtx target = operands[1]; + rtx target2 + = gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM); if (GET_CODE (target) == SYMBOL_REF) { -- cgit v1.1 From 0e1fd432e9cd5a2a4703c9ef9cc61255ea22cc49 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Fri, 21 May 2021 16:12:58 +0000 Subject: arm: Auto-vectorization for MVE: vaddv This patch adds support for the reduc_plus_scal optab with MVE, which maps to the vaddv instruction. It moves the reduc_plus_scal_ expander from neon.md to vec-common.md and adds support for MVE to it. Since vaddv uses a 32-bits accumulator, we have to truncate it's result. For instance: int32_t test__s8x16 (int8_t *a) { int i; int8_t result = 0; for (i=0; i<16; i++) { result += a[i]; } return result; } is compiled into: vldrb.8 q3, [r0] vaddv.s8 r0, q3 sxtb r0, r0 bx lr If we used uint8_t instead of int8_t, we still use vaddv.s8 r0, q3, but truncate with uxtb r0, r0. 2021-05-25 Christophe Lyon gcc/ * config/arm/mve.md (mve_vaddvq_): Prefix with '@'. * config/arm/neon.md (reduc_plus_scal_): Move to .. * config/arm/vec-common.md: .. here. Add support for MVE. gcc/testsuite/ * gcc.target/arm/simd/mve-vaddv-1.c: New test. --- gcc/config/arm/mve.md | 2 +- gcc/config/arm/neon.md | 13 ------------- gcc/config/arm/vec-common.md | 26 +++++++++++++++++++++++++ gcc/testsuite/gcc.target/arm/simd/mve-vaddv-1.c | 26 +++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/simd/mve-vaddv-1.c (limited to 'gcc') diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 133ebe9..0a6ba80 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -464,7 +464,7 @@ ;; ;; [vaddvq_s, vaddvq_u]) ;; -(define_insn "mve_vaddvq_" +(define_insn "@mve_vaddvq_" [ (set (match_operand:SI 0 "s_register_operand" "=Te") (unspec:SI [(match_operand:MVE_2 1 "s_register_operand" "w")] diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 977adef..6a65733 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1161,19 +1161,6 @@ DONE; }) -(define_expand "reduc_plus_scal_" - [(match_operand: 0 "nonimmediate_operand") - (match_operand:VQ 1 "s_register_operand")] - "ARM_HAVE_NEON__ARITH && !BYTES_BIG_ENDIAN" -{ - rtx step1 = gen_reg_rtx (mode); - - emit_insn (gen_quad_halves_plus (step1, operands[1])); - emit_insn (gen_reduc_plus_scal_ (operands[0], step1)); - - DONE; -}) - (define_expand "reduc_plus_scal_v2di" [(match_operand:DI 0 "nonimmediate_operand") (match_operand:V2DI 1 "s_register_operand")] diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md index e8b2901..8e35151 100644 --- a/gcc/config/arm/vec-common.md +++ b/gcc/config/arm/vec-common.md @@ -539,3 +539,29 @@ emit_insn (gen_mve_vst4q (operands[0], operands[1])); DONE; }) + +(define_expand "reduc_plus_scal_" + [(match_operand: 0 "nonimmediate_operand") + (match_operand:VQ 1 "s_register_operand")] + "ARM_HAVE__ARITH + && !(TARGET_HAVE_MVE && FLOAT_MODE_P (mode)) + && !BYTES_BIG_ENDIAN" +{ + if (TARGET_NEON) + { + rtx step1 = gen_reg_rtx (mode); + + emit_insn (gen_quad_halves_plus (step1, operands[1])); + emit_insn (gen_reduc_plus_scal_ (operands[0], step1)); + } + else + { + /* vaddv generates a 32 bits accumulator. */ + rtx op0 = gen_reg_rtx (SImode); + + emit_insn (gen_mve_vaddvq (VADDVQ_S, mode, op0, operands[1])); + emit_move_insn (operands[0], gen_lowpart (mode, op0)); + } + + DONE; +}) diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vaddv-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vaddv-1.c new file mode 100644 index 0000000..b6b0bc3 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vaddv-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O3" } */ + +#include + +#define FUNC(SIGN, TYPE, BITS, NB) \ + TYPE##32_t test_ ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t *a) { \ + int i; \ + TYPE##BITS##_t result = 0; \ + for (i=0; i Date: Wed, 26 May 2021 19:12:05 +0200 Subject: Warn on type punning that toggles scalar storage order As documented in the manual, we do not support type punning that toggles the scalar storage order, so this adds a warning for the case of unions. gcc/c/ PR c/100653 * c-decl.c (finish_struct): Warn for a union containing an aggregate field with a differing scalar storage order. gcc/testsuite/ * gcc.dg/sso-13.c: New test. --- gcc/c/c-decl.c | 7 +++++++ gcc/testsuite/gcc.dg/sso-13.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sso-13.c (limited to 'gcc') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 53b2b5b..3c7b306 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -8853,6 +8853,13 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, = c_build_qualified_type (fmain_type, TYPE_QUALS (ftype)); } } + + if (TREE_CODE (t) == UNION_TYPE + && AGGREGATE_TYPE_P (TREE_TYPE (field)) + && TYPE_REVERSE_STORAGE_ORDER (t) + != TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (field))) + warning_at (DECL_SOURCE_LOCATION (field), OPT_Wscalar_storage_order, + "type punning toggles scalar storage order"); } /* Now we have the truly final field list. diff --git a/gcc/testsuite/gcc.dg/sso-13.c b/gcc/testsuite/gcc.dg/sso-13.c new file mode 100644 index 0000000..ddfde00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-13.c @@ -0,0 +1,24 @@ +/* Test support of scalar_storage_order attribute */ + +/* { dg-do compile } */ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) +#else +#define REV_ENDIANNESS __attribute__((scalar_storage_order("little-endian"))) +#endif + +typedef struct tIp6Addr +{ + unsigned int s6_addr32[4]; +} tIp6Addr; + +struct _tBeTimNetAddr +{ + unsigned char isIPv4; + union + { + unsigned int addr; + tIp6Addr addr6; /* { dg-warning "type punning toggles" } */ + } REV_ENDIANNESS u; +} REV_ENDIANNESS; -- cgit v1.1 From 7f0cfeb1ac580edf629874146b349fe7ad7e7718 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 26 May 2021 18:45:09 +0200 Subject: Fix gcc-bootstrap issue ... or at least try to. 2021-05-26 Bernd Edlinger * gimple-range-gori.cc (range_def_chain::register_dependency): Resize m_def_chain when needed. --- gcc/gimple-range-gori.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index a4c4bf5..c51e6ce 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -176,6 +176,8 @@ range_def_chain::register_dependency (tree name, tree dep, basic_block bb) return; unsigned v = SSA_NAME_VERSION (name); + if (v >= m_def_chain.length ()) + m_def_chain.safe_grow_cleared (num_ssa_names + 1); struct rdc &src = m_def_chain[v]; gimple *def_stmt = SSA_NAME_DEF_STMT (dep); unsigned dep_v = SSA_NAME_VERSION (dep); -- cgit v1.1 From 28484d00c45b7bf094a22a4fddf9ffdc7482c7e1 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 26 May 2021 20:44:49 +0200 Subject: i386: Autovectorize 4-byte vectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2021-05-26 Uroš Bizjak gcc/ * config/i386/i386.c (ix86_autovectorize_vector_modes): Add V4QImode and V16QImode for TARGET_SSE2. * doc/sourcebuild.texi (Vector-specific attributes): Add vect64 and vect32 description. gcc/testsuite/ * lib/target-supports.exp (check_effective_target_vect32): New. (available_vector_sizes): Append 32 for x86 targets. * gcc.dg/vect/pr71264.c (dg-final): Xfail scan dump for vect32 targets. * gcc.dg/vect/slp-28.c (dg-final): Adjust dumps for vect32 targets. * gcc.dg/vect/slp-3.c (dg-final): Ditto. * gcc.target/i386/pr100637-3b.c: New test. * gcc.target/i386/pr100637-3w.c: Ditto. * gcc.target/i386/pr100637-4b.c: Ditto. * gcc.target/i386/pr100637-4w.c: Ditto. --- gcc/config/i386/i386.c | 5 +- gcc/doc/sourcebuild.texi | 6 ++ gcc/testsuite/gcc.dg/vect/pr71264.c | 3 +- gcc/testsuite/gcc.dg/vect/slp-28.c | 5 +- gcc/testsuite/gcc.dg/vect/slp-3.c | 8 +-- gcc/testsuite/gcc.target/i386/pr100637-3b.c | 56 +++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr100637-3w.c | 86 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr100637-4b.c | 19 +++++++ gcc/testsuite/gcc.target/i386/pr100637-4w.c | 19 +++++++ gcc/testsuite/lib/target-supports.exp | 7 +++ 10 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr100637-3b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr100637-3w.c create mode 100644 gcc/testsuite/gcc.target/i386/pr100637-4b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr100637-4w.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 28e6113..04649b4 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22190,12 +22190,15 @@ ix86_autovectorize_vector_modes (vector_modes *modes, bool all) modes->safe_push (V16QImode); modes->safe_push (V32QImode); } - else if (TARGET_MMX_WITH_SSE) + else if (TARGET_SSE2) modes->safe_push (V16QImode); if (TARGET_MMX_WITH_SSE) modes->safe_push (V8QImode); + if (TARGET_SSE2) + modes->safe_push (V4QImode); + return 0; } diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index cf309874..16c6a3b 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1740,6 +1740,12 @@ circumstances. @item vect_variable_length Target has variable-length vectors. +@item vect64 +Target supports vectors of 64 bits. + +@item vect32 +Target supports vectors of 32 bits. + @item vect_widen_sum_hi_to_si Target supports a vector widening summation of @code{short} operands into @code{int} results, or can promote (unpack) from @code{short} diff --git a/gcc/testsuite/gcc.dg/vect/pr71264.c b/gcc/testsuite/gcc.dg/vect/pr71264.c index dc849bf..1381e0e 100644 --- a/gcc/testsuite/gcc.dg/vect/pr71264.c +++ b/gcc/testsuite/gcc.dg/vect/pr71264.c @@ -19,5 +19,4 @@ void test(uint8_t *ptr, uint8_t *mask) } } -/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail s390*-*-* sparc*-*-* } } } */ - +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail { { s390*-*-* sparc*-*-* } || vect32 } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-28.c b/gcc/testsuite/gcc.dg/vect/slp-28.c index 7778bad..0bb5f0eb 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-28.c +++ b/gcc/testsuite/gcc.dg/vect/slp-28.c @@ -88,6 +88,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect32 } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { ! vect32 } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-3.c b/gcc/testsuite/gcc.dg/vect/slp-3.c index 46ab584..80ded18 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-3.c +++ b/gcc/testsuite/gcc.dg/vect/slp-3.c @@ -141,8 +141,8 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! vect_partial_vectors } } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_partial_vectors } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! vect_partial_vectors } } } }*/ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target vect_partial_vectors } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! { vect_partial_vectors || vect32 } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target { vect_partial_vectors || vect32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! { vect_partial_vectors || vect32 } } } } }*/ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_partial_vectors || vect32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100637-3b.c b/gcc/testsuite/gcc.target/i386/pr100637-3b.c new file mode 100644 index 0000000..16df700 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100637-3b.c @@ -0,0 +1,56 @@ +/* PR target/100637 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -msse4" } */ + +char r[4], a[4], b[4]; +unsigned char ur[4], ua[4], ub[4]; + +void maxs (void) +{ + int i; + + for (i = 0; i < 4; i++) + r[i] = a[i] > b[i] ? a[i] : b[i]; +} + +/* { dg-final { scan-assembler "pmaxsb" } } */ + +void maxu (void) +{ + int i; + + for (i = 0; i < 4; i++) + ur[i] = ua[i] > ub[i] ? ua[i] : ub[i]; +} + +/* { dg-final { scan-assembler "pmaxub" } } */ + +void mins (void) +{ + int i; + + for (i = 0; i < 4; i++) + r[i] = a[i] < b[i] ? a[i] : b[i]; +} + +/* { dg-final { scan-assembler "pminsb" } } */ + +void minu (void) +{ + int i; + + for (i = 0; i < 4; i++) + ur[i] = ua[i] < ub[i] ? ua[i] : ub[i]; +} + +/* { dg-final { scan-assembler "pminub" } } */ + +void _abs (void) +{ + int i; + + for (i = 0; i < 4; i++) + r[i] = a[i] < 0 ? -a[i] : a[i]; +} + +/* { dg-final { scan-assembler "pabsb" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100637-3w.c b/gcc/testsuite/gcc.target/i386/pr100637-3w.c new file mode 100644 index 0000000..7f1882e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100637-3w.c @@ -0,0 +1,86 @@ +/* PR target/100637 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -msse4" } */ + +short r[2], a[2], b[2]; +unsigned short ur[2], ua[2], ub[2]; + +void mulh (void) +{ + int i; + + for (i = 0; i < 2; i++) + r[i] = ((int) a[i] * b[i]) >> 16; +} + +/* { dg-final { scan-assembler "pmulhw" { xfail *-*-* } } } */ + +void mulhu (void) +{ + int i; + + for (i = 0; i < 2; i++) + ur[i] = ((unsigned int) ua[i] * ub[i]) >> 16; +} + +/* { dg-final { scan-assembler "pmulhuw" { xfail *-*-* } } } */ + +void mulhrs (void) +{ + int i; + + for (i = 0; i < 2; i++) + r[i] = ((((int) a[i] * b[i]) >> 14) + 1) >> 1; +} + +/* { dg-final { scan-assembler "pmulhrsw" } } */ + +void maxs (void) +{ + int i; + + for (i = 0; i < 2; i++) + r[i] = a[i] > b[i] ? a[i] : b[i]; +} + +/* { dg-final { scan-assembler "pmaxsw" } } */ + +void maxu (void) +{ + int i; + + for (i = 0; i < 2; i++) + ur[i] = ua[i] > ub[i] ? ua[i] : ub[i]; +} + +/* { dg-final { scan-assembler "pmaxuw" } } */ + +void mins (void) +{ + int i; + + for (i = 0; i < 2; i++) + r[i] = a[i] < b[i] ? a[i] : b[i]; +} + +/* { dg-final { scan-assembler "pminsw" } } */ + +void minu (void) +{ + int i; + + for (i = 0; i < 2; i++) + ur[i] = ua[i] < ub[i] ? ua[i] : ub[i]; +} + +/* { dg-final { scan-assembler "pminuw" } } */ + +void _abs (void) +{ + int i; + + for (i = 0; i < 2; i++) + r[i] = a[i] < 0 ? -a[i] : a[i]; +} + +/* { dg-final { scan-assembler "pabsw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100637-4b.c b/gcc/testsuite/gcc.target/i386/pr100637-4b.c new file mode 100644 index 0000000..198e3dd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100637-4b.c @@ -0,0 +1,19 @@ +/* PR target/100637 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -msse2" } */ + +typedef char T; + +#define M 4 + +extern T a[M], b[M], s1[M], s2[M], r[M]; + +void foo (void) +{ + int j; + + for (j = 0; j < M; j++) + r[j] = (a[j] < b[j]) ? s1[j] : s2[j]; +} + +/* { dg-final { scan-assembler "pcmpgtb" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100637-4w.c b/gcc/testsuite/gcc.target/i386/pr100637-4w.c new file mode 100644 index 0000000..0f5dacc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr100637-4w.c @@ -0,0 +1,19 @@ +/* PR target/100637 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -msse2" } */ + +typedef short T; + +#define M 2 + +extern T a[M], b[M], s1[M], s2[M], r[M]; + +void foo (void) +{ + int j; + + for (j = 0; j < M; j++) + r[j] = (a[j] < b[j]) ? s1[j] : s2[j]; +} + +/* { dg-final { scan-assembler "pcmpgtw" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 849f1bb..7f78c55 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -7626,6 +7626,7 @@ proc available_vector_sizes { } { if { ![is-effective-target ia32] } { lappend result 64 } + lappend result 32 } elseif { [istarget sparc*-*-*] } { lappend result 64 } elseif { [istarget amdgcn*-*-*] } { @@ -7655,6 +7656,12 @@ proc check_effective_target_vect64 { } { return [expr { [lsearch -exact [available_vector_sizes] 64] >= 0 }] } +# Return 1 if the target supports vectors of 32 bits. + +proc check_effective_target_vect32 { } { + return [expr { [lsearch -exact [available_vector_sizes] 32] >= 0 }] +} + # Return 1 if the target supports vector copysignf calls. proc check_effective_target_vect_call_copysignf { } { -- cgit v1.1 From 586d6f7aee0ba9faf3d9b7afd6ff89d57763a775 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 19 May 2021 18:27:05 +0200 Subject: Common API for accessing global and on-demand ranges. This patch provides a generic API for accessing global ranges. It is meant to replace get_range_info() and get_ptr_nonnull() with one common interface. It uses the same API as the ranger (class range_query), so there will now be one API for accessing local and global ranges alike. Follow-up patches will convert all users of get_range_info and get_ptr_nonnull to this API. For get_range_info, instead of: if (!POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_RANGE_INFO (name)) get_range_info (name, vr); You can now do: get_range_query (cfun)->range_of_expr (vr, name, [stmt]); ...as well as any other of the range_query methods (range_on_edge, range_of_stmt, value_of_expr, value_on_edge, value_on_stmt, etc). As per the API, range_of_expr will work on constants, SSA names, and anything we support in irange::supports_type_p(). For pointers, the interface is the same, so instead of: else if (POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_PTR_INFO (name)) { if (get_ptr_nonnull (name)) stuff(); } One can do: get_range_query (cfun)->range_of_expr (vr, name, [stmt]); if (vr.nonzero_p ()) stuff (); Along with this interface, we are providing a mechanism by which a pass can use an on-demand ranger transparently, without having to change its code. Of course, this assumes all get_range_info() and get_ptr_nonnull() users have been converted to the new API, which follow-up patches will do. If a pass would prefer to use an on-demand ranger with finer grained and context aware ranges, all it would have to do is call enable_ranger() at the beginning of the pass, and disable_ranger() at the end of the pass. Note, that to use context aware ranges, any user of range_of_expr() would need to pass additional context. For example, the optional gimple statement (or perhaps use range_on_edge or range_of_stmt). The observant reader will note that get_range_query is tied to a struct function, which may not be available in certain contexts, such as at RTL time, gimple-fold, or some other places where we may or may not have cfun set. For cases where we are sure there is no function, you can use get_global_range_query() instead of get_range_query(fun). The API is the same. For cases where a function may be called with or without a function, you could use the following idiom: range_query *query = cfun ? get_range_query (cfun) : get_global_range_query (); query->range_of_expr (range, expr, [stmt]); The default range query obtained by get_range_query() is the global range query, unless the user has enabled an on-demand ranger with enable_ranger(), in which case it will use the currently active ranger. That is, until disable_ranger() is called, at which point, we revert back to global ranges. We think this provides a generic way of accessing ranges, both globally and locally, without having to keep track of types, SSA_NAME_RANGE_INFO, and SSA_NAME_PTR_INFO. We also hope this can be used to transition passes from global to on-demand ranges when appropriate. gcc/ChangeLog: * function.c (allocate_struct_function): Set cfun->x_range_query. * function.h (struct function): Declare x_range_query. (get_range_query): New. (get_global_range_query): New. * gimple-range-cache.cc (ssa_global_cache::ssa_global_cache): Remove call to safe_grow_cleared. * gimple-range.cc (get_range_global): New. (gimple_range_global): Move from gimple-range.h. (get_global_range_query): New. (global_range_query::range_of_expr): New. (enable_ranger): New. (disable_ranger): New. * gimple-range.h (gimple_range_global): Move to gimple-range.cc. (class global_range_query): New. (enable_ranger): New. (disable_ranger): New. * gimple-ssa-evrp.c (evrp_folder::~evrp_folder): Rename dump_all_value_ranges to dump. * tree-vrp.c (vrp_prop::finalize): Same. * value-query.cc (range_query::dump): New. * value-query.h (range_query::dump): New. * vr-values.c (vr_values::dump_all_value_ranges): Rename to... (vr_values::dump): ...this. * vr-values.h (class vr_values): Rename dump_all_value_ranges to dump and make virtual. --- gcc/function.c | 4 ++ gcc/function.h | 17 +++++++ gcc/gimple-range-cache.cc | 1 - gcc/gimple-range.cc | 126 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/gimple-range.h | 60 ++++++---------------- gcc/gimple-ssa-evrp.c | 2 +- gcc/tree-vrp.c | 2 +- gcc/value-query.cc | 5 ++ gcc/value-query.h | 1 + gcc/vr-values.c | 2 +- gcc/vr-values.h | 2 +- 11 files changed, 172 insertions(+), 50 deletions(-) (limited to 'gcc') diff --git a/gcc/function.c b/gcc/function.c index fc7b147..6757695 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "options.h" #include "function-abi.h" +#include "value-range.h" +#include "gimple-range.h" /* So we can assign to cfun in this file. */ #undef cfun @@ -4856,6 +4858,8 @@ allocate_struct_function (tree fndecl, bool abstract_p) binding annotations among them. */ cfun->debug_nonbind_markers = lang_hooks.emits_begin_stmt && MAY_HAVE_DEBUG_MARKER_STMTS; + + cfun->x_range_query = &global_ranges; } /* This is like allocate_struct_function, but pushes a new cfun for FNDECL diff --git a/gcc/function.h b/gcc/function.h index 66cfa97..0db5177 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -157,6 +157,7 @@ struct GTY(()) rtl_eh { struct gimple_df; struct call_site_record_d; struct dw_fde_node; +class range_query; struct GTY(()) varasm_status { /* If we're using a per-function constant pool, this is it. */ @@ -309,6 +310,11 @@ struct GTY(()) function { debugging is enabled. */ struct dw_fde_node *fde; + /* Range query mechanism for functions. The default is to pick up + global ranges. If a pass wants on-demand ranges OTOH, it must + call enable/disable_ranger(). */ + range_query * GTY ((skip)) x_range_query; + /* Last statement uid. */ int last_stmt_uid; @@ -712,4 +718,15 @@ extern const char *current_function_name (void); extern void used_types_insert (tree); +/* Returns the currently active range access class. When there is no active + range class, global ranges are used. */ + +inline range_query * +get_range_query (struct function *fun) +{ + return fun->x_range_query; +} + +extern range_query *get_global_range_query (); + #endif /* GCC_FUNCTION_H */ diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 3969c4d..889cac1 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -384,7 +384,6 @@ block_range_cache::dump (FILE *f, basic_block bb, bool print_varying) ssa_global_cache::ssa_global_cache () { m_tab.create (0); - m_tab.safe_grow_cleared (num_ssa_names); m_irange_allocator = new irange_allocator; } diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index e2d24d6..e351a84 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1440,3 +1440,129 @@ trace_ranger::range_of_expr (irange &r, tree name, gimple *s) return trailer (idx, "range_of_expr", res, name, r); } + +// Return the legacy global range for NAME if it has one, otherwise +// return VARYING. + +static void +get_range_global (irange &r, tree name) +{ + tree type = TREE_TYPE (name); + + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + tree sym = SSA_NAME_VAR (name); + // Adapted from vr_values::get_lattice_entry(). + // Use a range from an SSA_NAME's available range. + if (TREE_CODE (sym) == PARM_DECL) + { + // Try to use the "nonnull" attribute to create ~[0, 0] + // anti-ranges for pointers. Note that this is only valid with + // default definitions of PARM_DECLs. + if (POINTER_TYPE_P (type) + && ((cfun && nonnull_arg_p (sym)) || get_ptr_nonnull (name))) + r.set_nonzero (type); + else if (INTEGRAL_TYPE_P (type)) + { + get_range_info (name, r); + if (r.undefined_p ()) + r.set_varying (type); + } + else + r.set_varying (type); + } + // If this is a local automatic with no definition, use undefined. + else if (TREE_CODE (sym) != RESULT_DECL) + r.set_undefined (); + else + r.set_varying (type); + } + else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name)) + { + get_range_info (name, r); + if (r.undefined_p ()) + r.set_varying (type); + } + else if (POINTER_TYPE_P (type) && SSA_NAME_PTR_INFO (name)) + { + if (get_ptr_nonnull (name)) + r.set_nonzero (type); + else + r.set_varying (type); + } + else + r.set_varying (type); +} + +// ?? Like above, but only for default definitions of NAME. This is +// so VRP passes using ranger do not start with known ranges, +// otherwise we'd eliminate builtin_unreachables too early because of +// inlining. +// +// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has +// all of its unreachable calls removed too early. We should +// investigate whether we should just adjust the test above. + +value_range +gimple_range_global (tree name) +{ + gcc_checking_assert (gimple_range_ssa_p (name)); + tree type = TREE_TYPE (name); + + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + value_range vr; + get_range_global (vr, name); + return vr; + } + return value_range (type); +} + +// ---------------------------------------------- +// global_range_query implementation. + +global_range_query global_ranges; + +// Like get_range_query, but for accessing global ranges. + +range_query * +get_global_range_query () +{ + return &global_ranges; +} + +bool +global_range_query::range_of_expr (irange &r, tree expr, gimple *) +{ + tree type = TREE_TYPE (expr); + + if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr)) + return get_tree_range (r, expr); + + get_range_global (r, expr); + + return true; +} + +gimple_ranger * +enable_ranger (struct function *fun) +{ + gimple_ranger *r; + + if (param_evrp_mode & EVRP_MODE_TRACE) + r = new trace_ranger; + else + r = new gimple_ranger; + + fun->x_range_query = r; + + return r; +} + +void +disable_ranger (struct function *fun) +{ + delete fun->x_range_query; + + fun->x_range_query = &global_ranges; +} diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 707dcfe..23734c6 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -65,7 +65,7 @@ public: virtual void range_on_entry (irange &r, basic_block bb, tree name); virtual void range_on_exit (irange &r, basic_block bb, tree name); void export_global_ranges (); - void dump (FILE *f); + virtual void dump (FILE *f) OVERRIDE; void dump_bb (FILE *f, basic_block bb); protected: bool fold_range_internal (irange &r, gimple *s, tree name); @@ -227,50 +227,6 @@ range_compatible_p (tree type1, tree type2) && TYPE_SIGN (type1) == TYPE_SIGN (type2)); } -// Return the legacy GCC global range for NAME if it has one, otherwise -// return VARYING. - -static inline value_range -gimple_range_global (tree name) -{ - gcc_checking_assert (gimple_range_ssa_p (name)); - tree type = TREE_TYPE (name); - - if (SSA_NAME_IS_DEFAULT_DEF (name)) - { - tree sym = SSA_NAME_VAR (name); - // Adapted from vr_values::get_lattice_entry(). - // Use a range from an SSA_NAME's available range. - if (TREE_CODE (sym) == PARM_DECL) - { - // Try to use the "nonnull" attribute to create ~[0, 0] - // anti-ranges for pointers. Note that this is only valid with - // default definitions of PARM_DECLs. - if (POINTER_TYPE_P (type) - && (nonnull_arg_p (sym) || get_ptr_nonnull (name))) - { - value_range r; - r.set_nonzero (type); - return r; - } - else if (INTEGRAL_TYPE_P (type)) - { - value_range r; - get_range_info (name, r); - if (r.undefined_p ()) - r.set_varying (type); - return r; - } - } - // If this is a local automatic with no definition, use undefined. - else if (TREE_CODE (sym) != RESULT_DECL) - return value_range (); - } - // Otherwise return range for the type. - return value_range (type); -} - - // This class overloads the ranger routines to provide tracing facilties // Entry and exit values to each of the APIs is placed in the dumpfile. @@ -296,4 +252,18 @@ private: // Flag to enable debugging the various internal Caches. #define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_DEBUG)) +// Global ranges for SSA names using SSA_NAME_RANGE_INFO. + +class global_range_query : public range_query +{ +public: + bool range_of_expr (irange &r, tree expr, gimple * = NULL) OVERRIDE; +}; + +extern global_range_query global_ranges; +extern value_range gimple_range_global (tree name); + +extern gimple_ranger *enable_ranger (struct function *); +extern void disable_ranger (struct function *); + #endif // GCC_GIMPLE_RANGE_STMT_H diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 5f566ae..829fdcd 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -60,7 +60,7 @@ public: if (dump_file) { fprintf (dump_file, "\nValue ranges after Early VRP:\n\n"); - m_range_analyzer.dump_all_value_ranges (dump_file); + m_range_analyzer.dump (dump_file); fprintf (dump_file, "\n"); } } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 12e6e6f..b0f1c47 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4044,7 +4044,7 @@ vrp_prop::finalize () if (dump_file) { fprintf (dump_file, "\nValue ranges after VRP:\n\n"); - m_vr_values->dump_all_value_ranges (dump_file); + m_vr_values->dump (dump_file); fprintf (dump_file, "\n"); } diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 4bb0897..509d2d3 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -135,6 +135,11 @@ range_query::value_of_stmt (gimple *stmt, tree name) } +void +range_query::dump (FILE *) +{ +} + // valuation_query support routines for value_range_equiv's. class equiv_allocator : public object_allocator diff --git a/gcc/value-query.h b/gcc/value-query.h index e2cbc68..5eff931 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -95,6 +95,7 @@ public: // rewrite all uses of it to the above API. virtual const class value_range_equiv *get_value_range (const_tree, gimple * = NULL); + virtual void dump (FILE *); protected: class value_range_equiv *allocate_value_range_equiv (); diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 02bc0db..e0c8844 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1819,7 +1819,7 @@ vr_values::adjust_range_with_scev (value_range_equiv *vr, class loop *loop, /* Dump value ranges of all SSA_NAMEs to FILE. */ void -vr_values::dump_all_value_ranges (FILE *file) +vr_values::dump (FILE *file) { size_t i; diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 8c1b2e0..81b9131 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -116,7 +116,7 @@ class vr_values : public range_query tree op_with_constant_singleton_value_range (tree); void adjust_range_with_scev (value_range_equiv *, class loop *, gimple *, tree); - void dump_all_value_ranges (FILE *); + virtual void dump (FILE *) OVERRIDE; void extract_range_for_var_from_comparison_expr (tree, enum tree_code, tree, tree, -- cgit v1.1 From 57bf375151111ba880e6060708c8b18a682f5b20 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 25 May 2021 17:44:51 +0200 Subject: Convert evrp pass to get_range_query. gcc/ChangeLog: * gimple-ssa-evrp.c (rvrp_folder::rvrp_folder): Call enable_ranger. (rvrp_folder::~rvrp_folder): Call disable_ranger. (hybrid_folder::hybrid_folder): Call enable_ranger. (hybrid_folder::~hybrid_folder): Call disable_ranger. --- gcc/gimple-ssa-evrp.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 829fdcd..118d103 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -117,11 +117,8 @@ class rvrp_folder : public substitute_and_fold_engine public: rvrp_folder () : substitute_and_fold_engine (), m_simplifier () - { - if (param_evrp_mode & EVRP_MODE_TRACE) - m_ranger = new trace_ranger (); - else - m_ranger = new gimple_ranger (); + { + m_ranger = enable_ranger (cfun); m_simplifier.set_range_query (m_ranger); } @@ -129,7 +126,9 @@ public: { if (dump_file && (dump_flags & TDF_DETAILS)) m_ranger->dump (dump_file); - delete m_ranger; + + m_ranger->export_global_ranges (); + disable_ranger (cfun); } tree value_of_expr (tree name, gimple *s = NULL) OVERRIDE @@ -175,10 +174,7 @@ class hybrid_folder : public evrp_folder public: hybrid_folder (bool evrp_first) { - if (param_evrp_mode & EVRP_MODE_TRACE) - m_ranger = new trace_ranger (); - else - m_ranger = new gimple_ranger (); + m_ranger = enable_ranger (cfun); if (evrp_first) { @@ -196,7 +192,9 @@ public: { if (dump_file && (dump_flags & TDF_DETAILS)) m_ranger->dump (dump_file); - delete m_ranger; + + m_ranger->export_global_ranges (); + disable_ranger (cfun); } bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE -- cgit v1.1 From fe9a499cb8775cfbcea356ab0cae5c365971cf86 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 19 May 2021 18:27:47 +0200 Subject: Convert Walloca pass to get_range_query. This patch converts the Walloca pass to use an on-demand ranger accesible with get_range_query instead of having to create a ranger and pass it around. gcc/ChangeLog: * gimple-ssa-warn-alloca.c (alloca_call_type): Use get_range_query instead of query argument. (pass_walloca::execute): Enable and disable global ranger. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-55.c: Adapt for range query changes. * gcc.dg/pr80776-1.c: Same. --- gcc/gimple-ssa-warn-alloca.c | 10 ++++++---- gcc/testsuite/gcc.dg/Wstringop-overflow-55.c | 8 ++++---- gcc/testsuite/gcc.dg/pr80776-1.c | 4 +--- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c index e9a24d4..72480f1 100644 --- a/gcc/gimple-ssa-warn-alloca.c +++ b/gcc/gimple-ssa-warn-alloca.c @@ -165,7 +165,7 @@ adjusted_warn_limit (bool idx) // call was created by the gimplifier for a VLA. static class alloca_type_and_limit -alloca_call_type (range_query &query, gimple *stmt, bool is_vla) +alloca_call_type (gimple *stmt, bool is_vla) { gcc_assert (gimple_alloca_call_p (stmt)); tree len = gimple_call_arg (stmt, 0); @@ -217,7 +217,7 @@ alloca_call_type (range_query &query, gimple *stmt, bool is_vla) int_range_max r; if (warn_limit_specified_p (is_vla) && TREE_CODE (len) == SSA_NAME - && query.range_of_expr (r, len, stmt) + && get_range_query (cfun)->range_of_expr (r, len, stmt) && !r.varying_p ()) { // The invalid bits are anything outside of [0, MAX_SIZE]. @@ -256,7 +256,7 @@ in_loop_p (gimple *stmt) unsigned int pass_walloca::execute (function *fun) { - gimple_ranger ranger; + gimple_ranger *ranger = enable_ranger (fun); basic_block bb; FOR_EACH_BB_FN (bb, fun) { @@ -290,7 +290,7 @@ pass_walloca::execute (function *fun) continue; class alloca_type_and_limit t - = alloca_call_type (ranger, stmt, is_vla); + = alloca_call_type (stmt, is_vla); unsigned HOST_WIDE_INT adjusted_alloca_limit = adjusted_warn_limit (false); @@ -383,6 +383,8 @@ pass_walloca::execute (function *fun) } } } + ranger->export_global_ranges (); + disable_ranger (fun); return 0; } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index 25f5b82..8df5cb6 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -66,7 +66,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -74,7 +74,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } @@ -83,7 +83,7 @@ void warn_int_anti_range (int i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -91,7 +91,7 @@ void warn_int_anti_range (int i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index af41c0c..f3a120b 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,7 +17,5 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - /* The correctness bits for [E]VRP cannot handle chained conditionals - when deciding to ignore a unreachable branch for setting SSA range info. */ - sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ } -- cgit v1.1 From 45f4e2b01b82c72b3a11ff4ad184d7edcf0e63d4 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 19 May 2021 18:44:08 +0200 Subject: Convert remaining passes to get_range_query. This patch converts the remaining users of get_range_info and get_ptr_nonnull to the get_range_query API. No effort was made to move passes away from VR_ANTI_RANGE, or any other use of deprecated methods. This was a straight up conversion to the new API, nothing else. gcc/ChangeLog: * builtins.c (check_nul_terminated_array): Convert to get_range_query. (expand_builtin_strnlen): Same. (determine_block_size): Same. * fold-const.c (expr_not_equal_to): Same. * gimple-fold.c (size_must_be_zero_p): Same. * gimple-match-head.c: Include gimple-range.h. * gimple-pretty-print.c (dump_ssaname_info): Convert to get_range_query. * gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): Same. * graphite-sese-to-poly.c (add_param_constraints): Same. * internal-fn.c (get_min_precision): Same. * ipa-fnsummary.c (set_switch_stmt_execution_predicate): Same. * ipa-prop.c (ipa_compute_jump_functions_for_edge): Same. * match.pd: Same. * tree-data-ref.c (split_constant_offset): Same. (dr_step_indicator): Same. * tree-dfa.c (get_ref_base_and_extent): Same. * tree-scalar-evolution.c (iv_can_overflow_p): Same. * tree-ssa-loop-niter.c (refine_value_range_using_guard): Same. (determine_value_range): Same. (record_nonwrapping_iv): Same. (infer_loop_bounds_from_signedness): Same. (scev_var_range_cant_overflow): Same. * tree-ssa-phiopt.c (two_value_replacement): Same. * tree-ssa-pre.c (insert_into_preds_of_block): Same. * tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Same. * tree-ssa-strlen.c (handle_builtin_stxncpy_strncat): Same. (get_range): Same. (dump_strlen_info): Same. (set_strlen_range): Same. (maybe_diag_stxncpy_trunc): Same. (get_len_or_size): Same. (handle_integral_assign): Same. * tree-ssa-structalias.c (find_what_p_points_to): Same. * tree-ssa-uninit.c (find_var_cmp_const): Same. * tree-switch-conversion.c (bit_test_cluster::emit): Same. * tree-vect-patterns.c (vect_get_range_info): Same. (vect_recog_divmod_pattern): Same. * tree-vrp.c (intersect_range_with_nonzero_bits): Same. (register_edge_assert_for_2): Same. (determine_value_range_1): Same. * tree.c (get_range_pos_neg): Same. * vr-values.c (vr_values::get_lattice_entry): Same. (vr_values::update_value_range): Same. (simplify_conversion_using_ranges): Same. --- gcc/builtins.c | 40 +++++++++++++------- gcc/fold-const.c | 8 +++- gcc/gimple-fold.c | 7 +++- gcc/gimple-match-head.c | 1 + gcc/gimple-pretty-print.c | 12 +++++- gcc/gimple-ssa-warn-restrict.c | 8 +++- gcc/graphite-sese-to-poly.c | 9 ++++- gcc/internal-fn.c | 14 ++++--- gcc/ipa-fnsummary.c | 11 +++++- gcc/ipa-prop.c | 16 ++++---- gcc/match.pd | 19 +++++++--- gcc/tree-data-ref.c | 24 ++++++++++-- gcc/tree-dfa.c | 14 ++++++- gcc/tree-scalar-evolution.c | 13 ++++++- gcc/tree-ssa-loop-niter.c | 81 ++++++++++++++++++++++++++-------------- gcc/tree-ssa-phiopt.c | 11 +++++- gcc/tree-ssa-pre.c | 19 ++++++---- gcc/tree-ssa-reassoc.c | 9 +++-- gcc/tree-ssa-strlen.c | 85 ++++++++++++++++++++++++------------------ gcc/tree-ssa-structalias.c | 8 ++-- gcc/tree-ssa-uninit.c | 8 +++- gcc/tree-switch-conversion.c | 10 +++-- gcc/tree-vect-patterns.c | 18 ++++++--- gcc/tree-vrp.c | 21 +++++------ gcc/tree.c | 13 ++++--- gcc/vr-values.c | 12 +++--- 26 files changed, 332 insertions(+), 159 deletions(-) (limited to 'gcc') diff --git a/gcc/builtins.c b/gcc/builtins.c index b0c880d..af1fe49b 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-outof-ssa.h" #include "attr-fnspec.h" #include "demangle.h" +#include "gimple-range.h" struct target_builtins default_target_builtins; #if SWITCHABLE_TARGET @@ -1218,14 +1219,15 @@ check_nul_terminated_array (tree expr, tree src, wide_int bndrng[2]; if (bound) { - if (TREE_CODE (bound) == INTEGER_CST) - bndrng[0] = bndrng[1] = wi::to_wide (bound); - else - { - value_range_kind rng = get_range_info (bound, bndrng, bndrng + 1); - if (rng != VR_RANGE) - return true; - } + value_range r; + + get_global_range_query ()->range_of_expr (r, bound); + + if (r.kind () != VR_RANGE) + return true; + + bndrng[0] = r.lower_bound (); + bndrng[1] = r.upper_bound (); if (exact) { @@ -3831,9 +3833,12 @@ expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode) return NULL_RTX; wide_int min, max; - enum value_range_kind rng = get_range_info (bound, &min, &max); - if (rng != VR_RANGE) + value_range r; + get_global_range_query ()->range_of_expr (r, bound); + if (r.kind () != VR_RANGE) return NULL_RTX; + min = r.lower_bound (); + max = r.upper_bound (); if (!len || TREE_CODE (len) != INTEGER_CST) { @@ -3901,7 +3906,16 @@ determine_block_size (tree len, rtx len_rtx, *probable_max_size = *max_size = GET_MODE_MASK (GET_MODE (len_rtx)); if (TREE_CODE (len) == SSA_NAME) - range_type = get_range_info (len, &min, &max); + { + value_range r; + get_global_range_query ()->range_of_expr (r, len); + range_type = r.kind (); + if (range_type != VR_UNDEFINED) + { + min = wi::to_wide (r.min ()); + max = wi::to_wide (r.max ()); + } + } if (range_type == VR_RANGE) { if (wi::fits_uhwi_p (min) && *min_size < min.to_uhwi ()) @@ -4920,8 +4934,8 @@ check_read_access (tree exp, tree src, tree bound /* = NULL_TREE */, /* If STMT is a call to an allocation function, returns the constant maximum size of the object allocated by the call represented as sizetype. If nonnull, sets RNG1[] to the range of the size. - When nonnull, uses RVALS for range information, otherwise calls - get_range_info to get it. + When nonnull, uses RVALS for range information, otherwise gets global + range info. Returns null when STMT is not a call to a valid allocation function. */ tree diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d088187..33d64bf 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vector-builder.h" #include "vec-perm-indices.h" #include "asan.h" +#include "gimple-range.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -10686,7 +10687,12 @@ expr_not_equal_to (tree t, const wide_int &w) case SSA_NAME: if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) return false; - get_range_info (t, vr); + + if (cfun) + get_range_query (cfun)->range_of_expr (vr, t); + else + get_global_range_query ()->range_of_expr (vr, t); + if (!vr.undefined_p () && !vr.contains_p (wide_int_to_tree (TREE_TYPE (t), w))) return true; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 68717cf..eaf0fb7 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -873,7 +873,12 @@ size_must_be_zero_p (tree size) value_range valid_range (build_int_cst (type, 0), wide_int_to_tree (type, ssize_max)); value_range vr; - get_range_info (size, vr); + if (cfun) + get_range_query (cfun)->range_of_expr (vr, size); + else + get_global_range_query ()->range_of_expr (vr, size); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (size)); vr.intersect (&valid_range); return vr.zero_p (); } diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index b084a3157..7112c116 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "dbgcnt.h" #include "tm.h" +#include "gimple-range.h" /* Forward declarations of the private auto-generated matchers. They expect valueized operands in canonical order and do not diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 0ef01e6..c9c0a66 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "asan.h" #include "cfgloop.h" +#include "gimple-range.h" /* Disable warnings about quoting issues in the pp_xxx calls below that (intentionally) don't follow GCC diagnostic conventions. */ @@ -2263,8 +2264,17 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc) && SSA_NAME_RANGE_INFO (node)) { wide_int min, max, nonzero_bits; - value_range_kind range_type = get_range_info (node, &min, &max); + value_range r; + get_global_range_query ()->range_of_expr (r, node); + value_range_kind range_type = r.kind (); + if (!r.undefined_p ()) + { + min = wi::to_wide (r.min ()); + max = wi::to_wide (r.max ()); + } + + // FIXME: Use irange::dump() instead. if (range_type == VR_VARYING) pp_printf (buffer, "# RANGE VR_VARYING"); else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE) diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index ad37f20..c8c9f95 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -349,7 +349,13 @@ builtin_memref::extend_offset_range (tree offset) /* There is a global version here because check_bounds_or_overlap may be called from gimple fold during gimple lowering. */ - rng = get_range_info (offset, &min, &max); + get_range_query (cfun)->range_of_expr (vr, offset, stmt); + rng = vr.kind (); + if (!vr.undefined_p ()) + { + min = wi::to_wide (vr.min ()); + max = wi::to_wide (vr.max ()); + } } if (rng == VR_ANTI_RANGE && wi::lts_p (max, min)) { diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index eebf2e0..99ea032 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -418,13 +418,18 @@ static void add_param_constraints (scop_p scop, graphite_dim_t p, tree parameter) { tree type = TREE_TYPE (parameter); + value_range r; wide_int min, max; gcc_assert (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)); if (INTEGRAL_TYPE_P (type) - && get_range_info (parameter, &min, &max) == VR_RANGE) - ; + && get_range_query (cfun)->range_of_expr (r, parameter) + && !r.undefined_p ()) + { + min = r.lower_bound (); + max = r.upper_bound (); + } else { min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)); diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index d209a52..f06c2711 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "ssa-iterators.h" #include "explow.h" #include "rtl-iter.h" +#include "gimple-range.h" /* The names of each internal function, indexed by function number. */ const char *const internal_fn_name_array[] = { @@ -680,8 +681,9 @@ get_min_precision (tree arg, signop sign) } if (TREE_CODE (arg) != SSA_NAME) return prec + (orig_sign != sign); - wide_int arg_min, arg_max; - while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE) + value_range r; + while (!get_global_range_query ()->range_of_expr (r, arg) + || r.kind () != VR_RANGE) { gimple *g = SSA_NAME_DEF_STMT (arg); if (is_gimple_assign (g) @@ -709,14 +711,14 @@ get_min_precision (tree arg, signop sign) } if (sign == TYPE_SIGN (TREE_TYPE (arg))) { - int p1 = wi::min_precision (arg_min, sign); - int p2 = wi::min_precision (arg_max, sign); + int p1 = wi::min_precision (r.lower_bound (), sign); + int p2 = wi::min_precision (r.upper_bound (), sign); p1 = MAX (p1, p2); prec = MIN (prec, p1); } - else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED)) + else if (sign == UNSIGNED && !wi::neg_p (r.lower_bound (), SIGNED)) { - int p = wi::min_precision (arg_max, UNSIGNED); + int p = wi::min_precision (r.upper_bound (), UNSIGNED); prec = MIN (prec, p); } return prec + (orig_sign != sign); diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 4e5be81..95d2875 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "tree-into-ssa.h" #include "symtab-clones.h" +#include "gimple-range.h" /* Summaries. */ fast_function_summary *ipa_fn_summaries; @@ -1687,8 +1688,14 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, int bound_limit = opt_for_fn (fbi->node->decl, param_ipa_max_switch_predicate_bounds); int bound_count = 0; - wide_int vr_wmin, vr_wmax; - value_range_kind vr_type = get_range_info (op, &vr_wmin, &vr_wmax); + value_range vr; + + get_range_query (cfun)->range_of_expr (vr, op); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (op)); + value_range_kind vr_type = vr.kind (); + wide_int vr_wmin = wi::to_wide (vr.min ()); + wide_int vr_wmax = wi::to_wide (vr.max ()); FOR_EACH_EDGE (e, ei, bb->succs) { diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 0591ef1..f74d2e1 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see #include "options.h" #include "symtab-clones.h" #include "attr-fnspec.h" +#include "gimple-range.h" /* Function summary where the parameter infos are actually stored. */ ipa_node_params_t *ipa_node_params_sum = NULL; @@ -2237,6 +2238,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, gcall *call = cs->call_stmt; int n, arg_num = gimple_call_num_args (call); bool useful_context = false; + value_range vr; if (arg_num == 0 || args->jump_functions) return; @@ -2274,7 +2276,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, if (TREE_CODE (arg) == SSA_NAME && param_type - && get_ptr_nonnull (arg)) + && get_range_query (cfun)->range_of_expr (vr, arg) + && vr.nonzero_p ()) addr_nonzero = true; else if (tree_single_nonzero_warnv_p (arg, &strict_overflow)) addr_nonzero = true; @@ -2289,19 +2292,14 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, } else { - wide_int min, max; - value_range_kind kind; if (TREE_CODE (arg) == SSA_NAME && param_type - && (kind = get_range_info (arg, &min, &max)) - && (kind == VR_RANGE || kind == VR_ANTI_RANGE)) + && get_range_query (cfun)->range_of_expr (vr, arg) + && !vr.undefined_p ()) { value_range resvr; - value_range tmpvr (wide_int_to_tree (TREE_TYPE (arg), min), - wide_int_to_tree (TREE_TYPE (arg), max), - kind); range_fold_unary_expr (&resvr, NOP_EXPR, param_type, - &tmpvr, TREE_TYPE (arg)); + &vr, TREE_TYPE (arg)); if (!resvr.undefined_p () && !resvr.varying_p ()) ipa_set_jfunc_vr (jfunc, &resvr); else diff --git a/gcc/match.pd b/gcc/match.pd index dd73081..b60e270 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -663,11 +663,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { bool overflowed = true; - wide_int wmin0, wmax0, wmin1, wmax1; + value_range vr0, vr1; if (INTEGRAL_TYPE_P (type) - && get_range_info (@0, &wmin0, &wmax0) == VR_RANGE - && get_range_info (@1, &wmin1, &wmax1) == VR_RANGE) + && get_global_range_query ()->range_of_expr (vr0, @0) + && get_global_range_query ()->range_of_expr (vr1, @1) + && vr0.kind () == VR_RANGE + && vr1.kind () == VR_RANGE) { + wide_int wmin0 = vr0.lower_bound (); + wide_int wmax0 = vr0.upper_bound (); + wide_int wmin1 = vr1.lower_bound (); + wide_int wmax1 = vr1.upper_bound (); /* If the multiplication can't overflow/wrap around, then it can be optimized too. */ wi::overflow_type min_ovf, max_ovf; @@ -2509,9 +2515,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type), TYPE_SIGN (inner_type)); - wide_int wmin0, wmax0; - if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE) + value_range vr; + if (get_global_range_query ()->range_of_expr (vr, @0) + && vr.kind () == VR_RANGE) { + wide_int wmin0 = vr.lower_bound (); + wide_int wmax0 = vr.upper_bound (); wi::add (wmin0, w1, TYPE_SIGN (inner_type), &min_ovf); wi::add (wmax0, w1, TYPE_SIGN (inner_type), &max_ovf); } diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index e6dd5f1..09d4667 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1035,14 +1035,23 @@ split_constant_offset (tree exp, tree *var, tree *off, value_range *exp_range, *exp_range = type; if (code == SSA_NAME) { - wide_int var_min, var_max; - value_range_kind vr_kind = get_range_info (exp, &var_min, &var_max); + value_range vr; + get_range_query (cfun)->range_of_expr (vr, exp); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (exp)); + wide_int var_min = wi::to_wide (vr.min ()); + wide_int var_max = wi::to_wide (vr.max ()); + value_range_kind vr_kind = vr.kind (); wide_int var_nonzero = get_nonzero_bits (exp); vr_kind = intersect_range_with_nonzero_bits (vr_kind, &var_min, &var_max, var_nonzero, TYPE_SIGN (type)); - if (vr_kind == VR_RANGE) + /* This check for VR_VARYING is here because the old code + using get_range_info would return VR_RANGE for the entire + domain, instead of VR_VARYING. The new code normalizes + full-domain ranges to VR_VARYING. */ + if (vr_kind == VR_RANGE || vr_kind == VR_VARYING) *exp_range = value_range (type, var_min, var_max); } } @@ -6298,12 +6307,19 @@ dr_step_indicator (struct data_reference *dr, int useful_min) /* Get the range of values that the unconverted step actually has. */ wide_int step_min, step_max; + value_range vr; if (TREE_CODE (step) != SSA_NAME - || get_range_info (step, &step_min, &step_max) != VR_RANGE) + || !get_range_query (cfun)->range_of_expr (vr, step) + || vr.kind () != VR_RANGE) { step_min = wi::to_wide (TYPE_MIN_VALUE (type)); step_max = wi::to_wide (TYPE_MAX_VALUE (type)); } + else + { + step_min = vr.lower_bound (); + step_max = vr.upper_bound (); + } /* Check whether the unconverted step has an acceptable range. */ signop sgn = TYPE_SIGN (type); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index c6c3bd6..1d20de0 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "gimple-walk.h" #include "tree-dfa.h" +#include "gimple-range.h" /* Build and maintain data flow information for trees. */ @@ -535,14 +536,23 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, index. */ seen_variable_array_ref = true; - wide_int min, max; + value_range vr; + range_query *query; + if (cfun) + query = get_range_query (cfun); + else + query = get_global_range_query (); + if (TREE_CODE (index) == SSA_NAME && (low_bound = array_ref_low_bound (exp), poly_int_tree_p (low_bound)) && (unit_size = array_ref_element_size (exp), TREE_CODE (unit_size) == INTEGER_CST) - && get_range_info (index, &min, &max) == VR_RANGE) + && query->range_of_expr (vr, index) + && vr.kind () == VR_RANGE) { + wide_int min = vr.lower_bound (); + wide_int max = vr.upper_bound (); poly_offset_int lbound = wi::to_poly_offset (low_bound); /* Try to constrain maxsize with range information. */ offset_int omax diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index ff052be..b22d49a 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -3039,18 +3039,27 @@ iv_can_overflow_p (class loop *loop, tree type, tree base, tree step) widest_int nit; wide_int base_min, base_max, step_min, step_max, type_min, type_max; signop sgn = TYPE_SIGN (type); + value_range r; if (integer_zerop (step)) return false; if (!INTEGRAL_TYPE_P (TREE_TYPE (base)) - || get_range_info (base, &base_min, &base_max) != VR_RANGE) + || !get_range_query (cfun)->range_of_expr (r, base) + || r.kind () != VR_RANGE) return true; + base_min = r.lower_bound (); + base_max = r.upper_bound (); + if (!INTEGRAL_TYPE_P (TREE_TYPE (step)) - || get_range_info (step, &step_min, &step_max) != VR_RANGE) + || !get_range_query (cfun)->range_of_expr (r, step) + || r.kind () != VR_RANGE) return true; + step_min = r.lower_bound (); + step_max = r.upper_bound (); + if (!get_max_loop_iterations (loop, &nit)) return true; diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 3817ec4..b5add82 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-chrec.h" #include "tree-scalar-evolution.h" #include "tree-dfa.h" +#include "gimple-range.h" /* The maximum number of dominator BBs we search for conditions @@ -121,7 +122,6 @@ refine_value_range_using_guard (tree type, tree var, tree varc0, varc1, ctype; mpz_t offc0, offc1; mpz_t mint, maxt, minc1, maxc1; - wide_int minv, maxv; bool no_wrap = nowrap_type_p (type); bool c0_ok, c1_ok; signop sgn = TYPE_SIGN (type); @@ -221,6 +221,7 @@ refine_value_range_using_guard (tree type, tree var, get_type_static_bounds (type, mint, maxt); mpz_init (minc1); mpz_init (maxc1); + value_range r; /* Setup range information for varc1. */ if (integer_zerop (varc1)) { @@ -229,11 +230,12 @@ refine_value_range_using_guard (tree type, tree var, } else if (TREE_CODE (varc1) == SSA_NAME && INTEGRAL_TYPE_P (type) - && get_range_info (varc1, &minv, &maxv) == VR_RANGE) + && get_range_query (cfun)->range_of_expr (r, varc1) + && r.kind () == VR_RANGE) { - gcc_assert (wi::le_p (minv, maxv, sgn)); - wi::to_mpz (minv, minc1, sgn); - wi::to_mpz (maxv, maxc1, sgn); + gcc_assert (wi::le_p (r.lower_bound (), r.upper_bound (), sgn)); + wi::to_mpz (r.lower_bound (), minc1, sgn); + wi::to_mpz (r.upper_bound (), maxc1, sgn); } else { @@ -372,34 +374,50 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off, gphi_iterator gsi; /* Either for VAR itself... */ - rtype = get_range_info (var, &minv, &maxv); + value_range var_range; + get_range_query (cfun)->range_of_expr (var_range, var); + rtype = var_range.kind (); + if (!var_range.undefined_p ()) + { + minv = var_range.lower_bound (); + maxv = var_range.upper_bound (); + } + /* Or for PHI results in loop->header where VAR is used as PHI argument from the loop preheader edge. */ for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) { gphi *phi = gsi.phi (); - wide_int minc, maxc; + value_range phi_range; if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var - && (get_range_info (gimple_phi_result (phi), &minc, &maxc) - == VR_RANGE)) + && get_range_query (cfun)->range_of_expr (phi_range, + gimple_phi_result (phi)) + && phi_range.kind () == VR_RANGE) { if (rtype != VR_RANGE) { rtype = VR_RANGE; - minv = minc; - maxv = maxc; + minv = phi_range.lower_bound (); + maxv = phi_range.upper_bound (); } else { - minv = wi::max (minv, minc, sgn); - maxv = wi::min (maxv, maxc, sgn); + minv = wi::max (minv, phi_range.lower_bound (), sgn); + maxv = wi::min (maxv, phi_range.upper_bound (), sgn); /* If the PHI result range are inconsistent with the VAR range, give up on looking at the PHI results. This can happen if VR_UNDEFINED is involved. */ if (wi::gt_p (minv, maxv, sgn)) { - rtype = get_range_info (var, &minv, &maxv); + value_range vr; + get_range_query (cfun)->range_of_expr (vr, var); + rtype = vr.kind (); + if (!vr.undefined_p ()) + { + minv = vr.lower_bound (); + maxv = vr.upper_bound (); + } break; } } @@ -3545,12 +3563,16 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt, if (tree_int_cst_sign_bit (step)) { - wide_int min, max; + wide_int max; + value_range base_range; + if (get_range_query (cfun)->range_of_expr (base_range, orig_base) + && !base_range.undefined_p ()) + max = base_range.upper_bound (); extreme = fold_convert (unsigned_type, low); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (high) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (orig_base)) - && (get_range_info (orig_base, &min, &max) == VR_RANGE + && (base_range.kind () == VR_RANGE || get_cst_init_from_scev (orig_base, &max, false)) && wi::gts_p (wi::to_wide (high), max)) base = wide_int_to_tree (unsigned_type, max); @@ -3563,12 +3585,16 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt, } else { - wide_int min, max; + wide_int min; + value_range base_range; + if (get_range_query (cfun)->range_of_expr (base_range, orig_base) + && !base_range.undefined_p ()) + min = base_range.lower_bound (); extreme = fold_convert (unsigned_type, high); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (low) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (orig_base)) - && (get_range_info (orig_base, &min, &max) == VR_RANGE + && (base_range.kind () == VR_RANGE || get_cst_init_from_scev (orig_base, &min, true)) && wi::gts_p (min, wi::to_wide (low))) base = wide_int_to_tree (unsigned_type, min); @@ -3835,11 +3861,12 @@ infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt) low = lower_bound_in_type (type, type); high = upper_bound_in_type (type, type); - wide_int minv, maxv; - if (get_range_info (def, &minv, &maxv) == VR_RANGE) + value_range r; + get_range_query (cfun)->range_of_expr (r, def); + if (r.kind () == VR_RANGE) { - low = wide_int_to_tree (type, minv); - high = wide_int_to_tree (type, maxv); + low = wide_int_to_tree (type, r.lower_bound ()); + high = wide_int_to_tree (type, r.upper_bound ()); } record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true); @@ -4873,7 +4900,6 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop) { tree type; wide_int minv, maxv, diff, step_wi; - enum value_range_kind rtype; if (TREE_CODE (step) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (var))) return false; @@ -4884,8 +4910,9 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop) if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb)) return false; - rtype = get_range_info (var, &minv, &maxv); - if (rtype != VR_RANGE) + value_range r; + get_range_query (cfun)->range_of_expr (r, var); + if (r.kind () != VR_RANGE) return false; /* VAR is a scev whose evolution part is STEP and value range info @@ -4899,11 +4926,11 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop) type = TREE_TYPE (var); if (tree_int_cst_sign_bit (step)) { - diff = minv - wi::to_wide (lower_bound_in_type (type, type)); + diff = r.lower_bound () - wi::to_wide (lower_bound_in_type (type, type)); step_wi = - step_wi; } else - diff = wi::to_wide (upper_bound_in_type (type, type)) - maxv; + diff = wi::to_wide (upper_bound_in_type (type, type)) - r.upper_bound (); return (wi::geu_p (diff, step_wi)); } diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index f133659..e3bd180 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "gimple-fold.h" #include "internal-fn.h" +#include "gimple-range.h" static unsigned int tree_ssa_phiopt_worker (bool, bool, bool); static bool two_value_replacement (basic_block, basic_block, edge, gphi *, @@ -684,7 +685,15 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb, return false; wide_int min, max; - if (get_range_info (lhs, &min, &max) != VR_RANGE) + value_range r; + get_range_query (cfun)->range_of_expr (r, lhs); + + if (r.kind () == VR_RANGE) + { + min = r.lower_bound (); + max = r.upper_bound (); + } + else { int prec = TYPE_PRECISION (TREE_TYPE (lhs)); signop sgn = TYPE_SIGN (TREE_TYPE (lhs)); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 2d22535..d86fe26 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-dce.h" #include "tree-cfgcleanup.h" #include "alias.h" +#include "gimple-range.h" /* Even though this file is called tree-ssa-pre.c, we actually implement a bit more than just PRE here. All of them piggy-back @@ -3234,16 +3235,18 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, >= TYPE_PRECISION (TREE_TYPE (expr->u.nary->op[0]))) && SSA_NAME_RANGE_INFO (expr->u.nary->op[0])) { - wide_int min, max; - if (get_range_info (expr->u.nary->op[0], &min, &max) == VR_RANGE - && !wi::neg_p (min, SIGNED) - && !wi::neg_p (max, SIGNED)) + value_range r; + if (get_range_query (cfun)->range_of_expr (r, expr->u.nary->op[0]) + && r.kind () == VR_RANGE + && !wi::neg_p (r.lower_bound (), SIGNED) + && !wi::neg_p (r.upper_bound (), SIGNED)) /* Just handle extension and sign-changes of all-positive ranges. */ - set_range_info (temp, - SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]), - wide_int_storage::from (min, TYPE_PRECISION (type), + set_range_info (temp, VR_RANGE, + wide_int_storage::from (r.lower_bound (), + TYPE_PRECISION (type), TYPE_SIGN (type)), - wide_int_storage::from (max, TYPE_PRECISION (type), + wide_int_storage::from (r.upper_bound (), + TYPE_PRECISION (type), TYPE_SIGN (type))); } diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 32e1632..6dfc703 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "case-cfn-macros.h" #include "tree-ssa-reassoc.h" #include "tree-ssa-math-opts.h" +#include "gimple-range.h" /* This is a simple global reassociation pass. It is, in part, based on the LLVM pass of the same name (They do some things more/less @@ -3221,12 +3222,14 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length, amount, then we can merge the entry test in the bit test. In this case, if we would need otherwise 2 or more comparisons, then use the bit test; in the other cases, the threshold is 3 comparisons. */ - wide_int min, max; bool entry_test_needed; + value_range r; if (TREE_CODE (exp) == SSA_NAME - && get_range_info (exp, &min, &max) == VR_RANGE - && wi::leu_p (max - min, prec - 1)) + && get_range_query (cfun)->range_of_expr (r, exp) + && r.kind () == VR_RANGE + && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1)) { + wide_int min = r.lower_bound (); wide_int ilowi = wi::to_wide (lowi); if (wi::lt_p (min, ilowi, TYPE_SIGN (TREE_TYPE (lowi)))) { diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index c7b5e2c..423075b 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -196,7 +196,7 @@ static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *); /* Sets MINMAX to either the constant value or the range VAL is in and returns either the constant value or VAL on success or null when the range couldn't be determined. Uses RVALS when nonnull - to determine the range, otherwise get_range_info. */ + to determine the range, otherwise uses global range info. */ tree get_range (tree val, gimple *stmt, wide_int minmax[2], @@ -211,9 +211,9 @@ get_range (tree val, gimple *stmt, wide_int minmax[2], if (TREE_CODE (val) != SSA_NAME) return NULL_TREE; + value_range vr; if (rvals && stmt) { - value_range vr; if (!rvals->range_of_expr (vr, val, stmt)) return NULL_TREE; value_range_kind rng = vr.kind (); @@ -225,7 +225,15 @@ get_range (tree val, gimple *stmt, wide_int minmax[2], return val; } - value_range_kind rng = get_range_info (val, minmax, minmax + 1); + // ?? This entire function should use get_range_query or get_global_range_query (), + // instead of doing something different for RVALS and global ranges. + + if (!get_global_range_query ()->range_of_expr (vr, val) || vr.undefined_p ()) + return NULL_TREE; + + minmax[0] = wi::to_wide (vr.min ()); + minmax[1] = wi::to_wide (vr.max ()); + value_range_kind rng = vr.kind (); if (rng == VR_RANGE) /* This may be an inverted range whose MINMAX[1] < MINMAX[0]. */ return val; @@ -929,7 +937,17 @@ dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals) rng = VR_UNDEFINED; } else - rng = get_range_info (si->nonzero_chars, &min, &max); + { + value_range vr; + get_global_range_query ()->range_of_expr (vr, + si->nonzero_chars); + rng = vr.kind (); + if (!vr.undefined_p ()) + { + min = wi::to_wide (vr.min ()); + max = wi::to_wide (vr.max ()); + } + } if (rng == VR_RANGE || rng == VR_ANTI_RANGE) { @@ -1809,18 +1827,17 @@ set_strlen_range (tree lhs, wide_int min, wide_int max, } else if (TREE_CODE (bound) == SSA_NAME) { - wide_int minbound, maxbound; - // FIXME: Use range_query instead of global ranges. - value_range_kind rng = get_range_info (bound, &minbound, &maxbound); - if (rng == VR_RANGE) + value_range r; + get_range_query (cfun)->range_of_expr (r, bound); + if (!r.undefined_p ()) { /* For a bound in a known range, adjust the range determined above as necessary. For a bound in some anti-range or in an unknown range, use the range determined by callers. */ - if (wi::ltu_p (minbound, min)) - min = minbound; - if (wi::ltu_p (maxbound, max)) - max = maxbound; + if (wi::ltu_p (r.lower_bound (), min)) + min = r.lower_bound (); + if (wi::ltu_p (r.upper_bound (), max)) + max = r.upper_bound (); } } } @@ -2780,12 +2797,15 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, return false; wide_int cntrange[2]; + value_range r; + if (!get_range_query (cfun)->range_of_expr (r, cnt) + || r.varying_p () + || r.undefined_p ()) + return false; - // FIXME: Use range_query instead of global ranges. - enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1); - if (rng == VR_RANGE) - ; - else if (rng == VR_ANTI_RANGE) + cntrange[0] = wi::to_wide (r.min ()); + cntrange[1] = wi::to_wide (r.max ()); + if (r.kind () == VR_ANTI_RANGE) { wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)); @@ -2800,8 +2820,6 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt))); } } - else - return false; /* Negative value is the constant string length. If it's less than the lower bound there is no truncation. Avoid calling get_stridx() @@ -3923,13 +3941,12 @@ get_len_or_size (gimple *stmt, tree arg, int idx, } else if (TREE_CODE (si->nonzero_chars) == SSA_NAME) { - wide_int min, max; - // FIXME: Use range_query instead of global ranges. - value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max); - if (rng == VR_RANGE) + value_range r; + get_range_query (cfun)->range_of_expr (r, si->nonzero_chars); + if (r.kind () == VR_RANGE) { - lenrng[0] = min.to_uhwi (); - lenrng[1] = max.to_uhwi (); + lenrng[0] = r.lower_bound ().to_uhwi (); + lenrng[1] = r.upper_bound ().to_uhwi (); *nulterm = si->full_string_p; } } @@ -5301,17 +5318,13 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh, /* Reading a character before the final '\0' character. Just set the value range to ~[0, 0] if we don't have anything better. */ - wide_int min, max; - signop sign = TYPE_SIGN (lhs_type); - int prec = TYPE_PRECISION (lhs_type); - // FIXME: Use range_query instead of global ranges. - value_range_kind vr = get_range_info (lhs, &min, &max); - if (vr == VR_VARYING - || (vr == VR_RANGE - && min == wi::min_value (prec, sign) - && max == wi::max_value (prec, sign))) - set_range_info (lhs, VR_ANTI_RANGE, - wi::zero (prec), wi::zero (prec)); + value_range r; + if (!get_range_query (cfun)->range_of_expr (r, lhs) + || r.varying_p ()) + { + r.set_nonzero (lhs_type); + set_range_info (lhs, r); + } } } } diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index a023871..7163438 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -43,6 +43,7 @@ #include "attribs.h" #include "tree-ssa.h" #include "tree-cfg.h" +#include "gimple-range.h" /* The idea behind this analyzer is to generate set constraints from the program, then solve the resulting constraints in order to generate the @@ -6740,7 +6741,9 @@ find_what_p_points_to (tree fndecl, tree p) struct ptr_info_def *pi; tree lookup_p = p; varinfo_t vi; - bool nonnull = get_ptr_nonnull (p); + value_range vr; + get_range_query (DECL_STRUCT_FUNCTION (fndecl))->range_of_expr (vr, p); + bool nonnull = vr.nonzero_p (); /* For parameters, get at the points-to set for the actual parm decl. */ @@ -6758,8 +6761,7 @@ find_what_p_points_to (tree fndecl, tree p) pi->pt = find_what_var_points_to (fndecl, vi); /* Conservatively set to NULL from PTA (to true). */ pi->pt.null = 1; - /* Preserve pointer nonnull computed by VRP. See get_ptr_nonnull - in gcc/tree-ssaname.c for more information. */ + /* Preserve pointer nonnull globally computed. */ if (nonnull) set_ptr_nonnull (p); } diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index f55ce19..dcfdec9 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "builtins.h" #include "calls.h" +#include "gimple-range.h" /* This implements the pass that does predicate aware warning on uses of possibly uninitialized variables. The pass first collects the set of @@ -1606,11 +1607,14 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def, flag_var <= [min, max] -> flag_var < [min, max+1] flag_var >= [min, max] -> flag_var > [min-1, max] if no overflow/wrap. */ - wide_int min, max; tree type = TREE_TYPE (cond_lhs); + value_range r; if (!INTEGRAL_TYPE_P (type) - || get_range_info (cond_rhs, &min, &max) != VR_RANGE) + || !get_range_query (cfun)->range_of_expr (r, cond_rhs) + || r.kind () != VR_RANGE) continue; + wide_int min = r.lower_bound (); + wide_int max = r.upper_bound (); if (code == LE_EXPR && max != wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type))) { diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 7f65c4c..294b545 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -50,6 +50,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "target.h" #include "tree-into-ssa.h" #include "omp-general.h" +#include "gimple-range.h" /* ??? For lang_hooks.types.type_for_mode, but is there a word_mode type in the GIMPLE type system that is language-independent? */ @@ -1553,12 +1554,15 @@ bit_test_cluster::emit (tree index_expr, tree index_type, /* If every possible relative value of the index expression is a valid shift amount, then we can merge the entry test in the bit test. */ - wide_int min, max; bool entry_test_needed; + value_range r; if (TREE_CODE (index_expr) == SSA_NAME - && get_range_info (index_expr, &min, &max) == VR_RANGE - && wi::leu_p (max - min, prec - 1)) + && get_range_query (cfun)->range_of_expr (r, index_expr) + && r.kind () == VR_RANGE + && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1)) { + wide_int min = r.lower_bound (); + wide_int max = r.upper_bound (); tree index_type = TREE_TYPE (index_expr); minval = fold_convert (index_type, minval); wide_int iminval = wi::to_wide (minval); diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 803de3f..177d44e 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "predict.h" #include "tree-vector-builder.h" #include "vec-perm-indices.h" +#include "gimple-range.h" /* Return true if we have a useful VR_RANGE range for VAR, storing it in *MIN_VALUE and *MAX_VALUE if so. Note the range in the dump files. */ @@ -55,7 +56,13 @@ along with GCC; see the file COPYING3. If not see static bool vect_get_range_info (tree var, wide_int *min_value, wide_int *max_value) { - value_range_kind vr_type = get_range_info (var, min_value, max_value); + value_range vr; + get_range_query (cfun)->range_of_expr (vr, var); + if (vr.undefined_p ()) + vr.set_varying (TREE_TYPE (var)); + *min_value = wi::to_wide (vr.min ()); + *max_value = wi::to_wide (vr.max ()); + value_range_kind vr_type = vr.kind (); wide_int nonzero = get_nonzero_bits (var); signop sgn = TYPE_SIGN (TREE_TYPE (var)); if (intersect_range_with_nonzero_bits (vr_type, min_value, max_value, @@ -3437,13 +3444,14 @@ vect_recog_divmod_pattern (vec_info *vinfo, else t3 = t2; - wide_int oprnd0_min, oprnd0_max; int msb = 1; - if (get_range_info (oprnd0, &oprnd0_min, &oprnd0_max) == VR_RANGE) + value_range r; + get_range_query (cfun)->range_of_expr (r, oprnd0); + if (r.kind () == VR_RANGE) { - if (!wi::neg_p (oprnd0_min, TYPE_SIGN (itype))) + if (!wi::neg_p (r.lower_bound (), TYPE_SIGN (itype))) msb = 0; - else if (wi::neg_p (oprnd0_max, TYPE_SIGN (itype))) + else if (wi::neg_p (r.upper_bound (), TYPE_SIGN (itype))) msb = -1; } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b0f1c47..450926d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -228,7 +228,7 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type, vr_type = VR_RANGE; } } - if (vr_type == VR_RANGE) + if (vr_type == VR_RANGE || vr_type == VR_VARYING) { *max = wi::round_down_for_mask (*max, nonzero_bits); @@ -1717,7 +1717,7 @@ register_edge_assert_for_2 (tree name, edge e, simply register the same assert for it. */ if (CONVERT_EXPR_CODE_P (rhs_code)) { - wide_int rmin, rmax; + value_range vr; tree rhs1 = gimple_assign_rhs1 (def_stmt); if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) && TREE_CODE (rhs1) == SSA_NAME @@ -1739,13 +1739,14 @@ register_edge_assert_for_2 (tree name, edge e, && int_fits_type_p (val, TREE_TYPE (rhs1)) && ((TYPE_PRECISION (TREE_TYPE (name)) > TYPE_PRECISION (TREE_TYPE (rhs1))) - || (get_range_info (rhs1, &rmin, &rmax) == VR_RANGE + || ((get_range_query (cfun)->range_of_expr (vr, rhs1) + && vr.kind () == VR_RANGE) && wi::fits_to_tree_p - (widest_int::from (rmin, + (widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (rhs1))), TREE_TYPE (name)) && wi::fits_to_tree_p - (widest_int::from (rmax, + (widest_int::from (vr.upper_bound (), TYPE_SIGN (TREE_TYPE (rhs1))), TREE_TYPE (name))))) add_assert_info (asserts, rhs1, rhs1, @@ -4631,16 +4632,14 @@ determine_value_range_1 (value_range *vr, tree expr) vr->set (expr); else { - value_range_kind kind; - wide_int min, max; + 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)) - && (kind = get_range_info (expr, &min, &max)) != VR_VARYING) - vr->set (wide_int_to_tree (TREE_TYPE (expr), min), - wide_int_to_tree (TREE_TYPE (expr), max), - kind); + && get_range_query (cfun)->range_of_expr (r, expr) + && !r.undefined_p ()) + *vr = r; else vr->set_varying (TREE_TYPE (expr)); } diff --git a/gcc/tree.c b/gcc/tree.c index bdb29b8..9cafe43 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vector-builder.h" #include "gimple-fold.h" #include "escaped_string.h" +#include "gimple-range.h" /* Tree code classes. */ @@ -13831,8 +13832,8 @@ get_range_pos_neg (tree arg) if (TREE_CODE (arg) != SSA_NAME) return 3; - wide_int arg_min, arg_max; - while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE) + value_range r; + while (!get_global_range_query ()->range_of_expr (r, arg) || r.kind () != VR_RANGE) { gimple *g = SSA_NAME_DEF_STMT (arg); if (is_gimple_assign (g) @@ -13858,16 +13859,16 @@ get_range_pos_neg (tree arg) { /* For unsigned values, the "positive" range comes below the "negative" range. */ - if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED)) + if (!wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED)) return 1; - if (wi::neg_p (wi::sext (arg_min, prec), SIGNED)) + if (wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED)) return 2; } else { - if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED)) + if (!wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED)) return 1; - if (wi::neg_p (wi::sext (arg_max, prec), SIGNED)) + if (wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED)) return 2; } return 3; diff --git a/gcc/vr-values.c b/gcc/vr-values.c index e0c8844..d283108 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -117,14 +117,16 @@ vr_values::get_lattice_entry (const_tree var) default definitions of PARM_DECLs. */ if (POINTER_TYPE_P (TREE_TYPE (sym)) && (nonnull_arg_p (sym) - || get_ptr_nonnull (var))) + || (get_global_range_query ()->range_of_expr (*vr, + const_cast (var)) + && vr->nonzero_p ()))) { vr->set_nonzero (TREE_TYPE (sym)); vr->equiv_clear (); } else if (INTEGRAL_TYPE_P (TREE_TYPE (sym))) { - get_range_info (var, *vr); + get_global_range_query ()->range_of_expr (*vr, const_cast (var)); if (vr->undefined_p ()) vr->set_varying (TREE_TYPE (sym)); } @@ -262,7 +264,7 @@ vr_values::update_value_range (const_tree var, value_range_equiv *new_vr) if (INTEGRAL_TYPE_P (TREE_TYPE (var))) { value_range_equiv nr; - get_range_info (var, nr); + get_global_range_query ()->range_of_expr (nr, const_cast (var)); if (!nr.undefined_p ()) new_vr->intersect (&nr); } @@ -3829,13 +3831,13 @@ simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)) return false; - /* Get the value-range of the inner operand. Use get_range_info in + /* Get the value-range of the inner operand. Use global ranges in case innerop was created during substitute-and-fold. */ wide_int imin, imax; value_range vr; if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop))) return false; - get_range_info (innerop, vr); + get_global_range_query ()->range_of_expr (vr, innerop, stmt); if (vr.undefined_p () || vr.varying_p ()) return false; innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop))); -- cgit v1.1 From af66d0af87cf36d923d4663935a2b7a682753a24 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 20 May 2021 12:23:49 +0200 Subject: Cleanup get_range_info Now that there is only one user of get_range_info() we can clean this up to always return a range instead of pairs of wide_ints. A follow-up patch will inline both get_range_info and get_ptr_nonnull into its only remaining user. gcc/ChangeLog: * tree-ssanames.c (get_range_info): Merge both copies of get_range_info into one that works with irange. * tree-ssanames.h (get_range_info): Remove version that works on wide_ints. --- gcc/tree-ssanames.c | 57 +++++++++++++---------------------------------------- gcc/tree-ssanames.h | 2 -- 2 files changed, 14 insertions(+), 45 deletions(-) (limited to 'gcc') diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 51a26d2..5329c0a 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -423,58 +423,29 @@ set_range_info (tree name, const value_range &vr) set_range_info (name, vr.kind (), min, max); } -/* Gets range information MIN, MAX and returns enum value_range_kind - corresponding to tree ssa_name NAME. enum value_range_kind returned - is used to determine if MIN and MAX are valid values. */ +/* Gets range information corresponding to ssa_name NAME and stores it + in a value_range VR. Returns the value_range_kind. */ enum value_range_kind -get_range_info (const_tree expr, wide_int *min, wide_int *max) +get_range_info (const_tree name, irange &vr) { - gcc_assert (!POINTER_TYPE_P (TREE_TYPE (expr))); - gcc_assert (min && max); - if (TREE_CODE (expr) == INTEGER_CST) - { - *min = wi::to_wide (expr); - *max = *min; - return VR_RANGE; - } - if (TREE_CODE (expr) != SSA_NAME) - return VR_VARYING; + tree type = TREE_TYPE (name); + gcc_checking_assert (!POINTER_TYPE_P (type)); + gcc_checking_assert (TREE_CODE (name) == SSA_NAME); - range_info_def *ri = SSA_NAME_RANGE_INFO (expr); + range_info_def *ri = SSA_NAME_RANGE_INFO (name); /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */ - if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (expr))) + if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (name))) > 2 * HOST_BITS_PER_WIDE_INT)) - return VR_VARYING; - - *min = ri->get_min (); - *max = ri->get_max (); - return SSA_NAME_RANGE_TYPE (expr); -} - -/* Gets range information corresponding to ssa_name NAME and stores it - in a value_range VR. Returns the value_range_kind. */ - -enum value_range_kind -get_range_info (const_tree name, irange &vr) -{ - tree min, max; - wide_int wmin, wmax; - enum value_range_kind kind = get_range_info (name, &wmin, &wmax); - - if (kind == VR_VARYING) - vr.set_varying (TREE_TYPE (name)); - else if (kind == VR_UNDEFINED) - vr.set_undefined (); + vr.set_varying (type); else - { - min = wide_int_to_tree (TREE_TYPE (name), wmin); - max = wide_int_to_tree (TREE_TYPE (name), wmax); - vr.set (min, max, kind); - } - return kind; + vr.set (wide_int_to_tree (type, ri->get_min ()), + wide_int_to_tree (type, ri->get_max ()), + SSA_NAME_RANGE_TYPE (name)); + + return vr.kind (); } /* Set nonnull attribute to pointer NAME. */ diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index cce2d2c..166f921 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -71,8 +71,6 @@ extern void set_range_info (tree, enum value_range_kind, const wide_int_ref &, const wide_int_ref &); extern void set_range_info (tree, const value_range &); /* Gets the value range from SSA. */ -extern enum value_range_kind get_range_info (const_tree, wide_int *, - wide_int *); extern enum value_range_kind get_range_info (const_tree, irange &); extern void set_nonzero_bits (tree, const wide_int_ref &); extern wide_int get_nonzero_bits (const_tree); -- cgit v1.1 From abe8787a8492013145b275b858f70943522d7226 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 26 May 2021 16:02:33 -0400 Subject: c++: access for hidden friend of nested class template [PR100502] Here, during ahead of time access checking for the private member EnumeratorRange::end_reached_ in the hidden friend f, we're triggering the assert in enforce_access that verifies we're not trying to add a access check for a dependent decl onto TI_DEFERRED_ACCESS_CHECKS. The special thing about this class member access expression is that the overall expression is non-dependent (so finish_class_member_access_expr doesn't exit early at parse time), and then accessible_p rejects the access (so we don't exit early from enforce access either, and end up triggering the assert b/c the member itself is dependent). I think we're correct to reject the access because a hidden friend is not a member function, so [class.access.nest] doesn't apply, and also a hidden friend of a nested class is not a friend of the enclosing class. To fix this ICE, this patch disables ahead of time access checking during the member lookup in finish_class_member_access_expr. This avoids potentially pushing an access check for a dependent member onto TI_DEFERRED_ACCESS_CHECKS, and it's safe because we're going to redo the same lookup at instantiation time anyway. PR c++/100502 gcc/cp/ChangeLog: * typeck.c (finish_class_member_access_expr): Disable ahead of time access checking during the member lookup. gcc/testsuite/ChangeLog: * g++.dg/template/access37.C: New test. * g++.dg/template/access37a.C: New test. --- gcc/cp/typeck.c | 10 ++++++++++ gcc/testsuite/g++.dg/template/access37.C | 26 ++++++++++++++++++++++++++ gcc/testsuite/g++.dg/template/access37a.C | 6 ++++++ 3 files changed, 42 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/access37.C create mode 100644 gcc/testsuite/g++.dg/template/access37a.C (limited to 'gcc') diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 703ddd3..3df4117 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3201,9 +3201,19 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, { /* Look up the member. */ access_failure_info afi; + if (processing_template_decl) + /* Even though this class member access expression is at this + point not dependent, the member itself may be dependent, and + we must not potentially push a access check for a dependent + member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access + ahead of time here; we're going to redo this member lookup at + instantiation time anyway. */ + push_deferring_access_checks (dk_no_check); member = lookup_member (access_path, name, /*protect=*/1, /*want_type=*/false, complain, &afi); + if (processing_template_decl) + pop_deferring_access_checks (); afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); if (member == NULL_TREE) { diff --git a/gcc/testsuite/g++.dg/template/access37.C b/gcc/testsuite/g++.dg/template/access37.C new file mode 100644 index 0000000..5be532c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access37.C @@ -0,0 +1,26 @@ +// PR c++/100502 + +template +struct EnumeratorRange { + struct Iterator { + EnumeratorRange range_; + + friend void f(Iterator i) { + i.range_.end_reached_; // { dg-error "private" } + i.range_.EnumeratorRange::end_reached_; // { dg-error "private" } + &i.range_.end_reached_; // { dg-error "private" } + &i.range_.EnumeratorRange::end_reached_; // { dg-error "private" } + } + }; + + private: + bool end_reached_; +#if DECLARE_FRIEND + friend void f(Iterator); +#endif +}; + +int main() { + EnumeratorRange::Iterator i; + f(i); +} diff --git a/gcc/testsuite/g++.dg/template/access37a.C b/gcc/testsuite/g++.dg/template/access37a.C new file mode 100644 index 0000000..4ce1b27 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access37a.C @@ -0,0 +1,6 @@ +// PR c++/100502 +// { dg-additional-options "-DDECLARE_FRIEND -Wno-non-template-friend" } + +// Verify that access37.C is accepted if the appropriate friend relation +// is declared (controlled by the macro DECLARE_FRIEND). +#include "access37.C" -- cgit v1.1 From 58523f23fefcef0850841e7055d75d4309f0453e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 27 May 2021 00:24:20 +0200 Subject: Small tweak to documentation of scalar_storage_order gcc/ PR c/100653 * doc/extend.texi (scalar_storage_order): Rephrase slightly. --- gcc/doc/extend.texi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 3ddeb0d..bfe9c21 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -8586,8 +8586,9 @@ The second case is nevertheless allowed to be able to perform a block copy from or to the array. Moreover, the use of type punning or aliasing to toggle the storage order -is not supported; that is to say, a given scalar object cannot be accessed -through distinct types that assign a different storage order to it. +is not supported; that is to say, if a given scalar object can be accessed +through distinct types that assign a different storage order to it, then the +behavior is undefined. @item transparent_union @cindex @code{transparent_union} type attribute -- cgit v1.1 From 01c59ef2e5a59b44d2b662361196abb6be872a20 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 27 May 2021 00:16:53 +0000 Subject: Daily bump. --- gcc/ChangeLog | 214 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 4 + gcc/c/ChangeLog | 6 ++ gcc/cp/ChangeLog | 24 ++++++ gcc/testsuite/ChangeLog | 55 +++++++++++++ 6 files changed, 304 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 897c704..c639576 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,217 @@ +2021-05-26 Eric Botcazou + + PR c/100653 + * doc/extend.texi (scalar_storage_order): Rephrase slightly. + +2021-05-26 Aldy Hernandez + + * tree-ssanames.c (get_range_info): Merge both copies of + get_range_info into one that works with irange. + * tree-ssanames.h (get_range_info): Remove version that works on + wide_ints. + +2021-05-26 Aldy Hernandez + + * builtins.c (check_nul_terminated_array): Convert to get_range_query. + (expand_builtin_strnlen): Same. + (determine_block_size): Same. + * fold-const.c (expr_not_equal_to): Same. + * gimple-fold.c (size_must_be_zero_p): Same. + * gimple-match-head.c: Include gimple-range.h. + * gimple-pretty-print.c (dump_ssaname_info): Convert to get_range_query. + * gimple-ssa-warn-restrict.c + (builtin_memref::extend_offset_range): Same. + * graphite-sese-to-poly.c (add_param_constraints): Same. + * internal-fn.c (get_min_precision): Same. + * ipa-fnsummary.c (set_switch_stmt_execution_predicate): Same. + * ipa-prop.c (ipa_compute_jump_functions_for_edge): Same. + * match.pd: Same. + * tree-data-ref.c (split_constant_offset): Same. + (dr_step_indicator): Same. + * tree-dfa.c (get_ref_base_and_extent): Same. + * tree-scalar-evolution.c (iv_can_overflow_p): Same. + * tree-ssa-loop-niter.c (refine_value_range_using_guard): Same. + (determine_value_range): Same. + (record_nonwrapping_iv): Same. + (infer_loop_bounds_from_signedness): Same. + (scev_var_range_cant_overflow): Same. + * tree-ssa-phiopt.c (two_value_replacement): Same. + * tree-ssa-pre.c (insert_into_preds_of_block): Same. + * tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Same. + * tree-ssa-strlen.c (handle_builtin_stxncpy_strncat): Same. + (get_range): Same. + (dump_strlen_info): Same. + (set_strlen_range): Same. + (maybe_diag_stxncpy_trunc): Same. + (get_len_or_size): Same. + (handle_integral_assign): Same. + * tree-ssa-structalias.c (find_what_p_points_to): Same. + * tree-ssa-uninit.c (find_var_cmp_const): Same. + * tree-switch-conversion.c (bit_test_cluster::emit): Same. + * tree-vect-patterns.c (vect_get_range_info): Same. + (vect_recog_divmod_pattern): Same. + * tree-vrp.c (intersect_range_with_nonzero_bits): Same. + (register_edge_assert_for_2): Same. + (determine_value_range_1): Same. + * tree.c (get_range_pos_neg): Same. + * vr-values.c (vr_values::get_lattice_entry): Same. + (vr_values::update_value_range): Same. + (simplify_conversion_using_ranges): Same. + +2021-05-26 Aldy Hernandez + + * gimple-ssa-warn-alloca.c (alloca_call_type): Use + get_range_query instead of query argument. + (pass_walloca::execute): Enable and disable global ranger. + +2021-05-26 Aldy Hernandez + + * gimple-ssa-evrp.c (rvrp_folder::rvrp_folder): Call + enable_ranger. + (rvrp_folder::~rvrp_folder): Call disable_ranger. + (hybrid_folder::hybrid_folder): Call enable_ranger. + (hybrid_folder::~hybrid_folder): Call disable_ranger. + +2021-05-26 Aldy Hernandez + + * function.c (allocate_struct_function): Set cfun->x_range_query. + * function.h (struct function): Declare x_range_query. + (get_range_query): New. + (get_global_range_query): New. + * gimple-range-cache.cc (ssa_global_cache::ssa_global_cache): + Remove call to safe_grow_cleared. + * gimple-range.cc (get_range_global): New. + (gimple_range_global): Move from gimple-range.h. + (get_global_range_query): New. + (global_range_query::range_of_expr): New. + (enable_ranger): New. + (disable_ranger): New. + * gimple-range.h (gimple_range_global): Move to gimple-range.cc. + (class global_range_query): New. + (enable_ranger): New. + (disable_ranger): New. + * gimple-ssa-evrp.c (evrp_folder::~evrp_folder): Rename + dump_all_value_ranges to dump. + * tree-vrp.c (vrp_prop::finalize): Same. + * value-query.cc (range_query::dump): New. + * value-query.h (range_query::dump): New. + * vr-values.c (vr_values::dump_all_value_ranges): Rename to... + (vr_values::dump): ...this. + * vr-values.h (class vr_values): Rename dump_all_value_ranges to + dump and make virtual. + +2021-05-26 Uroš Bizjak + + * config/i386/i386.c (ix86_autovectorize_vector_modes): + Add V4QImode and V16QImode for TARGET_SSE2. + * doc/sourcebuild.texi (Vector-specific attributes): + Add vect64 and vect32 description. + +2021-05-26 Bernd Edlinger + + * gimple-range-gori.cc (range_def_chain::register_dependency): + Resize m_def_chain when needed. + +2021-05-26 Christophe Lyon + + * config/arm/mve.md (mve_vaddvq_): Prefix with '@'. + * config/arm/neon.md (reduc_plus_scal_): Move to .. + * config/arm/vec-common.md: .. here. Add support for MVE. + +2021-05-26 Jakub Jelinek + + * config/epiphany/epiphany.c (epiphany_print_operand_address): Remove + register keywords. + * config/microblaze/microblaze.c (microblaze_legitimize_address, + call_internal1, + microblaze_option_override, print_operand): Likewise. + * config/microblaze/microblaze.md (call_internal_plt, + call_value_intern_plt, call_value_intern): Likewise. + * config/arm/aout.h (ASM_OUTPUT_ALIGN): Likewise. + * config/iq2000/iq2000.md (call_internal1, call_value_internal1, + call_value_multiple_internal1): Likewise. + * config/bfin/bfin.c (symbolic_reference_mentioned_p): Likewise. + +2021-05-26 Jan-Benedict Glaw + + * config/arc/arc.c (arc_address_cost, arc_print_operand_address, + arc_ccfsm_advance, symbolic_reference_mentioned_p, + arc_raw_symbolic_reference_mentioned_p): Remove register + keyword. + +2021-05-26 Jakub Jelinek + + PR libgomp/100573 + * omp-low.c: Include omp-offload.h. + (create_omp_child_function): If current_function_decl has + "omp declare target" attribute and is_gimple_omp_offloaded, + remove that attribute from the copy of attribute list and + add "omp target entrypoint" attribute instead. + (lower_omp_target): Mark .omp_data_sizes.* and .omp_data_kinds.* + variables for offloading if in omp_maybe_offloaded_ctx. + * omp-offload.c (pass_omp_target_link::execute): Nullify second + argument to GOMP_target_data_ext in offloaded code. + +2021-05-26 Geng Qi + + * config/csky/csky.c (csky_can_change_mode_class): Delete. + For csky, HF/SF mode use the low bits of VREGS. + +2021-05-26 Eric Botcazou + + * gimplify.c (gimplify_decl_expr): Do not clear TREE_READONLY on a + DECL which is a reference for OMP. + +2021-05-26 Martin Liska + + PR gcov-profile/100751 + * doc/gcov.texi: Document that __gcov_dump can be called just + once and that __gcov_reset resets run-time counters. + +2021-05-26 Martin Liska + + * doc/install.texi: Port relevant part from install-old.texi + and re-generate list of CPUs and systems. + +2021-05-26 Martin Liska + + * Makefile.in: Remove it. + * doc/include/fdl.texi: Update next/previous chapters. + * doc/install.texi: Likewise. + * doc/install-old.texi: Removed. + +2021-05-26 Geng Qi + + * config/csky/csky.c (ck810_legitimate_index_p): Support + "base + index" with DF mode. + * config/csky/constraints.md ("Y"): New constraint for memory operands + without index register. + * config/csky/csky_insn_fpuv2.md (fpuv3_movdf): Use "Y" instead of "m" + when mov between memory and general registers, and lower their priority. + * config/csky/csky_insn_fpuv3.md (fpuv2_movdf): Likewise. + +2021-05-26 Geng Qi + + * config/csky/csky.c (TARGET_PROMOTE_PROTOTYPES): Delete. + +2021-05-26 Geng Qi + + * config/csky/csky.md (untyped_call): Emit clobber for return + registers to mark them used. + +2021-05-26 Geng Qi + + * config/csky/csky.md (cskyv2_sextend_ldbs): New. + +2021-05-26 Andrew Pinski + + * match.pd (x < 0 ? ~y : y): New patterns. + +2021-05-26 Andrew Pinski + + * match.pd (A?CST1:CST2): Add simplifcations for A?0:+-1, A?+-1:0, + A?POW2:0 and A?0:POW2. + 2021-05-25 Andrew MacLeod * gimple-range-gori.cc (class logical_stmt_cache): Delete diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index f3c7e4f..328fa3e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210526 +20210527 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 14a8c58..0641e60 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2021-05-26 Jakub Jelinek + + * init.c (__gnat_error_handler): Remove register keyword. + 2021-05-25 Martin Liska * doc/share/conf.py: Fix Sphinx 4.0.x error. diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7780539..669a818 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2021-05-26 Eric Botcazou + + PR c/100653 + * c-decl.c (finish_struct): Warn for a union containing an aggregate + field with a differing scalar storage order. + 2021-05-21 Jakub Jelinek PR middle-end/99928 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1cbd043..7c13a6e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2021-05-26 Patrick Palka + + PR c++/100502 + * typeck.c (finish_class_member_access_expr): Disable ahead + of time access checking during the member lookup. + +2021-05-26 Patrick Palka + + PR c++/100368 + * tree.c (build_target_expr_with_type): Don't call force_rvalue + on CALL_EXPR initializer. Simplify now that bot_manip is no + longer a caller. + (bot_manip): Use force_target_expr instead of + build_target_expr_with_type. + +2021-05-26 Patrick Palka + + PR c++/97420 + * cvt.c (noexcept_conv_p): Remove redundant checks and simplify. + (fnptr_conv_p): Don't call non_reference. Use INDIRECT_TYPE_P + instead of TYPE_PTR_P. + * pt.c (convert_nontype_argument_function): Look through + implicit INDIRECT_REFs before calling strip_fnptr_conv. + 2021-05-25 Jakub Jelinek PR c++/100666 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 72d4f58..b62a557 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,58 @@ +2021-05-26 Patrick Palka + + PR c++/100502 + * g++.dg/template/access37.C: New test. + * g++.dg/template/access37a.C: New test. + +2021-05-26 Aldy Hernandez + + * gcc.dg/Wstringop-overflow-55.c: Adapt for range query changes. + * gcc.dg/pr80776-1.c: Same. + +2021-05-26 Uroš Bizjak + + * lib/target-supports.exp (check_effective_target_vect32): New. + (available_vector_sizes): Append 32 for x86 targets. + * gcc.dg/vect/pr71264.c (dg-final): Xfail scan dump for vect32 targets. + * gcc.dg/vect/slp-28.c (dg-final): Adjust dumps for vect32 targets. + * gcc.dg/vect/slp-3.c (dg-final): Ditto. + * gcc.target/i386/pr100637-3b.c: New test. + * gcc.target/i386/pr100637-3w.c: Ditto. + * gcc.target/i386/pr100637-4b.c: Ditto. + * gcc.target/i386/pr100637-4w.c: Ditto. + +2021-05-26 Eric Botcazou + + * gcc.dg/sso-13.c: New test. + +2021-05-26 Christophe Lyon + + * gcc.target/arm/simd/mve-vaddv-1.c: New test. + +2021-05-26 Patrick Palka + + PR c++/100368 + * g++.dg/cpp1z/elide6.C: New test. + +2021-05-26 Patrick Palka + + PR c++/97420 + * g++.dg/cpp0x/noexcept68.C: New test. + +2021-05-26 Geng Qi + + * gcc.target/csky/fldrd_fstrd.c: New. + * gcc.target/csky/fpuv3/fldr64_fstr64.c: New. + +2021-05-26 Geng Qi + + * gcc.target/csky/ldbs.c: New. + +2021-05-26 Andrew Pinski + + * gcc.dg/tree-ssa/pr96928.c: Update test for slightly different IR. + * gcc.dg/tree-ssa/pr96928-1.c: New testcase. + 2021-05-25 Jakub Jelinek PR c++/100666 -- cgit v1.1