[gcc/aoliva/heads/testme] (2 commits) [rs6000] adjust return_pc debug attrs
The branch 'aoliva/heads/testme' was updated to point to: 3bcf4294d89... [rs6000] adjust return_pc debug attrs It previously pointed to: 3612317409b... Introduce attribute sym_alias Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 3612317... Introduce attribute sym_alias Summary of changes (added commits): --- 3bcf429... [rs6000] adjust return_pc debug attrs a56062c... enable adjustment of return_pc debug attrs
[gcc(refs/users/aoliva/heads/testme)] enable adjustment of return_pc debug attrs
https://gcc.gnu.org/g:a56062c190d0324f8b84be3705fee494be390894 commit a56062c190d0324f8b84be3705fee494be390894 Author: Alexandre Oliva Date: Fri Apr 14 23:53:34 2023 -0300 enable adjustment of return_pc debug attrs This patch introduces infrastructure for targets to add an offset to the label issued after the call_insn to set the call_return_pc attribute. This will be used on rs6000, that sometimes issues another instruction after the call proper as part of a call insn. for gcc/ChangeLog * target.def (call_offset_return_label): New hook. * gcc/doc/tm.texi.in (TARGET_CALL_OFFSET_RETURN_LABEL): Add placeholder. * gcc/doc/tm.texi: Rebuild. * dwarf2out.cc (struct call_arg_loc_node): Record call_insn instad of call_arg_loc_note. (add_AT_lbl_id): Add optional offset argument. (gen_call_site_die): Compute and pass on a return pc offset. (gen_subprogram_die): Move call_arg_loc_note computation... (dwarf2out_var_location): ... from here. Set call_insn. Diff: --- gcc/doc/tm.texi| 7 +++ gcc/doc/tm.texi.in | 2 ++ gcc/dwarf2out.cc | 26 +- gcc/target.def | 9 + 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cd50078227d..8a7aa70d605 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5557,6 +5557,13 @@ except the last are treated as named. You need not define this hook if it always returns @code{false}. @end deftypefn +@deftypefn {Target Hook} int TARGET_CALL_OFFSET_RETURN_LABEL (rtx_insn *@var{call_insn}) +While generating call-site debug info for a CALL insn, or a SEQUENCE +insn starting with a CALL, this target hook is invoked to compute the +offset to be added to the debug label emitted after the call to obtain +the return address that should be recorded as the return PC. +@end deftypefn + @deftypefn {Target Hook} void TARGET_START_CALL_ARGS (cumulative_args_t @var{complete_args}) This target hook is invoked while generating RTL for a function call, after the argument values have been computed, and after stack arguments diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 058bd56487a..9e0830758ae 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3887,6 +3887,8 @@ These machine description macros help implement varargs: @hook TARGET_STRICT_ARGUMENT_NAMING +@hook TARGET_CALL_OFFSET_RETURN_LABEL + @hook TARGET_START_CALL_ARGS @hook TARGET_CALL_ARGS diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 5b064ffd78a..1092880738d 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -3593,7 +3593,7 @@ typedef struct var_loc_list_def var_loc_list; /* Call argument location list. */ struct GTY ((chain_next ("%h.next"))) call_arg_loc_node { - rtx GTY (()) call_arg_loc_note; + rtx_insn * GTY (()) call_insn; const char * GTY (()) label; tree GTY (()) block; bool tail_call_p; @@ -3777,7 +3777,8 @@ static void remove_addr_table_entry (addr_table_entry *); static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool); static inline rtx AT_addr (dw_attr_node *); static void add_AT_symview (dw_die_ref, enum dwarf_attribute, const char *); -static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *); +static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *, + int = 0); static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_range_list (dw_die_ref, enum dwarf_attribute, @@ -5353,14 +5354,17 @@ add_AT_symview (dw_die_ref die, enum dwarf_attribute attr_kind, static inline void add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, - const char *lbl_id) + const char *lbl_id, int offset) { dw_attr_node attr; attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_lbl_id; attr.dw_attr_val.val_entry = NULL; - attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id); + if (!offset) +attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id); + else +attr.dw_attr_val.v.val_lbl_id = xasprintf ("%s%+i", lbl_id, offset); if (dwarf_split_debug_info) attr.dw_attr_val.val_entry = add_addr_table_entry (attr.dw_attr_val.v.val_lbl_id, @@ -23515,7 +23519,9 @@ gen_call_site_die (tree decl, dw_die_ref subr_die, if (stmt_die == NULL) stmt_die = subr_die; die = new_die (dwarf_TAG (DW_TAG_call_site), stmt_die, NULL_TREE); - add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc), ca_loc->label); + add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc), +ca_loc->label, +targetm.calls.call_offset_return_label (ca_loc->call_insn)); if (ca_loc->tail_call_p) add_AT_flag (die, dwarf_AT (DW_AT_call_tail_call), 1); if (ca_lo
[gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
https://gcc.gnu.org/g:3bcf4294d8937a47886d2694a5888006f5d82741 commit 3bcf4294d8937a47886d2694a5888006f5d82741 Author: Alexandre Oliva Date: Fri Apr 14 23:53:35 2023 -0300 [rs6000] adjust return_pc debug attrs Some of the rs6000 call patterns, on some ABIs, issue multiple opcodes out of a single call insn, but the call (bl) or jump (b) is not always the last opcode in the sequence. This does not seem to be a problem for exception handling tables, but the return_pc attribute in the call graph output in dwarf2+ debug information, that takes the address of a label output right after the call, does not match the value of the link register even for non-tail calls. E.g., with ABI_AIX or ABI_ELFv2, such code as: foo (); outputs: bl foo nop LVL#: [...] .8byte .LVL# # DW_AT_call_return_pc but debug info consumers may rely on the return_pc address, and draw incorrect conclusions from its off-by-4 value. This patch uses the infrastructure for targets to add an offset to the label issued after the call_insn to set the call_return_pc attribute, on rs6000, to account for opcodes issued after actual call opcode as part of call insns output patterns. for gcc/ChangeLog * config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL): Override. (rs6000_call_offset_return_label): New. Diff: --- gcc/config/rs6000/rs6000.cc | 18 ++ 1 file changed, 18 insertions(+) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index e4dc629ddcc..77e6b94a539 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -1779,6 +1779,8 @@ static const scoped_attribute_specs *const rs6000_attribute_table[] = #undef TARGET_OVERLAP_OP_BY_PIECES_P #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true +#undef TARGET_CALL_OFFSET_RETURN_LABEL +#define TARGET_CALL_OFFSET_RETURN_LABEL rs6000_call_offset_return_label /* Processor table. */ @@ -14822,6 +14824,22 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p) return default_assemble_integer (x, size, aligned_p); } +/* Return the offset to be added to the label output after CALL_INSN + to compute the address to be placed in DW_AT_call_return_pc. */ + +static int +rs6000_call_offset_return_label (rtx_insn *call_insn) +{ + /* All rs6000 CALL_INSN output patterns start with a b or bl, always + a 4-byte instruction, but some output patterns issue other + opcodes afterwards. The return label is issued after the entire + call insn, including any such post-call opcodes. Instead of + figuring out which cases need adjustments, we compute the offset + back to the address of the call opcode proper, then add the + constant 4 bytes, to get the address after that opcode. */ + return 4 - get_attr_length (call_insn); +} + /* Return a template string for assembly to emit when making an external call. FUNOP is the call mem argument operand number. */
[gcc r15-831] [committed] [v2] More logical op simplifications in simplify-rtx.cc
https://gcc.gnu.org/g:05daf617ea22e1d818295ed2d037456937e23530 commit r15-831-g05daf617ea22e1d818295ed2d037456937e23530 Author: Jeff Law Date: Sat May 25 12:39:05 2024 -0600 [committed] [v2] More logical op simplifications in simplify-rtx.cc This is a revamp of what started as a target specific patch. Basically xalan (corrected, I originally thought it was perlbench) has a bitset implementation with a bit of an oddity. Specifically setBit will clear the bit before it is set: > if (bitToSet < 32) > { > fBits1 &= ~mask; > fBits1 |= mask; > } > else > { > fBits2 &= ~mask; > fBits2 |= mask; > } We can clean this up pretty easily in RTL with a small bit of code in simplify-rtx. While xalan doesn't have other cases, we can synthesize tests pretty easily and handle them as well. It turns out we don't actually have to recognize this stuff at the bit level, just standard logical identities are sufficient. For example (X | Y) & ~Y -> X & ~Y Andrew P. might poke at this at the gimple level. The type changes kindof get in the way in gimple but he's much better at match.pd than I am, so if he wants to chase it from the gimple side, I'll fully support that. Bootstrapped and regression tested on x86. Also run through my tester on its embedded targets. Pushing to the trunk. gcc/ * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): Handle more logical simplifications. gcc/testsuite/ * g++.target/riscv/redundant-bitmap-1.C: New test. * g++.target/riscv/redundant-bitmap-2.C: New test. * g++.target/riscv/redundant-bitmap-3.C: New test. * g++.target/riscv/redundant-bitmap-4.C: New test. Diff: --- gcc/simplify-rtx.cc| 29 ++ .../g++.target/riscv/redundant-bitmap-1.C | 14 +++ .../g++.target/riscv/redundant-bitmap-2.C | 14 +++ .../g++.target/riscv/redundant-bitmap-3.C | 14 +++ .../g++.target/riscv/redundant-bitmap-4.C | 14 +++ 5 files changed, 85 insertions(+) diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 53f54d1d392..5caf1dfd957 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -3549,6 +3549,12 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, return tem; } + /* Convert (ior (and (not A) B) A) into A | B. */ + if (GET_CODE (op0) == AND + && GET_CODE (XEXP (op0, 0)) == NOT + && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)) + return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1); + tem = simplify_byte_swapping_operation (code, mode, op0, op1); if (tem) return tem; @@ -3801,6 +3807,12 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, return tem; } + /* Convert (xor (and (not A) B) A) into A | B. */ + if (GET_CODE (op0) == AND + && GET_CODE (XEXP (op0, 0)) == NOT + && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)) + return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1); + tem = simplify_byte_swapping_operation (code, mode, op0, op1); if (tem) return tem; @@ -4006,6 +4018,23 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0))) return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0)); + /* (and (ior/xor (X Y) (not Y)) -> X & ~Y */ + if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR) + && GET_CODE (op1) == NOT + && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 1))) + return simplify_gen_binary (AND, mode, XEXP (op0, 0), + simplify_gen_unary (NOT, mode, + XEXP (op1, 0), + mode)); + /* (and (ior/xor (Y X) (not Y)) -> X & ~Y */ + if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR) + && GET_CODE (op1) == NOT + && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 0))) + return simplify_gen_binary (AND, mode, XEXP (op0, 1), + simplify_gen_unary (NOT, mode, + XEXP (op1, 0), + mode)); + /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */ if (GET_CODE (op0) == GET_CODE (op1) && (GET_CODE (op0) == AND diff --git a/gcc/testsuite/g++.target/riscv/redundant-bitmap-1.C b/gcc/testsuite/g++.target/riscv/redundant-bitmap-1.C new file mode 100644 index 00
[gcc r14-10244] Fortran: fix bounds check for assignment, class component [PR86100]
https://gcc.gnu.org/g:b0b21d5bdfbc7d417b70010a11354b44968bb184 commit r14-10244-gb0b21d5bdfbc7d417b70010a11354b44968bb184 Author: Harald Anlauf Date: Mon May 13 22:06:33 2024 +0200 Fortran: fix bounds check for assignment, class component [PR86100] gcc/fortran/ChangeLog: PR fortran/86100 * trans-array.cc (gfc_conv_ss_startstride): Use abridged_ref_name to generate a more user-friendly name for bounds-check messages. * trans-expr.cc (gfc_copy_class_to_class): Fix bounds check for rank>1 by looping over the dimensions. gcc/testsuite/ChangeLog: PR fortran/86100 * gfortran.dg/bounds_check_25.f90: New test. (cherry picked from commit 93765736815a049e14d985b758a213cfe60c1e1c) Diff: --- gcc/fortran/trans-array.cc| 7 - gcc/fortran/trans-expr.cc | 40 +++ gcc/testsuite/gfortran.dg/bounds_check_25.f90 | 32 + 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 7ec33fb1598..a15ff30e8f4 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -4911,6 +4911,7 @@ done: gfc_expr *expr; locus *expr_loc; const char *expr_name; + char *ref_name = NULL; ss_info = ss->info; if (ss_info->type != GFC_SS_SECTION) @@ -4922,7 +4923,10 @@ done: expr = ss_info->expr; expr_loc = &expr->where; - expr_name = expr->symtree->name; + if (expr->ref) + expr_name = ref_name = abridged_ref_name (expr, NULL); + else + expr_name = expr->symtree->name; gfc_start_block (&inner); @@ -5134,6 +5138,7 @@ done: gfc_add_expr_to_block (&block, tmp); + free (ref_name); } tmp = gfc_finish_block (&block); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index bc8eb419cff..d5fd6e39996 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1518,7 +1518,6 @@ gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited) stmtblock_t body; stmtblock_t ifbody; gfc_loopinfo loop; - tree orig_nelems = nelems; /* Needed for bounds check. */ gfc_init_block (&body); tmp = fold_build2_loc (input_location, MINUS_EXPR, @@ -1550,27 +1549,32 @@ gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited) /* Add bounds check. */ if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc) { - char *msg; const char *name = "<>"; - tree from_len; + int dim, rank; if (DECL_P (to)) - name = (const char *)(DECL_NAME (to)->identifier.id.str); - - from_len = gfc_conv_descriptor_size (from_data, 1); - from_len = fold_convert (TREE_TYPE (orig_nelems), from_len); - tmp = fold_build2_loc (input_location, NE_EXPR, - logical_type_node, from_len, orig_nelems); - msg = xasprintf ("Array bound mismatch for dimension %d " - "of array '%s' (%%ld/%%ld)", - 1, name); - - gfc_trans_runtime_check (true, false, tmp, &body, - &gfc_current_locus, msg, -fold_convert (long_integer_type_node, orig_nelems), - fold_convert (long_integer_type_node, from_len)); + name = IDENTIFIER_POINTER (DECL_NAME (to)); - free (msg); + rank = GFC_TYPE_ARRAY_RANK (TREE_TYPE (from_data)); + for (dim = 1; dim <= rank; dim++) + { + tree from_len, to_len, cond; + char *msg; + + from_len = gfc_conv_descriptor_size (from_data, dim); + from_len = fold_convert (long_integer_type_node, from_len); + to_len = gfc_conv_descriptor_size (to_data, dim); + to_len = fold_convert (long_integer_type_node, to_len); + msg = xasprintf ("Array bound mismatch for dimension %d " + "of array '%s' (%%ld/%%ld)", + dim, name); + cond = fold_build2_loc (input_location, NE_EXPR, + logical_type_node, from_len, to_len); + gfc_trans_runtime_check (true, false, cond, &body, + &gfc_current_locus, msg, + to_len, from_len); + free (msg); + } } tmp = build_call_vec (fcn_type, fcn, args); diff --git a/gcc/testsuite/gfortran.dg/bounds_check_25.f90 b/gcc/testsuite/gfortran.dg/bounds_check_25.f90 new file mode 100644 index 000..cc2247597f9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bounds_check_25.f90 @@ -0,0 +1,3
[gcc r15-833] Delete gori_map during destruction of GORI.
https://gcc.gnu.org/g:f9810728cf42ea7c3d84198aa582e53cfb2302d1 commit r15-833-gf9810728cf42ea7c3d84198aa582e53cfb2302d1 Author: Andrew MacLeod Date: Sat May 25 12:28:52 2024 -0400 Delete gori_map during destruction of GORI. Forgot to free the gori_mpa object when a gori object is freed. PR tree-optimization/115208 * value-query.cc (range_query::create_gori): Confirm gori_map is NULL. (range_query::destroy_gori): Free gori_map if one was allocated. Diff: --- gcc/value-query.cc | 4 1 file changed, 4 insertions(+) diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 0d0c0e8058e..556a0f39b09 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -188,6 +188,7 @@ void range_query::create_gori (int not_executable_flag, int sw_max_edges) { gcc_checking_assert (m_gori == &default_gori); + gcc_checking_assert (m_map == NULL); m_map = new gori_map (); gcc_checking_assert (m_map); m_gori = new gori_compute (*m_map, not_executable_flag, sw_max_edges); @@ -199,6 +200,9 @@ range_query::destroy_gori () { if (m_gori && m_gori != &default_gori) delete m_gori; + if (m_map) +delete m_map; + m_map = NULL; m_gori= &default_gori; }