[PATCH] widening_mul: Recognize another form of ADD_OVERFLOW [PR96272]
Hi! The following patch recognizes another form of hand written __builtin_add_overflow (this time _p), in particular when the code does unsigned if (x > ~0U - y) or if (x <= ~0U - y) it can be optimized (if the subtraction turned into ~y is single use) into if (__builtin_add_overflow_p (x, y, 0U)) or if (!__builtin_add_overflow_p (x, y, 0U)) and generate better code, e.g. for the first function in the testcase: - movl%esi, %eax addl%edi, %esi - notl%eax - cmpl%edi, %eax - movl$-1, %eax - cmovnb %esi, %eax + jc .L3 + movl%esi, %eax + ret +.L3: + orl $-1, %eax ret on x86_64. As for the jumps vs. conditional move case, that is some CE issue with complex branch patterns we should fix up no matter what, but in this case I'm actually not sure if branchy code isn't better, overflow is something that isn't that common. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-12-12 Jakub Jelinek PR tree-optimization/96272 * tree-ssa-math-opts.c (uaddsub_overflow_check_p): Add OTHER argument. Handle BIT_NOT_EXPR. (match_uaddsub_overflow): Optimize unsigned a > ~b into __imag__ .ADD_OVERFLOW (a, b). (math_opts_dom_walker::after_dom_children): Call match_uaddsub_overflow even for BIT_NOT_EXPR. * gcc.dg/tree-ssa/pr96272.c: New test. --- gcc/tree-ssa-math-opts.c.jj 2020-11-22 19:16:25.302440812 +0100 +++ gcc/tree-ssa-math-opts.c2020-12-11 16:19:17.314846597 +0100 @@ -3457,7 +3457,8 @@ convert_mult_to_fma (gimple *mul_stmt, t and 0 otherwise. */ static int -uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt, tree maxval) +uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt, tree maxval, + tree *other) { enum tree_code ccode = ERROR_MARK; tree crhs1 = NULL_TREE, crhs2 = NULL_TREE; @@ -3520,6 +3521,13 @@ uaddsub_overflow_check_p (gimple *stmt, || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2) && crhs2 == lhs)) return ccode == GT_EXPR ? 1 : -1; + /* r = ~a; b > r or b <= r. */ + if (code == BIT_NOT_EXPR && crhs2 == lhs) + { + if (other) + *other = crhs1; + return ccode == GT_EXPR ? 1 : -1; + } break; case LT_EXPR: case GE_EXPR: @@ -3531,6 +3539,13 @@ uaddsub_overflow_check_p (gimple *stmt, || (code == PLUS_EXPR && crhs1 == lhs && (crhs2 == rhs1 || crhs2 == rhs2))) return ccode == LT_EXPR ? 1 : -1; + /* r = ~a; r < b or r >= b. */ + if (code == BIT_NOT_EXPR && crhs1 == lhs) + { + if (other) + *other = crhs2; + return ccode == LT_EXPR ? 1 : -1; + } break; default: break; @@ -3560,7 +3575,15 @@ uaddsub_overflow_check_p (gimple *stmt, _9 = REALPART_EXPR <_7>; _8 = IMAGPART_EXPR <_8>; if (_8) - and replace (utype) x with _9. */ + and replace (utype) x with _9. + + Also recognize: + x = ~z; + if (y > x) + and replace it with + _7 = ADD_OVERFLOW (y, z); + _8 = IMAGPART_EXPR <_8>; + if (_8) */ static bool match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt, @@ -3576,34 +3599,49 @@ match_uaddsub_overflow (gimple_stmt_iter gimple *add_stmt = NULL; bool add_first = false; - gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR); + gcc_checking_assert (code == PLUS_EXPR + || code == MINUS_EXPR + || code == BIT_NOT_EXPR); if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type) || has_zero_uses (lhs) - || (code == MINUS_EXPR - && optab_handler (usubv4_optab, + || (code != PLUS_EXPR + && optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab, TYPE_MODE (type)) == CODE_FOR_nothing)) return false; + tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs2 (stmt); FOR_EACH_IMM_USE_FAST (use_p, iter, lhs) { use_stmt = USE_STMT (use_p); if (is_gimple_debug (use_stmt)) continue; - if (uaddsub_overflow_check_p (stmt, use_stmt, NULL_TREE)) - ovf_use_seen = true; + tree other = NULL_TREE; + if (uaddsub_overflow_check_p (stmt, use_stmt, NULL_TREE, &other)) + { + if (code == BIT_NOT_EXPR) + { + gcc_assert (other); + if (TREE_CODE (other) != SSA_NAME) + return false; + if (rhs2 == NULL) + rhs2 = other; + else if (rhs2 != other) + return false; + } + ovf_use_seen = true; + } else use_seen = true; if (ovf_use_seen && use_seen) break; } - tree rhs1 = gimple_assign_rhs1 (stmt); - tree rhs2 = gimple_assign_rhs2 (stmt); tree maxval = NULL_TREE; if (!ovf_use_seen - || !u
[PATCH] match.pd: Add ~(X - Y) -> ~X + Y simplification [PR96685]
Hi! This patch adds the ~(X - Y) -> ~X + Y simplification requested in the PR (plus also ~(X + C) -> ~X + (-C) for constants C that can be safely negated. The first two simplify blocks is what has been requested in the PR and that makes the first testcase pass. Unfortunately, that change also breaks the second testcase, because while the same expressions appearing in the same stmt and split across multiple stmts has been folded (not really) before, with this optimization fold-const.c optimizes ~X + Y further into (Y - X) - 1 in fold_binary_loc associate: code, but we have nothing like that in GIMPLE and so end up with different expressions. The last simplify is an attempt to deal with just this case, had to rule out there the Y == -1U case, because then we reached infinite recursion as ~X + -1U was canonicalized by the pattern into (-1U - X) + -1U but there is a canonicalization -1 - A -> ~A that turns it back. Furthermore, had to make it #if GIMPLE only, because it otherwise resulted in infinite recursion when interacting with the associate: optimization. The end result is that we pass all 3 testcases and thus canonizalize the 3 possible forms of writing the same thing. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-12-12 Jakub Jelinek PR tree-optimization/96685 * match.pd (~(X - Y) -> ~X + Y): New optimization. (~X + Y -> (Y - X) - 1): Likewise. * gcc.dg/tree-ssa/pr96685-1.c: New test. * gcc.dg/tree-ssa/pr96685-2.c: New test. * gcc.dg/tree-ssa/pr96685-3.c: New test. --- gcc/match.pd.jj 2020-12-11 16:41:45.797787831 +0100 +++ gcc/match.pd2020-12-11 23:12:45.769291586 +0100 @@ -1074,6 +1074,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_not (plus:c (bit_not @0) @1)) (minus @0 @1)) +/* ~(X - Y) -> ~X + Y. */ +(simplify + (bit_not (minus:s @0 @1)) + (plus (bit_not @0) @1)) +(simplify + (bit_not (plus:s @0 INTEGER_CST@1)) + (if ((INTEGRAL_TYPE_P (type) + && TYPE_UNSIGNED (type)) + || (!TYPE_OVERFLOW_SANITIZED (type) + && may_negate_without_overflow_p (@1))) + (plus (bit_not @0) { const_unop (NEGATE_EXPR, type, @1); }))) + +#if GIMPLE +/* ~X + Y -> (Y - X) - 1. */ +(simplify + (plus:c (bit_not @0) @1) + (if (ANY_INTEGRAL_TYPE_P (type) + && TYPE_OVERFLOW_WRAPS (type) + /* -1 - X is folded to ~X, so we'd recurse endlessly. */ + && !integer_all_onesp (@1)) + (plus (minus @1 @0) { build_minus_one_cst (type); }) + (if (INTEGRAL_TYPE_P (type) + && TREE_CODE (@1) == INTEGER_CST + && wi::to_wide (@1) != wi::min_value (TYPE_PRECISION (type), + SIGNED)) +(minus (plus @1 { build_minus_one_cst (type); }) @0 +#endif + /* x + (x & 1) -> (x + 1) & ~1 */ (simplify (plus:c @0 (bit_and:s @0 integer_onep@1)) --- gcc/testsuite/gcc.dg/tree-ssa/pr96685-1.c.jj2020-12-11 16:42:03.975584838 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-1.c 2020-12-11 16:42:03.975584838 +0100 @@ -0,0 +1,52 @@ +/* PR tree-optimization/96685 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "return 1;" 6 "optimized" } } */ + +unsigned +f1 (unsigned x, unsigned y) +{ + unsigned a = ~(x - y); + unsigned b = ~x + y; + return a == b; +} + +unsigned +f2 (unsigned x) +{ + unsigned a = ~(x + -124U); + unsigned b = ~x + 124U; + return a == b; +} + +unsigned +f3 (unsigned x) +{ + unsigned a = ~(x + 124U); + unsigned b = ~x + -124U; + return a == b; +} + +int +f4 (int x, int y) +{ + int a = ~(x - y); + int b = ~x + y; + return a == b; +} + +int +f5 (int x) +{ + int a = ~(x + -124); + int b = ~x + 124; + return a == b; +} + +int +f6 (int x) +{ + int a = ~(x + 124); + int b = ~x + -124; + return a == b; +} --- gcc/testsuite/gcc.dg/tree-ssa/pr96685-2.c.jj2020-12-11 16:42:03.975584838 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-2.c 2020-12-11 16:42:03.975584838 +0100 @@ -0,0 +1,40 @@ +/* PR tree-optimization/96685 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */ + +int +f1 (unsigned x, unsigned y) +{ + unsigned int r1 = (x - y); + r1 = ~r1; + unsigned int r2 = ~(x - y); + return r1 == r2; +} + +int +f2 (unsigned x, unsigned y) +{ + unsigned int r1 = (x - 23); + r1 = ~r1; + unsigned int r2 = ~(x - 23); + return r1 == r2; +} + +int +f3 (int x, int y) +{ + int r1 = (x - y); + r1 = ~r1; + int r2 = ~(x - y); + return r1 == r2; +} + +int +f4 (int x, int y) +{ + int r1 = (x - 23); + r1 = ~r1; + int r2 = ~(x - 23); + return r1 == r2; +} --- gcc/testsuite/gcc.dg/tree-ssa/pr96685-3.c.jj2020-12-11 17:35:09.536123227 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-3.c 2020-12-11 17:34:31.911543423 +0100 @@ -0,0 +1,43 @@ +/* PR tree-optimization/96685 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */
[Patch, fortran] PR97694 - ICE with optional assumed rank class(*) argument (and PR97723)
Fortran: Fix some select rank issues [PR97694 and 97723]. Hi All, Unlike select type, select rank selectors retain the allocatable attribute. This is corrected by the chunk in check.c. Note the trailing whitespace corrections. Resolution of select rank construct must be done in the same way as select type and so the break has been added to ensure that the block is resolved in resolve_select_rank. The final chunk prevents segfaults for class associate variables that are optional dummies, since these apparently are not adorned with the GFC_DECL_SAVED_DESCRIPTOR. Regtests OK on FC31/x86_64 - OK for master? Cheers Paul 2020-12-12 Paul Thomas gcc/fortran PR fortran/97694 PR fortran/97723 * check.c (allocatable_check): Select rank temporaries are permitted even though they are treated as associate variables. * resolve.c (gfc_resolve_code): Break on select rank as well as select type so that the block os resolved. * trans-stmt.c (trans_associate_var): Class associate variables that are optional dummies must use the backend_decl. gcc/testsuite/ PR fortran/97694 PR fortran/97723 * gfortran.dg/select_rank_5.f90: New test. diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 1e64fab3401..d8829e42b18 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -289,7 +289,7 @@ bin2real (gfc_expr *x, int kind) } -/* Fortran 2018 treats a BOZ as simply a string of bits. gfc_boz2real () +/* Fortran 2018 treats a BOZ as simply a string of bits. gfc_boz2real () converts the string into a REAL of the appropriate kind. The treatment of the sign bit is processor dependent. */ @@ -377,12 +377,12 @@ gfc_boz2real (gfc_expr *x, int kind) } -/* Fortran 2018 treats a BOZ as simply a string of bits. gfc_boz2int () +/* Fortran 2018 treats a BOZ as simply a string of bits. gfc_boz2int () converts the string into an INTEGER of the appropriate kind. The treatment of the sign bit is processor dependent. If the converted value exceeds the range of the type, then wrap-around semantics are applied. */ - + bool gfc_boz2int (gfc_expr *x, int kind) { @@ -975,7 +975,8 @@ allocatable_check (gfc_expr *e, int n) symbol_attribute attr; attr = gfc_variable_attr (e, NULL); - if (!attr.allocatable || attr.associate_var) + if (!attr.allocatable + || (attr.associate_var && !attr.select_rank_temporary)) { gfc_error ("%qs argument of %qs intrinsic at %L must be ALLOCATABLE", gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic, @@ -3232,7 +3233,7 @@ gfc_check_intconv (gfc_expr *x) || strcmp (gfc_current_intrinsic, "long") == 0) { gfc_error ("%qs intrinsic subprogram at %L has been deprecated. " - "Use INT intrinsic subprogram.", gfc_current_intrinsic, + "Use INT intrinsic subprogram.", gfc_current_intrinsic, &x->where); return false; } @@ -3965,7 +3966,7 @@ gfc_check_findloc (gfc_actual_arglist *ap) /* Check the kind of the characters argument match. */ if (a1 && v1 && a->ts.kind != v->ts.kind) goto incompat; - + d = ap->next->next->expr; m = ap->next->next->next->expr; k = ap->next->next->next->next->expr; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 0a8f90775ab..891571c0864 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -11776,8 +11776,9 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns) gfc_resolve_omp_do_blocks (code, ns); break; case EXEC_SELECT_TYPE: - /* Blocks are handled in resolve_select_type because we have - to transform the SELECT TYPE into ASSOCIATE first. */ + case EXEC_SELECT_RANK: + /* Blocks are handled in resolve_select_type/rank because we + have to transform the SELECT TYPE into ASSOCIATE first. */ break; case EXEC_DO_CONCURRENT: gfc_do_concurrent_flag = 1; diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index adc6b8fefb5..ab99e579461 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -1784,7 +1784,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) if (e->ts.type == BT_CLASS) { /* Go straight to the class data. */ - if (sym2->attr.dummy) + if (sym2->attr.dummy && !sym2->attr.optional) { class_decl = DECL_LANG_SPECIFIC (sym2->backend_decl) ? GFC_DECL_SAVED_DESCRIPTOR (sym2->backend_decl) : ! { dg-do run } ! ! Test the fixes for PR97723 and PR97694. ! ! Contributed by Martin ! module mod implicit none private public cssel contains function cssel(x) result(s) character(len=:), allocatable :: s class(*), dimension(..), optional, intent(in) :: x if (present(x)) then select rank (x) rank (0) s = '0' ! PR97723: ‘assign’ at (1) is not a function ! PR97694: ICE in trans-stmt.c(trans_associate_var) rank (1) s = '1' ! PR97723: ‘assign’ at (1) is not a function rank default s = '?'
Re: [PATCH] match.pd: Add ~(X - Y) -> ~X + Y simplification [PR96685]
On December 12, 2020 9:10:41 AM GMT+01:00, Jakub Jelinek wrote: >Hi! > >This patch adds the ~(X - Y) -> ~X + Y simplification requested >in the PR (plus also ~(X + C) -> ~X + (-C) for constants C that can >be safely negated. > >The first two simplify blocks is what has been requested in the PR >and that makes the first testcase pass. >Unfortunately, that change also breaks the second testcase, because >while the same expressions appearing in the same stmt and split >across multiple stmts has been folded (not really) before, with >this optimization fold-const.c optimizes ~X + Y further into >(Y - X) - 1 in fold_binary_loc associate: code, but we have nothing >like that in GIMPLE and so end up with different expressions. > >The last simplify is an attempt to deal with just this case, >had to rule out there the Y == -1U case, because then we >reached infinite recursion as ~X + -1U was canonicalized by >the pattern into (-1U - X) + -1U but there is a canonicalization >-1 - A -> ~A that turns it back. Furthermore, had to make it >#if GIMPLE only, because it otherwise resulted in infinite recursion >when interacting with the associate: optimization. >The end result is that we pass all 3 testcases and thus canonizalize >the 3 possible forms of writing the same thing. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Ok. Thanks, Richard. >2020-12-12 Jakub Jelinek > > PR tree-optimization/96685 > * match.pd (~(X - Y) -> ~X + Y): New optimization. > (~X + Y -> (Y - X) - 1): Likewise. > > * gcc.dg/tree-ssa/pr96685-1.c: New test. > * gcc.dg/tree-ssa/pr96685-2.c: New test. > * gcc.dg/tree-ssa/pr96685-3.c: New test. > >--- gcc/match.pd.jj2020-12-11 16:41:45.797787831 +0100 >+++ gcc/match.pd 2020-12-11 23:12:45.769291586 +0100 >@@ -1074,6 +1074,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (bit_not (plus:c (bit_not @0) @1)) > (minus @0 @1)) > >+/* ~(X - Y) -> ~X + Y. */ >+(simplify >+ (bit_not (minus:s @0 @1)) >+ (plus (bit_not @0) @1)) >+(simplify >+ (bit_not (plus:s @0 INTEGER_CST@1)) >+ (if ((INTEGRAL_TYPE_P (type) >+ && TYPE_UNSIGNED (type)) >+ || (!TYPE_OVERFLOW_SANITIZED (type) >+&& may_negate_without_overflow_p (@1))) >+ (plus (bit_not @0) { const_unop (NEGATE_EXPR, type, @1); }))) >+ >+#if GIMPLE >+/* ~X + Y -> (Y - X) - 1. */ >+(simplify >+ (plus:c (bit_not @0) @1) >+ (if (ANY_INTEGRAL_TYPE_P (type) >+ && TYPE_OVERFLOW_WRAPS (type) >+ /* -1 - X is folded to ~X, so we'd recurse endlessly. */ >+ && !integer_all_onesp (@1)) >+ (plus (minus @1 @0) { build_minus_one_cst (type); }) >+ (if (INTEGRAL_TYPE_P (type) >+ && TREE_CODE (@1) == INTEGER_CST >+ && wi::to_wide (@1) != wi::min_value (TYPE_PRECISION (type), >+SIGNED)) >+(minus (plus @1 { build_minus_one_cst (type); }) @0 >+#endif >+ > /* x + (x & 1) -> (x + 1) & ~1 */ > (simplify > (plus:c @0 (bit_and:s @0 integer_onep@1)) >--- gcc/testsuite/gcc.dg/tree-ssa/pr96685-1.c.jj 2020-12-11 >16:42:03.975584838 +0100 >+++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-1.c 2020-12-11 >16:42:03.975584838 +0100 >@@ -0,0 +1,52 @@ >+/* PR tree-optimization/96685 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -fdump-tree-optimized" } */ >+/* { dg-final { scan-tree-dump-times "return 1;" 6 "optimized" } } */ >+ >+unsigned >+f1 (unsigned x, unsigned y) >+{ >+ unsigned a = ~(x - y); >+ unsigned b = ~x + y; >+ return a == b; >+} >+ >+unsigned >+f2 (unsigned x) >+{ >+ unsigned a = ~(x + -124U); >+ unsigned b = ~x + 124U; >+ return a == b; >+} >+ >+unsigned >+f3 (unsigned x) >+{ >+ unsigned a = ~(x + 124U); >+ unsigned b = ~x + -124U; >+ return a == b; >+} >+ >+int >+f4 (int x, int y) >+{ >+ int a = ~(x - y); >+ int b = ~x + y; >+ return a == b; >+} >+ >+int >+f5 (int x) >+{ >+ int a = ~(x + -124); >+ int b = ~x + 124; >+ return a == b; >+} >+ >+int >+f6 (int x) >+{ >+ int a = ~(x + 124); >+ int b = ~x + -124; >+ return a == b; >+} >--- gcc/testsuite/gcc.dg/tree-ssa/pr96685-2.c.jj 2020-12-11 >16:42:03.975584838 +0100 >+++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-2.c 2020-12-11 >16:42:03.975584838 +0100 >@@ -0,0 +1,40 @@ >+/* PR tree-optimization/96685 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -fdump-tree-optimized" } */ >+/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */ >+ >+int >+f1 (unsigned x, unsigned y) >+{ >+ unsigned int r1 = (x - y); >+ r1 = ~r1; >+ unsigned int r2 = ~(x - y); >+ return r1 == r2; >+} >+ >+int >+f2 (unsigned x, unsigned y) >+{ >+ unsigned int r1 = (x - 23); >+ r1 = ~r1; >+ unsigned int r2 = ~(x - 23); >+ return r1 == r2; >+} >+ >+int >+f3 (int x, int y) >+{ >+ int r1 = (x - y); >+ r1 = ~r1; >+ int r2 = ~(x - y); >+ return r1 == r2; >+} >+ >+int >+f4 (int x, int y) >+{ >+ int r1 = (x - 23); >+ r1 = ~r1; >+ int r2 = ~(x - 23); >+ return r1 == r2; >+} >--- gcc/testsuite/gcc.dg/tree-ssa/pr96685-3.c.jj
Re: [PATCH] widening_mul: Recognize another form of ADD_OVERFLOW [PR96272]
On December 12, 2020 9:01:50 AM GMT+01:00, Jakub Jelinek wrote: >Hi! > >The following patch recognizes another form of hand written >__builtin_add_overflow (this time _p), in particular when >the code does unsigned >if (x > ~0U - y) >or >if (x <= ~0U - y) >it can be optimized (if the subtraction turned into ~y is single use) >into >if (__builtin_add_overflow_p (x, y, 0U)) >or >if (!__builtin_add_overflow_p (x, y, 0U)) >and generate better code, e.g. for the first function in the testcase: >- movl%esi, %eax > addl%edi, %esi >- notl%eax >- cmpl%edi, %eax >- movl$-1, %eax >- cmovnb %esi, %eax >+ jc .L3 >+ movl%esi, %eax >+ ret >+.L3: >+ orl $-1, %eax > ret >on x86_64. As for the jumps vs. conditional move case, that is some CE >issue with complex branch patterns we should fix up no matter what, but >in this case I'm actually not sure if branchy code isn't better, >overflow >is something that isn't that common. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Ok. Richard. >2020-12-12 Jakub Jelinek > > PR tree-optimization/96272 > * tree-ssa-math-opts.c (uaddsub_overflow_check_p): Add OTHER argument. > Handle BIT_NOT_EXPR. > (match_uaddsub_overflow): Optimize unsigned a > ~b into > __imag__ .ADD_OVERFLOW (a, b). > (math_opts_dom_walker::after_dom_children): Call >match_uaddsub_overflow > even for BIT_NOT_EXPR. > > * gcc.dg/tree-ssa/pr96272.c: New test. > >--- gcc/tree-ssa-math-opts.c.jj2020-11-22 19:16:25.302440812 +0100 >+++ gcc/tree-ssa-math-opts.c 2020-12-11 16:19:17.314846597 +0100 >@@ -3457,7 +3457,8 @@ convert_mult_to_fma (gimple *mul_stmt, t >and 0 otherwise. */ > > static int >-uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt, tree maxval) >+uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt, tree maxval, >+tree *other) > { > enum tree_code ccode = ERROR_MARK; > tree crhs1 = NULL_TREE, crhs2 = NULL_TREE; >@@ -3520,6 +3521,13 @@ uaddsub_overflow_check_p (gimple *stmt, > || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2) > && crhs2 == lhs)) > return ccode == GT_EXPR ? 1 : -1; >+ /* r = ~a; b > r or b <= r. */ >+ if (code == BIT_NOT_EXPR && crhs2 == lhs) >+ { >+if (other) >+ *other = crhs1; >+return ccode == GT_EXPR ? 1 : -1; >+ } > break; > case LT_EXPR: > case GE_EXPR: >@@ -3531,6 +3539,13 @@ uaddsub_overflow_check_p (gimple *stmt, > || (code == PLUS_EXPR && crhs1 == lhs > && (crhs2 == rhs1 || crhs2 == rhs2))) > return ccode == LT_EXPR ? 1 : -1; >+ /* r = ~a; r < b or r >= b. */ >+ if (code == BIT_NOT_EXPR && crhs1 == lhs) >+ { >+if (other) >+ *other = crhs2; >+return ccode == LT_EXPR ? 1 : -1; >+ } > break; > default: > break; >@@ -3560,7 +3575,15 @@ uaddsub_overflow_check_p (gimple *stmt, >_9 = REALPART_EXPR <_7>; >_8 = IMAGPART_EXPR <_8>; >if (_8) >- and replace (utype) x with _9. */ >+ and replace (utype) x with _9. >+ >+ Also recognize: >+ x = ~z; >+ if (y > x) >+ and replace it with >+ _7 = ADD_OVERFLOW (y, z); >+ _8 = IMAGPART_EXPR <_8>; >+ if (_8) */ > > static bool > match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt, >@@ -3576,34 +3599,49 @@ match_uaddsub_overflow (gimple_stmt_iter > gimple *add_stmt = NULL; > bool add_first = false; > >- gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR); >+ gcc_checking_assert (code == PLUS_EXPR >+ || code == MINUS_EXPR >+ || code == BIT_NOT_EXPR); > if (!INTEGRAL_TYPE_P (type) > || !TYPE_UNSIGNED (type) > || has_zero_uses (lhs) >- || (code == MINUS_EXPR >-&& optab_handler (usubv4_optab, >+ || (code != PLUS_EXPR >+&& optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab, > TYPE_MODE (type)) == CODE_FOR_nothing)) > return false; > >+ tree rhs1 = gimple_assign_rhs1 (stmt); >+ tree rhs2 = gimple_assign_rhs2 (stmt); > FOR_EACH_IMM_USE_FAST (use_p, iter, lhs) > { > use_stmt = USE_STMT (use_p); > if (is_gimple_debug (use_stmt)) > continue; > >- if (uaddsub_overflow_check_p (stmt, use_stmt, NULL_TREE)) >- ovf_use_seen = true; >+ tree other = NULL_TREE; >+ if (uaddsub_overflow_check_p (stmt, use_stmt, NULL_TREE, >&other)) >+ { >+if (code == BIT_NOT_EXPR) >+ { >+gcc_assert (other); >+if (TREE_CODE (other) != SSA_NAME) >+ return false; >+if (rhs2 == NULL) >+ rhs2 = other; >+else if (rhs2 != other) >+ return false; >+ } >+ovf_use_seen = true; >+ } > else > use_seen = true; > if (ovf_use_seen
Re: [RFC] [avr] Toolchain Integration for Testsuite Execution (avr cc0 to mode_cc0 conversion)
Hello! >> I'd ask the original author, but it seems he's busy with other work, so to >> avoid delays... > > Please try to ask him first? That is always nice, but you all also need > to figure out what to do with the bounty. Going through the messages in this thread, my suggestion would be to pick Senthil's conversion as it apparently has no regressions as reported by Dimitar [1]. Since the largest share of the bounty was donated by Atmel/Microchip, there might be a conflict of interest as Senthil works for them from what I have seen on his homepage. If claiming the bounty should be a problem in this case, I would suggest that Senthil donates the money for a good cause or maybe puts the money on a different Bountysource campaign to either benefit GCC (I'm sure there are enough other areas that could see some love) itself or another open source project. Either way, the money is awarded to the individual who did the heavy lifting and it's important that we keep it that way. Otherwise, there is a risk that future potential contributors will refrain from picking up the task from such a Bountysource campaign if there is a reduced chance for them to claim such a bounty. After all, the whole idea of Bountysource is to delegate tasks that the community is interested to being worked on to skilled developers who are willing to spend a lot of their free time and to give them a small financial reward in return. Normally, buying developer time for such extensive tasks is way more expensive, so the community should appreciate anyone willing to do such work for a comparably little amount of money. For what it's worth, there are certainly more tasks coming in the future, so I'd recommend everyone interested in claiming a bounty regularly checking Bountysource.com (Disclaimer: I'm not affiliated with them, I just chose them because the seem to be the most popular site) or similar campaign sites for such offers. Thanks, Adrian > [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-December/561489.html -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer - glaub...@debian.org `. `' Freie Universitaet Berlin - glaub...@physik.fu-berlin.de `-GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
[PATCH 0/2] VAX: Push operation fixes
Hi, While working on QMATH DImode add/sub fixes I have spotted an issue with the push operation. Here's a small patch series that addresses it. Lightly-verified with the `vax-netbsdelf' target and the C frontend test suite only as I need to have hardware available for a Linux kernel project (i.e. I need to be able to reboot the host at any time). These should be considered almost obviously correct though. Maciej
[PATCH 1/2] VAX: Check the correct operand for constant 0 push operation
Check the output operand for representing pushing a value onto the stack rather than the constant 0 input in determining whether to use the PUSHL or the CLRL instruction for a SImode move. The latter actually works by means of using the predecrement addressing mode with the SP register and the machine code produced even takes the same number of bytes, however at least with some VAX implementations it incurs a performance penalty. Besides, we don't want to check the wrong operand anyway and have code that works by chance only. Add a test case covering push operations; for operands different from constant zero there is actually a code size advantage for using PUSHL rather than the equivalent MOVL instruction. gcc/ * config/vax/vax.c (vax_output_int_move): Check the correct operand for constant 0 push operation. gcc/testsuite/ * gcc.target/vax/push.c: New test. --- gcc/config/vax/vax.c|2 +- gcc/testsuite/gcc.target/vax/push.c | 27 +++ 2 files changed, 28 insertions(+), 1 deletion(-) gcc-vax-push-zero.diff Index: gcc/gcc/config/vax/vax.c === --- gcc.orig/gcc/config/vax/vax.c +++ gcc/gcc/config/vax/vax.c @@ -1354,7 +1354,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_ if (operands[1] == const0_rtx) { - if (push_operand (operands[1], SImode)) + if (push_operand (operands[0], SImode)) return "pushl %1"; return "clrl %0"; } Index: gcc/gcc/testsuite/gcc.target/vax/push.c === --- /dev/null +++ gcc/gcc/testsuite/gcc.target/vax/push.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +void bar (void (*) (void), int, int); + +void +foo (void) +{ + bar (foo, 1, 0); +} + +/* Expect assembly like: + + pushl $0 + pushl $1 + pushab foo + calls $3,bar + +rather than: + + clrl -(%sp) + movl $1,-(%sp) + movab foo,-(%sp) + calls $3,bar + + */ + +/* { dg-final { scan-assembler "\[ \t\]+pushl\[ \t\]+\\\$0\n\[ \t\]+pushl\[ \t\]+\\\$1\n\[ \t\]+pushab\[ \t\]+foo\n" } } */
[PATCH 2/2] VAX: Unify push operation selection
Avoid the possibility of code discrepancies like one fixed with the previous change and improve the structure of code by selecting between push and non-push operations in a single place in `vax_output_int_move'. The PUSHAB/MOVAB address moves are never actually produced from this code as the SImode invocation of this function is guarded with the `nonsymbolic_operand' predicate, but let's not mess up with this code too much on this occasion and keep the piece in place. * config/vax/vax.c (vax_output_int_move): Unify push operation selection. --- gcc/config/vax/vax.c | 19 ++- 1 file changed, 6 insertions(+), 13 deletions(-) gcc-vax-int-move-push-p.diff Index: gcc/gcc/config/vax/vax.c === --- gcc.orig/gcc/config/vax/vax.c +++ gcc/gcc/config/vax/vax.c @@ -1235,6 +1235,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_ { rtx hi[3], lo[3]; const char *pattern_hi, *pattern_lo; + bool push_p; switch (mode) { @@ -1345,19 +1346,13 @@ vax_output_int_move (rtx insn ATTRIBUTE_ return "movq %1,%0"; case E_SImode: + push_p = push_operand (operands[0], SImode); + if (symbolic_operand (operands[1], SImode)) - { - if (push_operand (operands[0], SImode)) - return "pushab %a1"; - return "movab %a1,%0"; - } + return push_p ? "pushab %a1" : "movab %a1,%0"; if (operands[1] == const0_rtx) - { - if (push_operand (operands[0], SImode)) - return "pushl %1"; - return "clrl %0"; - } + return push_p ? "pushl %1" : "clrl %0"; if (CONST_INT_P (operands[1]) && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) @@ -1383,9 +1378,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_ if (i >= -0x8000 && i < 0) return "cvtwl %1,%0"; } - if (push_operand (operands[0], SImode)) - return "pushl %1"; - return "movl %1,%0"; + return push_p ? "pushl %1" : "movl %1,%0"; case E_HImode: if (CONST_INT_P (operands[1]))
Re: [PATCH] match.pd: Add ~(X - Y) -> ~X + Y simplification [PR96685]
On Sat, 12 Dec 2020, Jakub Jelinek via Gcc-patches wrote: This patch adds the ~(X - Y) -> ~X + Y simplification requested in the PR (plus also ~(X + C) -> ~X + (-C) for constants C that can be safely negated. Would it have been wrong to produce ~X - C without caring about negating (and then extending it to non-constants)? I wonder if this makes /* ~(~X - Y) -> X + Y and ~(~X + Y) -> X - Y. */ useless. -- Marc Glisse
Re: [PATCH] match.pd: Add ~(X - Y) -> ~X + Y simplification [PR96685]
On Sat, Dec 12, 2020 at 01:25:39PM +0100, Marc Glisse wrote: > On Sat, 12 Dec 2020, Jakub Jelinek via Gcc-patches wrote: > > > This patch adds the ~(X - Y) -> ~X + Y simplification requested > > in the PR (plus also ~(X + C) -> ~X + (-C) for constants C that can > > be safely negated. > > Would it have been wrong to produce ~X - C without caring about negating > (and then extending it to non-constants)? Extending it to non-constants is what I wanted to avoid. For ~(X + Y), because + is commutative, it wouldn't be a canonicalization as it would pick more-less randomly whether to do ~X + Y or X + ~Y. > I wonder if this makes > /* ~(~X - Y) -> X + Y and ~(~X + Y) -> X - Y. */ > useless. Maybe the former, but not the latter. Jakub
Re: [PATCH] match.pd: Add ~(X - Y) -> ~X + Y simplification [PR96685]
On Sat, 12 Dec 2020, Jakub Jelinek via Gcc-patches wrote: On Sat, Dec 12, 2020 at 01:25:39PM +0100, Marc Glisse wrote: On Sat, 12 Dec 2020, Jakub Jelinek via Gcc-patches wrote: This patch adds the ~(X - Y) -> ~X + Y simplification requested in the PR (plus also ~(X + C) -> ~X + (-C) for constants C that can be safely negated. Would it have been wrong to produce ~X - C without caring about negating (and then extending it to non-constants)? Extending it to non-constants is what I wanted to avoid. For ~(X + Y), because + is commutative, it wouldn't be a canonicalization as it would pick more-less randomly whether to do ~X + Y or X + ~Y. ~X - Y or ~Y - X I guess. Ok, I understand. But then in the constant case, why produce ~X + -C instead of ~X - C (which I think doesn't need to care about negating), or even ~C - X (one less operation)? Or do we already have a transformation from ~X - C to ~C - X? -- Marc Glisse
Re: [PATCH] match.pd: Add ~(X - Y) -> ~X + Y simplification [PR96685]
On Sat, Dec 12, 2020 at 02:00:49PM +0100, Marc Glisse wrote: > > Extending it to non-constants is what I wanted to avoid. > > For ~(X + Y), because + is commutative, it wouldn't be a canonicalization > > as it would pick more-less randomly whether to do ~X + Y or X + ~Y. > > ~X - Y or ~Y - X I guess. > > Ok, I understand. But then in the constant case, why produce ~X + -C instead > of ~X - C (which I think doesn't need to care about negating), Because we immediately simplify it again into ~X + (-C) then. Jakub
[Patch, fortran] PR
Fortran: Enable inquiry references in data statements [PR98022]. This patch speaks for itself. Regtests on FC31/x86_64 - OK for master? Paul 2020-12-12 Paul Thomas gcc/fortran PR fortran/98022 * data.c (gfc_assign_data_value): Handle inquiry references in the data statement object list. gcc/testsuite/ PR fortran/98022 * gfortran.dg/data_inquiry_ref.f90: New test. ! { dg-do run } ! ! Test the fix for PR98022. ! ! Contributed by Arseny Solokha ! module ur contains ! The reporter's test. function kn1() result(hm2) complex :: hm(1:2), hm2(1:2) data (hm(md)%re, md=1,2)/1.0, 2.0/ hm2 = hm end function kn1 ! Check for derived types with complex components. function kn2() result(hm2) type t complex :: c integer :: i end type type (t) :: hm(1:2) complex :: hm2(1:2) data (hm(md)%c%im, md=1,2)/1.0, 2.0/ data (hm(md)%i, md=1,2)/1, 2/ hm2 = hm%c end function kn2 end module ur use ur if (any (kn1() .ne. [(1.0,0.0),(2.0,0.0)])) stop 1 if (any (kn2() .ne. [(0.0,1.0),(0.0,2.0)])) stop 2 end diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c index 5147515659b..3e52a5717b5 100644 --- a/gcc/fortran/data.c +++ b/gcc/fortran/data.c @@ -20,14 +20,14 @@ along with GCC; see the file COPYING3. If not see /* Notes for DATA statement implementation: - + We first assign initial value to each symbol by gfc_assign_data_value during resolving DATA statement. Refer to check_data_variable and traverse_data_list in resolve.c. - + The complexity exists in the handling of array section, implied do and array of struct appeared in DATA statement. - + We call gfc_conv_structure, gfc_con_array_array_initializer, etc., to convert the initial value. Refer to trans-expr.c and trans-array.c. */ @@ -464,6 +464,54 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index, } break; + case REF_INQUIRY: + + /* This breaks with the other reference types in that the output + constructor has to be of type COMPLEX, whereas the lvalue is + of type REAL. The rvalue is copied to the real or imaginary + part as appropriate. */ + gcc_assert (ref->next == NULL && last_ts->type == BT_COMPLEX); + expr = gfc_copy_expr (rvalue); + if (!gfc_compare_types (&lvalue->ts, &expr->ts)) + gfc_convert_type (expr, &lvalue->ts, 0); + + if (last_con->expr) + gfc_free_expr (last_con->expr); + + last_con->expr = gfc_get_constant_expr (BT_COMPLEX, + last_ts->kind, + &lvalue->where); + + /* Rejection of LEN and KIND inquiry references is handled + elsewhere. The error here is added as backup. The assertion + of F2008 for RE and IM is also done elsewhere. */ + switch (ref->u.i) + { + case INQUIRY_LEN: + case INQUIRY_KIND: + gfc_error ("LEN or KIND inquiry ref in DATA statement at %L", + &lvalue->where); + goto abort; + case INQUIRY_RE: + mpfr_set (mpc_realref (last_con->expr->value.complex), + expr->value.real, + GFC_RND_MODE); + mpfr_set_ui (mpc_imagref (last_con->expr->value.complex), + 0.0, GFC_RND_MODE); + break; + case INQUIRY_IM: + mpfr_set (mpc_imagref (last_con->expr->value.complex), + expr->value.real, + GFC_RND_MODE); + mpfr_set_ui (mpc_realref (last_con->expr->value.complex), + 0.0, GFC_RND_MODE); + break; + } + + gfc_free_expr (expr); + mpz_clear (offset); + return true; + default: gcc_unreachable (); } @@ -513,7 +561,7 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index, && gfc_has_default_initializer (lvalue->ts.u.derived)) { gfc_error ("Nonpointer object %qs with default initialization " - "shall not appear in a DATA statement at %L", + "shall not appear in a DATA statement at %L", symbol->name, &lvalue->where); return false; } @@ -540,13 +588,13 @@ abort: /* Modify the index of array section and re-calculate the array offset. */ -void +void gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar, mpz_t *offset_ret) { int i; mpz_t delta; - mpz_t tmp; + mpz_t tmp; bool forwards; int cmp; gfc_expr *start, *end, *stride; @@ -567,21 +615,21 @@ gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar, forwards = true; else forwards = false; - gfc_free_expr(stride); + gfc_free_expr(stride); } else { mpz_add_ui (section_index[i], section_index[i], 1); forwards = true; } - + if (ar->end[i]) { end = gfc_copy_expr(ar->end[i]); if(!gfc_simplify_expr(end, 1)) gfc_internal_error("Simplification error"); cmp = mpz_cmp (section_index[i], end->value.integer); - gfc_free_expr(end); + gfc_free_expr(end); } else cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer); @@ -595,7 +643,7 @@ gfc_advance_section (mpz_t *secti
Re: [Patch, fortran] PR 98022
Hi Paul, Fortran: Enable inquiry references in data statements [PR98022]. This patch speaks for itself. Regtests on FC31/x86_64 - OK for master? Looks good. Thanks a lot for the patch! Best regards Thomas
Re: [RFC] [avr] Toolchain Integration for Testsuite Execution (avr cc0 to mode_cc0 conversion)
Hi! On Sat, Dec 12, 2020 at 12:17:19PM +0100, John Paul Adrian Glaubitz wrote: > >> I'd ask the original author, but it seems he's busy with other work, so to > >> avoid delays... > > > > Please try to ask him first? That is always nice, but you all also need > > to figure out what to do with the bounty. > > Going through the messages in this thread, my suggestion would be to pick > Senthil's conversion as it apparently has no regressions as reported by > Dimitar [1]. It is up to the avr maintainer what patch is accepted, of course :-) > Since the largest share of the bounty was donated by Atmel/Microchip, there > might be a conflict of interest as Senthil works for them from what I have > seen on his homepage. This is something that Senthil can clarify, there is no need to second-guess it -- there should be no conflict at all if he did it on his own time, for example. > If claiming the bounty should be a problem in this case, I would suggest > that Senthil donates the money for a good cause or maybe puts the money > on a different Bountysource campaign to either benefit GCC (I'm sure there > are enough other areas that could see some love) itself or another open source > project. > > Either way, the money is awarded to the individual who did the heavy lifting > and it's important that we keep it that way. Otherwise, there is a risk > that future potential contributors will refrain from picking up the task > from such a Bountysource campaign if there is a reduced chance for them > to claim such a bounty. The individual(s) who wrote the code. Yes. > After all, the whole idea of Bountysource is to delegate tasks that the > community is interested to being worked on to skilled developers who are > willing to spend a lot of their free time and to give them a small financial > reward in return. Normally, buying developer time for such extensive tasks > is way more expensive, so the community should appreciate anyone willing > to do such work for a comparably little amount of money. +1. Well, +100 or such :-) Segher
Re: [committed] openmp, openacc: Fix up handling of data regions [PR98183]
On Sat, Dec 12, 2020 at 08:55:01AM +0100, Jakub Jelinek via Gcc-patches wrote: > Actually, seems we diagnose goto out of it, so perhaps for trunk > the best thing forward is to add the noexcept block around target data > body, but I think we still don't really need the omp return, omp-expand > doesn't really care, all interesting happens during gimplification and > omplower, and adding the noexcept block is probably inappropriate for > release branches. That would be 2020-12-12 Jakub Jelinek * omp-low.c (lower_omp_target): Wrap even data region body into maybe_catch_exception. --- gcc/omp-low.c.jj2020-12-12 08:35:51.182131932 +0100 +++ gcc/omp-low.c 2020-12-12 17:31:31.392537247 +0100 @@ -12978,11 +12978,10 @@ lower_omp_target (gimple_stmt_iterator * gimple_seq_add_seq (&new_body, tgt_body); gimple_seq_add_seq (&new_body, join_seq); + if (offloaded || data_region) + new_body = maybe_catch_exception (new_body); if (offloaded) - { - new_body = maybe_catch_exception (new_body); - gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false)); - } + gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false)); gimple_omp_set_body (stmt, new_body); } but thinking about it more, nothing in the OpenMP standard requires that terminate is called, it is undefined behavior instead, and handling it the way users expect is perhaps a reasonable choice when we easily can. Testcase would be: extern "C" void abort (); int main () { int x = 1; try { #pragma omp target data map (to: x) { throw 1; } } catch (int y) { if (y == 1) return 0; } abort (); } Tobias/Thomas, your thoughts on this? Jakub
Re: [RFC] [avr] Toolchain Integration for Testsuite Execution (avr cc0 to mode_cc0 conversion)
On Sat, 12 Dec 2020 at 01:15, Segher Boessenkool wrote: > On Fri, Dec 11, 2020 at 11:20:01PM +0200, abebeos wrote: > > Στις Παρ, 11 Δεκ 2020 στις 11:00 μ.μ., ο/η Segher Boessenkool < > > seg...@kernel.crashing.org> έγραψε: > > > > Ok, to speed things up, is it ok if I simply pick the patch that I've > > > > attached to the issue: > > > > > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92729#c21 > > > > > > I see no patch attached there? Just a link to github. > > > > sorry, it's on top of the issue. > > > > direct link: > > https://gcc.gnu.org/bugzilla/attachment.cgi?bugid=92729&action=viewall > > Ah, you linked to comment 21, so I only looked in that comment :-) > > > > I'd ask the original author, but it seems he's busy with other work, > so to > > > > avoid delays... > > > > > > Please try to ask him first? That is always nice, > > > > contacted days ago both authors via email (naturally closing with "feel > > free to ignore if you're busy"), pip replied, saa not. Though both are > on > > the cc of the issue, too. > > Let's hope he replies soon after you post it. Here it is: https://gcc.gnu.org/pipermail/gcc-patches/2020-December/561718.html My understanding is that patches are neutral (no signature, no names), so if saaadhu signs it off and commits it, all will be fine (legal and ethics). > We aren't in a super > hurry of course, most of the work is done after all and GCC 12 > development won't start until months from now. > The only ones in hurry a those who want to get "closure" (that's me: it ends, when it's merged in main/upstream), and of course those who want to claim the bounty (poor me, again, and possibly some others). (As a sidenote: did you know that Bountysource takes a 10% cut, and pays out manually "once a week depending on availability of volunteers"? Super-strange processes, getting closure a bit hellish. See yourself: *"Note:* The timing here can vary substantially based on volunteer availability. If your request is still pending after a week or two please send us a support request and poke it occasionally until somebody can get to it" source: https://github.com/bountysource/core/wiki/Frequently-Asked-Questions#i-submitted-a-cash-out-request-when-will-i-be-paid This is worth filing an issue "Consider replacing bountysource with a faster&cheaper alternative") > (Please cc: all interested parties on the patch -- they aren't on this > mail thread either?) > Not sure I understand: you mean that the traffic on gcc-patches is so huge, than one needs to ping interested parties via cc? Segher >
[patch, fortran] Optionally improve debugging of auxiliary variables
Hello world, I have struggled with debugging the GENERIC generated by the Fortran front end because it is only possible to look at the code via -fdump-tree-original, but it is not possible to inspect the values; additionally, the D.3456 form makes it hard to read which variable is which. This patch adds a flag which gives all variables generated by Fortran a name and makes them visible to debuggers. As an example, compiler-generated variables now look like this (for a "Hello, world" program): { struct __st_parameter_dt dt_parm:0; dt_parm:0.common.filename = &"hello.f90"[1]{lb: 1 sz: 1}; dt_parm:0.common.line = 2; dt_parm:0.common.flags = 128; dt_parm:0.common.unit = 6; _gfortran_st_write (&dt_parm:0); _gfortran_transfer_character_write (&dt_parm:0, &"Hello, world"[1]{lb: 1 sz: 1}, 12); _gfortran_st_write_done (&dt_parm:0); } Note the colon in the variable name, which I chose because it is not in the user's namespace, and gdb does not choke on it. In order to inspect the variables, you usually have to step a bit through the generated assembly code, but you can then print the values, manipulate them etc (and sometimes also hit an internal error in gdb). Example of a debugging session: (gdb) b _gfortran_st_write Breakpoint 1 at 0x4005f0 (gdb) r Starting program: /tmp/a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, _gfortran_st_write (dtp=0x7fffd9f0) at ../../../coarray_native/libgfortran/io/transfer.c:4398 4398{ (gdb) fin Run till exit from #0 _gfortran_st_write (dtp=0x7fffd9f0) at ../../../coarray_native/libgfortran/io/transfer.c:4398 0x00400719 in MAIN__ () at hello.f90:2 2 print *,"Hello, world" (gdb) info local dt_parm:0 = ( common = ( flags = 128, unit = 6, filename = 0x400810, line = 2, iomsg_len = 0, iomsg = 0x0, iostat = 0x0 ), rec = 0, size = 0x0, iolength = 0x0, internal_unit_desc = 0x0, format = 0x0, format_len = 0, advance_len = 0, advance = 0x0, internal_unit = 0x0, internal_unit_len = 0, namelist_name_len = 0, namelist_name = 0x0, id = 0x2, pos = -9223372036854775802, asynchronous = 0x0, asynchronous_len = 4569374499253603072, blank_len = 0, blank = 0x3f69ade5c1bd4b00, decimal = 0x779490f0 <_gfortrani_backtrace_handler>, decimal_len = 140737335317407, delim_len = 140737347096816, delim = 0x100, pad = 0x0, pad_len = 0, round_len = 0, round = 0x0, sign = 0x0, sign_len = 0, u = '`&\270\367\377\177\000\000\060H`\000\000\000\000\000\000\000\000\000\001', '\000' , '\002', '\000' , '\377\377\377\377\377\377\377\377', '\000' ... ) (gdb) p dt_parm:0%common $1 = ( flags = 128, unit = 6, filename = 0x400810, line = 2, iomsg_len = 0, iomsg = 0x0, iostat = 0x0 ) (gdb) p dt_parm:0%common%filename $2 = (PTR TO -> ( character(kind=1) )) 0x400810 There is no user impact (only developers will use this), so it is not surprising that there is no regression. So, OK for trunk? Best regards Thomas diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 8bdc8a6b038..58e4e50b315 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -1227,6 +1227,17 @@ compiler itself. The output generated by this option might change between releases. This option may also generate internal compiler errors for features which have only recently been added. +@item -fdebug-aux-vars +@opindex @code{debug-aux-vars} +Make internal variables generated by the gfortran front end visible to a +debugger. This option also renames these internal variables shown by +@code{-fdump-tree-original} to a form @code{string:number} and enables +compiler warnings on them. + +This option is only really useful when debugging the gfortran compiler +itself together with @code{-g} or @code{-ggdb3} and +@code{-fdump-tree-original}. + @item -ffpe-trap=@var{list} @opindex @code{ffpe-trap=}@var{list} Specify a list of floating point exception traps to enable. On most diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 96ed208cb85..57b0264458e 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -452,6 +452,10 @@ fd-lines-as-comments Fortran RejectNegative Treat lines with 'D' in column one as comments. +fdebug-aux-vars +Fortran Var(flag_debug_aux_vars) +Issue debug information for compiler-generated auxiliary variables. + fdec Fortran Var(flag_dec) Enable all DEC language extensions. diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 025abe38985..1d5f6c28c7a 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -73,6 +73,40 @@ gfc_advance_chain (tree t, int n) return t; } +static int num_var; + +#define MAX_PREFIX_LEN 20 + +static tree +create_var_debug_raw (tree type, const char *prefix) +{ + /* Space for prefix + @ + 9-digit-number + \0. */ + char name_buf[MAX_PREFIX_LEN + 1 + 9 + 1]; + tree t; + + if (prefix == NULL) +prefix = "gfc"; + else +gcc_assert (strlen(prefix) <= MA
rs6000: Update the processor defaults for FreeBSD
Piotr is the one spending most times on ensuring FreeBSD ports work fine on POWER, so personally I'm happy to follow his recommendation on such matters. Okay for trunk and backports (GCC 10 at least)? Gerald gcc/ChangeLog: 2020-12-13 Piotr Kubaj Gerald Pfeifer * config/rs6000/freebsd64.h (PROCESSOR_DEFAULT): Update to PROCESSOR_PPC7450. (PROCESSOR_DEFAULT64): Update to PROCESSOR_POWER8. --- gcc/config/rs6000/freebsd64.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gcc/config/rs6000/freebsd64.h b/gcc/config/rs6000/freebsd64.h index 6984ca5a107..4b2da571c4a 100644 --- a/gcc/config/rs6000/freebsd64.h +++ b/gcc/config/rs6000/freebsd64.h @@ -51,11 +51,10 @@ extern int dot_symbols; #define SET_CMODEL(opt) do {} while (0) #endif -/* Until now the 970 is the only Processor where FreeBSD 64-bit runs on. */ #undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWER4 +#define PROCESSOR_DEFAULT PROCESSOR_PPC7450 #undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER8 /* We don't need to generate entries in .fixup, except when -mrelocatable or -mrelocatable-lib is given. */ -- 2.29.2