diff --git a/gcc.spec b/gcc.spec index 8b02282..093e6ef 100644 --- a/gcc.spec +++ b/gcc.spec @@ -255,6 +255,9 @@ Patch9: gcc9-Wno-format-security.patch Patch10: gcc9-rh1574936.patch Patch11: gcc9-d-shared-libphobos.patch Patch12: gcc9-pr89093.patch +Patch13: gcc9-pr89794.patch +Patch14: gcc9-pr90071.patch +Patch15: gcc9-pr90074.patch Patch1000: nvptx-tools-no-ptxas.patch Patch1001: nvptx-tools-build.patch @@ -766,6 +769,9 @@ to NVidia PTX capable devices if available. %endif %patch11 -p0 -b .d-shared-libphobos~ %patch12 -p0 -b .pr89093~ +%patch13 -p0 -b .pr89794~ +%patch14 -p0 -b .pr90071~ +%patch15 -p0 -b .pr90074~ cd nvptx-tools-%{nvptx_tools_gitrev} %patch1000 -p1 -b .nvptx-tools-no-ptxas~ @@ -2992,6 +2998,7 @@ end tree-optimization/89730, tree-optimization/89956, tree-optimization/89998, tree-optimization/90006, tree-optimization/90018, tree-optimization/90020 +- PRs rtl-optimization/89794, tree-optimization/90071, debug/90074 * Thu Mar 28 2019 Jakub Jelinek 9.0.1-0.12 - update from trunk diff --git a/gcc9-foffload-default.patch b/gcc9-foffload-default.patch index 2ecd537..ac462f1 100644 --- a/gcc9-foffload-default.patch +++ b/gcc9-foffload-default.patch @@ -70,7 +70,7 @@ libgomp/ + if (!compiler) fatal_error (input_location, - "could not find %s in %s (consider using '-B')\n", suffix + 1, + "could not find %s in %s (consider using %<-B%>)\n", @@ -883,6 +890,7 @@ compile_images_for_offload_targets (unsi unsigned num_targets = parse_env_var (target_names, &names, NULL); diff --git a/gcc9-pr89794.patch b/gcc9-pr89794.patch new file mode 100644 index 0000000..d76f002 --- /dev/null +++ b/gcc9-pr89794.patch @@ -0,0 +1,142 @@ +2019-04-15 Segher Boessenkool + + PR rtl-optimization/89794 + * combine.c (count_auto_inc): New function. + (try_combine): Count how many auto_inc expressions there were in the + original instructions. Ensure we have the same number in the new + instructions. Remove the code that tried to ensure auto_inc side + effects on i1 and i0 are not lost. + + * gcc.dg/torture/pr89794.c: New testcase. + +--- gcc/combine.c (revision 270367) ++++ gcc/combine.c (revision 270368) +@@ -2641,6 +2641,16 @@ is_just_move (rtx x) + return (GET_CODE (x) == SET && general_operand (SET_SRC (x), VOIDmode)); + } + ++/* Callback function to count autoincs. */ ++ ++static int ++count_auto_inc (rtx, rtx, rtx, rtx, rtx, void *arg) ++{ ++ (*((int *) arg))++; ++ ++ return 0; ++} ++ + /* Try to combine the insns I0, I1 and I2 into I3. + Here I0, I1 and I2 appear earlier than I3. + I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into +@@ -2706,6 +2716,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, + int split_i2i3 = 0; + int changed_i3_dest = 0; + bool i2_was_move = false, i3_was_move = false; ++ int n_auto_inc = 0; + + int maxreg; + rtx_insn *temp_insn; +@@ -3210,6 +3221,16 @@ try_combine (rtx_insn *i3, rtx_insn *i2, + return 0; + } + ++ /* Count how many auto_inc expressions there were in the original insns; ++ we need to have the same number in the resulting patterns. */ ++ ++ if (i0) ++ for_each_inc_dec (PATTERN (i0), count_auto_inc, &n_auto_inc); ++ if (i1) ++ for_each_inc_dec (PATTERN (i1), count_auto_inc, &n_auto_inc); ++ for_each_inc_dec (PATTERN (i2), count_auto_inc, &n_auto_inc); ++ for_each_inc_dec (PATTERN (i3), count_auto_inc, &n_auto_inc); ++ + /* If the set in I2 needs to be kept around, we must make a copy of + PATTERN (I2), so that when we substitute I1SRC for I1DEST in + PATTERN (I2), we are only substituting for the original I1DEST, not into +@@ -3411,18 +3432,11 @@ try_combine (rtx_insn *i3, rtx_insn *i2, + + if (i1 && GET_CODE (newpat) != CLOBBER) + { +- /* Check that an autoincrement side-effect on I1 has not been lost. +- This happens if I1DEST is mentioned in I2 and dies there, and +- has disappeared from the new pattern. */ +- if ((FIND_REG_INC_NOTE (i1, NULL_RTX) != 0 +- && i1_feeds_i2_n +- && dead_or_set_p (i2, i1dest) +- && !reg_overlap_mentioned_p (i1dest, newpat)) +- /* Before we can do this substitution, we must redo the test done +- above (see detailed comments there) that ensures I1DEST isn't +- mentioned in any SETs in NEWPAT that are field assignments. */ +- || !combinable_i3pat (NULL, &newpat, i1dest, NULL_RTX, NULL_RTX, +- 0, 0, 0)) ++ /* Before we can do this substitution, we must redo the test done ++ above (see detailed comments there) that ensures I1DEST isn't ++ mentioned in any SETs in NEWPAT that are field assignments. */ ++ if (!combinable_i3pat (NULL, &newpat, i1dest, NULL_RTX, NULL_RTX, ++ 0, 0, 0)) + { + undo_all (); + return 0; +@@ -3452,12 +3466,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, + + if (i0 && GET_CODE (newpat) != CLOBBER) + { +- if ((FIND_REG_INC_NOTE (i0, NULL_RTX) != 0 +- && ((i0_feeds_i2_n && dead_or_set_p (i2, i0dest)) +- || (i0_feeds_i1_n && dead_or_set_p (i1, i0dest))) +- && !reg_overlap_mentioned_p (i0dest, newpat)) +- || !combinable_i3pat (NULL, &newpat, i0dest, NULL_RTX, NULL_RTX, +- 0, 0, 0)) ++ if (!combinable_i3pat (NULL, &newpat, i0dest, NULL_RTX, NULL_RTX, ++ 0, 0, 0)) + { + undo_all (); + return 0; +@@ -3478,6 +3488,20 @@ try_combine (rtx_insn *i3, rtx_insn *i2, + substed_i0 = 1; + } + ++ if (n_auto_inc) ++ { ++ int new_n_auto_inc = 0; ++ for_each_inc_dec (newpat, count_auto_inc, &new_n_auto_inc); ++ ++ if (n_auto_inc != new_n_auto_inc) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Number of auto_inc expressions changed\n"); ++ undo_all (); ++ return 0; ++ } ++ } ++ + /* Fail if an autoincrement side-effect has been duplicated. Be careful + to count all the ways that I2SRC and I1SRC can be used. */ + if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0 +--- gcc/testsuite/gcc.dg/torture/pr89794.c (nonexistent) ++++ gcc/testsuite/gcc.dg/torture/pr89794.c (revision 270368) +@@ -0,0 +1,24 @@ ++/* { dg-do run } */ ++ ++typedef unsigned short u16; ++typedef unsigned int u32; ++typedef unsigned long long u64; ++ ++u32 a, b, c, d; ++ ++u32 foo (u32 f, u32 g, u32 g2, u32 g3, u16 h, u16 i) ++{ ++ (void)g, (void)g2, (void)g3, (void)h; ++ d = __builtin_bswap64 (i); ++ __builtin_sub_overflow (0, d, &b); ++ __builtin_memset (&i, c, 2); ++ a = 0; ++ return b + f + i + c; ++} ++ ++int main (void) ++{ ++ u32 x = foo (0, 0, 0, 0, 0, 0); ++ asm ("" :: "r" (x)); ++ return 0; ++} diff --git a/gcc9-pr90071.patch b/gcc9-pr90071.patch new file mode 100644 index 0000000..66dcb3a --- /dev/null +++ b/gcc9-pr90071.patch @@ -0,0 +1,47 @@ +2019-04-15 Richard Biener + + PR tree-optimization/90071 + * tree-ssa-reassoc.c (init_range_entry): Do not pick up + abnormal operands from def stmts. + + * gcc.dg/torture/pr90071.c: New testcase. + +--- gcc/tree-ssa-reassoc.c (revision 270368) ++++ gcc/tree-ssa-reassoc.c (revision 270369) +@@ -2143,7 +2143,8 @@ init_range_entry (struct range_entry *r, + exp_type = boolean_type_node; + } + +- if (TREE_CODE (arg0) != SSA_NAME) ++ if (TREE_CODE (arg0) != SSA_NAME ++ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg0)) + break; + loc = gimple_location (stmt); + switch (code) +--- gcc/testsuite/gcc.dg/torture/pr90071.c (nonexistent) ++++ gcc/testsuite/gcc.dg/torture/pr90071.c (revision 270369) +@@ -0,0 +1,24 @@ ++/* { dg-do compile } */ ++ ++int a; ++static int b; ++ ++void ++foo () ++{ ++ int d; ++ int e = (int) (__INTPTR_TYPE__) &&f; ++ void *g = &&h; ++h: ++e; ++ if (a) ++ i: goto *g; ++ for (;;) ++ { ++ e = 0; ++ if (b) ++ goto i; ++ } ++f: ++ goto *({ d || e < 0 || e >= 2; }); ++ &e; ++} diff --git a/gcc9-pr90074.patch b/gcc9-pr90074.patch new file mode 100644 index 0000000..b57aac2 --- /dev/null +++ b/gcc9-pr90074.patch @@ -0,0 +1,107 @@ +2019-04-15 Richard Biener + + PR debug/90074 + * tree-loop-distribution.c (destroy_loop): Preserve correct + debug info. + + * gcc.dg/guality/pr90074.c: New testcase. + +--- gcc/tree-loop-distribution.c (revision 270369) ++++ gcc/tree-loop-distribution.c (revision 270370) +@@ -1094,12 +1094,8 @@ destroy_loop (struct loop *loop) + + bbs = get_loop_body_in_dom_order (loop); + +- redirect_edge_pred (exit, src); +- exit->flags &= ~(EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); +- exit->flags |= EDGE_FALLTHRU; +- cancel_loop_tree (loop); +- rescan_loop_exit (exit, false, true); +- ++ gimple_stmt_iterator dst_gsi = gsi_after_labels (exit->dest); ++ bool safe_p = single_pred_p (exit->dest); + i = nbbs; + do + { +@@ -1116,14 +1112,45 @@ destroy_loop (struct loop *loop) + if (virtual_operand_p (gimple_phi_result (phi))) + mark_virtual_phi_result_for_renaming (phi); + } +- for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); +- gsi_next (&gsi)) ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);) + { + gimple *stmt = gsi_stmt (gsi); + tree vdef = gimple_vdef (stmt); + if (vdef && TREE_CODE (vdef) == SSA_NAME) + mark_virtual_operand_for_renaming (vdef); ++ /* Also move and eventually reset debug stmts. We can leave ++ constant values in place in case the stmt dominates the exit. ++ ??? Non-constant values from the last iteration can be ++ replaced with final values if we can compute them. */ ++ if (gimple_debug_bind_p (stmt)) ++ { ++ tree val = gimple_debug_bind_get_value (stmt); ++ gsi_move_before (&gsi, &dst_gsi); ++ if (val ++ && (!safe_p ++ || !is_gimple_min_invariant (val) ++ || !dominated_by_p (CDI_DOMINATORS, exit->src, bbs[i]))) ++ { ++ gimple_debug_bind_reset_value (stmt); ++ update_stmt (stmt); ++ } ++ } ++ else ++ gsi_next (&gsi); + } ++ } ++ while (i != 0); ++ ++ redirect_edge_pred (exit, src); ++ exit->flags &= ~(EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); ++ exit->flags |= EDGE_FALLTHRU; ++ cancel_loop_tree (loop); ++ rescan_loop_exit (exit, false, true); ++ ++ i = nbbs; ++ do ++ { ++ --i; + delete_basic_block (bbs[i]); + } + while (i != 0); +--- gcc/testsuite/gcc.dg/guality/pr90074.c (nonexistent) ++++ gcc/testsuite/gcc.dg/guality/pr90074.c (revision 270370) +@@ -0,0 +1,31 @@ ++/* { dg-do run } */ ++/* { dg-options "-g" } */ ++ ++void __attribute__((noinline)) ++optimize_me_not () ++{ ++ __asm__ volatile ("" : : : "memory"); ++} ++char a; ++short b[7][1]; ++int main() ++{ ++ int i, c; ++ a = 0; ++ i = 0; ++ for (; i < 7; i++) { ++ c = 0; ++ for (; c < 1; c++) ++ b[i][c] = 0; ++ } ++ /* i may very well be optimized out, so we cannot test for i == 7. ++ Instead test i + 1 which will make the test UNSUPPORTED if i ++ is optimized out. Since the test previously had wrong debug ++ with i == 0 this is acceptable. Optimally we'd produce a ++ debug stmt for the final value of the loop during loop distribution ++ which would fix the UNSUPPORTED cases. ++ c is optimized out at -Og for no obvious reason. */ ++ optimize_me_not(); /* { dg-final { gdb-test . "i + 1" "8" } } */ ++ /* { dg-final { gdb-test .-1 "c + 1" "2" } } */ ++ return 0; ++}