[r14-2386 Regression] FAIL: gcc.target/i386/pr91681-1.c scan-assembler-not xor on Linux/x86_64
On Linux/x86_64, bdf2737cda53a83332db1a1a021653447b05a7e7 is the first bad commit commit bdf2737cda53a83332db1a1a021653447b05a7e7 Author: Roger Sayle Date: Fri Jul 7 20:39:58 2023 +0100 i386: Improve __int128 argument passing (in ix86_expand_move). caused FAIL: gcc.target/i386/pr82580.c scan-assembler-not \\mmovzb FAIL: gcc.target/i386/pr91681-1.c scan-assembler-not xor with GCC configured with ../../gcc/configure --prefix=/export/users/haochenj/src/gcc-bisect/master/master/r14-2386/usr --enable-clocale=gnu --with-system-zlib --with-demangler-in-ld --with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl --enable-libmpx x86_64-linux --disable-bootstrap To reproduce: $ cd {build_dir}/gcc && make check RUNTESTFLAGS="i386.exp=gcc.target/i386/pr82580.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="i386.exp=gcc.target/i386/pr82580.c --target_board='unix{-m64\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="i386.exp=gcc.target/i386/pr91681-1.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="i386.exp=gcc.target/i386/pr91681-1.c --target_board='unix{-m64\ -march=cascadelake}'" (Please do not reply to this email, for question about this report, contact me at haochen dot jiang at intel.com.) (If you met problems with cascadelake related, disabling AVX512F in command line might save that.) (However, please make sure that there is no potential problems with AVX512.)
Add missing dump_file check
Hi, I forgot to check dump_file being non-NULL before writting to it. It is somewhat odd that this does not trigger more often - I will take deeper look tomorrow, but I am checking this in as obvious to avoid ICE. Honza gcc/ChangeLog: PR tree-optimization/110600 * cfgloopmanip.cc (scale_loop_profile): Add mising profile_dump check. gcc/testsuite/ChangeLog: PR tree-optimization/110600 * gcc.c-torture/compile/pr110600.c: New test. diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 52732420787..5c0065b2f5a 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -582,9 +582,10 @@ scale_loop_profile (class loop *loop, profile_probability p, if (exit_edge && exit_edge->src->loop_father != loop) { - fprintf (dump_file, - ";; Loop exit is in inner loop;" - " will leave exit probabilities inconsistent\n"); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, +";; Loop exit is in inner loop;" +" will leave exit probabilities inconsistent\n"); } else if (exit_edge) { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr110600.c b/gcc/testsuite/gcc.c-torture/compile/pr110600.c new file mode 100644 index 000..4b126f74e43 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr110600.c @@ -0,0 +1,6 @@ +int a(int b, int c) { return (b ^ c) < 0 ? b : b - c; } +int main() { + for (int e = 0; e != -1; e = a(e, 1)) +; + return 0; +}
[r14-2383 Regression] FAIL: gcc.dg/unroll-7.c scan-rtl-dump-not loop2_unroll "Invalid sum" on Linux/x86_64
On Linux/x86_64, 768f00e3e84123e8d0f1bf28a3b2e0b7995402f1 is the first bad commit commit 768f00e3e84123e8d0f1bf28a3b2e0b7995402f1 Author: Jan Hubicka Date: Fri Jul 7 19:16:59 2023 +0200 Fix some profile consistency testcases caused FAIL: gcc.dg/pr43864-2.c scan-tree-dump-times pre "if " 0 FAIL: gcc.dg/pr43864-2.c scan-tree-dump-times pre "(?n)_.*\\+.*_" 1 FAIL: gcc.dg/pr43864-3.c scan-tree-dump-times pre "if " 0 FAIL: gcc.dg/pr43864-3.c scan-tree-dump-times pre "(?n)_.*\\+.*_" 1 FAIL: gcc.dg/pr43864-4.c scan-tree-dump-times pre "if " 0 FAIL: gcc.dg/pr43864.c scan-tree-dump-times pre "myfree \\(" 1 FAIL: gcc.dg/unroll-7.c scan-rtl-dump-not loop2_unroll "Invalid sum" with GCC configured with ../../gcc/configure --prefix=/export/users/haochenj/src/gcc-bisect/master/master/r14-2383/usr --enable-clocale=gnu --with-system-zlib --with-demangler-in-ld --with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl --enable-libmpx x86_64-linux --disable-bootstrap To reproduce: $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-2.c --target_board='unix{-m32}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-2.c --target_board='unix{-m32\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-2.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-2.c --target_board='unix{-m64\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-3.c --target_board='unix{-m32}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-3.c --target_board='unix{-m32\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-3.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-3.c --target_board='unix{-m64\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-4.c --target_board='unix{-m32}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-4.c --target_board='unix{-m32\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-4.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864-4.c --target_board='unix{-m64\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864.c --target_board='unix{-m32}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864.c --target_board='unix{-m32\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr43864.c --target_board='unix{-m64\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/unroll-7.c --target_board='unix{-m32}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/unroll-7.c --target_board='unix{-m32\ -march=cascadelake}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/unroll-7.c --target_board='unix{-m64}'" $ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/unroll-7.c --target_board='unix{-m64\ -march=cascadelake}'" (Please do not reply to this email, for question about this report, contact me at haochen dot jiang at intel.com.) (If you met problems with cascadelake related, disabling AVX512F in command line might save that.) (However, please make sure that there is no potential problems with AVX512.)
Fix profile update in tree-ssa/update-cunroll.c
Fix tree-ssa/update-cunroll.c In this testcase the profile is misupdated before loop has two exits. The first exit is one eliminated by complete unrolling while second exit remains. We remove first exit but forget about fact that the source BB of other exit will then have higher frequency making other exit more likely. This patch fixes that in duplicate_loop_body_to_header_edge. While looking into resulting profiles I also noticed that in some cases scale_loop_profile may drop probabilities to 0 incorrectly either when trying to update exit from nested loop (which has similar problem) or when the profile was inconsistent as described in coment bellow. With the patch I now get on tramp3d with -O3: Profile consistency report: Pass dump id and name|static mismat|dynamic mismatch |in count |in count 127t ch | 12 +10|0 131t dom | 20+8|0 134t reassoc | 22+2|0 136t forwprop| 26+4| 185250 +185250 159t cddce | 38 +12| 213412 +28162 161t ldist | 39+1| 213412 172t ifcvt | 41+2| 369692 +156280 173t vect|108 +67| 9508861 +9139169 176t cunroll |102-6| 11603578 +2094717 183t loopdone|101-1| 11547143 -56435 197t dom |100-1| 12641109 +1093966 199t threadfull |102+2| 12849084 +207975 200t vrp |104+2| 13047253 +198169 204t dce |102-2| 12973989 -73264 206t sink| 98-4| 12959537 -14452 211t cddce |102+4| 12973989 +14452 255t optimized | 98-4| 12959537 -14452 258r into_cfglayout | 97-1| 12960039 259r jump| 98+1| 12960039 262r cse1| 97-1| 12960039 275r loop2_unroll| 99+2| 16090384 +3130345 312r pro_and_epilogue|119 +20| 16191103 +100720 323r bbro|118-1| 15877546 -313557 So 118 instead of 160 mismatches. Bootstrapped/regtested x86_64-linux, comitted. gcc/ChangeLog: PR middle-end/110590 * cfgloopmanip.cc (scale_loop_profile): Avoid scaling exits within inner loops and be more careful about inconsistent profiles. (duplicate_loop_body_to_header_edge): Fix profile update when eliminated exit is followed by other exit. gcc/testsuite/ChangeLog: PR middle-end/110590 * gcc.dg/tree-prof/update-cunroll-2.c: Remove xfail. * gcc.dg/tree-ssa/update-cunroll.c: Likewise. diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index f56a9b87d1c..52732420787 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -580,13 +580,47 @@ scale_loop_profile (class loop *loop, profile_probability p, unadjusted_exit_count = exit_edge->count (); scale_loop_frequencies (loop, scale_prob); - if (exit_edge) + if (exit_edge && exit_edge->src->loop_father != loop) +{ + fprintf (dump_file, + ";; Loop exit is in inner loop;" + " will leave exit probabilities inconsistent\n"); +} + else if (exit_edge) { profile_count old_exit_count = exit_edge->count (); profile_probability new_probability; if (iteration_bound > 0) - new_probability - = unadjusted_exit_count.probability_in (exit_edge->src->count); + { + /* It may happen that the source basic block of the exit edge is +inside in-loop condition: + + +-> header + || + | B1 + | / \ + | | B2--exit_edge--> + | \ / + | B3 + +__/ + + If B2 count is smaller than desired exit edge count + the profile was inconsistent with the newly discovered upper bound. + Probablity of edge B1->B2 is too low. We do not attempt to fix + that (as it is hard in general) but we want to avoid dropping + count of edge B2->B3 to zero may confuse later optimizations. */ + if (unadjusted_exit_count.apply_scale (7, 8) > exit_edge->src->count) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, +";; Source basic block of loop exit count is too small;" +
Re: [Patch, fortran] Fix default type bugs in gfortran [PR99139, PR99368]
On Sat, Jul 08, 2023 at 03:23:31PM +0100, Paul Richard Thomas wrote: > The attached patch incorporates two of Steve's "Orphaned Patches" - > https://gcc.gnu.org/pipermail/fortran/2023-June/059423.html Thanks Paul for picking up the pieces I left behind. A few nits below. > They have in common that they both involve faults in use of default > type and that I was the ultimate cause of the bugs. > > The patch regtests with the attached testcases. > > I will commit in the next 24 hours unless there are any objections. > > Paul > > Fortran: Fix default type bugs in gfortran [PR99139, PR99368] > > 2023-07-08 Steve Kargl ka...@gcc.gnu.org. > gcc/fortran > PR fortran/99139 > PR fortran/99368 > * match.cc (gfc_match_namelist): Check for host associated or > defined types before applying default type. > (gfc_match_select_rank): Apply default type to selector of > unlnown type if possible. s/unlnown/unknown > * resolve.cc (resolve_fl_variable): Do not apply local default > initialization to assumed rank entities. > > gcc/testsuite/ > PR fortran/999139 > * gfortran.dg/pr99139.f90 : New test > > PR fortran/99368 > * gfortran.dg/pr99368.f90 : New test > > Fortran: Fix default type bugs in gfortran [PR99139, PR99368] > > 2023-07-08 Steve Kargl ka...@gcc.gnu.org > > gcc/fortran > PR fortran/99139 > PR fortran/99368 > * match.cc (gfc_match_namelist): Check for host associated or > defined types before applying default type. > (gfc_match_select_rank): Apply default type to selector of > unlnown type if possible. s/unlnown/unknown Other than the nits the patch looks fine. -- Steve
Re: [Patch, fortran] Fix default type bugs in gfortran [PR99139, PR99368]
Hi Paul, thanks for taking this. I have just a minor comment regards coding style: + if (tmp + && tmp->attr.generic + && (tmp = gfc_find_dt_in_generic (tmp))) + { + if (tmp->attr.flavor == FL_DERIVED) My reading of the guidelines says that I should rather write if (tmp && tmp->attr.generic) { tmp = gfc_find_dt_in_generic (tmp); if (tmp && tmp->attr.flavor == FL_DERIVED) Both variants are equally readable, though. I haven't though long enough about possible minor memleaks, i.e. if a freeing of gfc_symbol tmp is advised. Running f951 under valgrind might give you a hint. Thanks, Harald Am 08.07.23 um 16:23 schrieb Paul Richard Thomas via Gcc-patches: The attached patch incorporates two of Steve's "Orphaned Patches" - https://gcc.gnu.org/pipermail/fortran/2023-June/059423.html They have in common that they both involve faults in use of default type and that I was the ultimate cause of the bugs. The patch regtests with the attached testcases. I will commit in the next 24 hours unless there are any objections. Paul Fortran: Fix default type bugs in gfortran [PR99139, PR99368] 2023-07-08 Steve Kargl gcc/fortran PR fortran/99139 PR fortran/99368 * match.cc (gfc_match_namelist): Check for host associated or defined types before applying default type. (gfc_match_select_rank): Apply default type to selector of unlnown type if possible. * resolve.cc (resolve_fl_variable): Do not apply local default initialization to assumed rank entities. gcc/testsuite/ PR fortran/999139 * gfortran.dg/pr99139.f90 : New test PR fortran/99368 * gfortran.dg/pr99368.f90 : New test Fortran: Fix default type bugs in gfortran [PR99139, PR99368] 2023-07-08 Steve Kargl gcc/fortran PR fortran/99139 PR fortran/99368 * match.cc (gfc_match_namelist): Check for host associated or defined types before applying default type. (gfc_match_select_rank): Apply default type to selector of unlnown type if possible. * resolve.cc (resolve_fl_variable): Do not apply local default initialization to assumed rank entities. gcc/testsuite/ PR fortran/999139 * gfortran.dg/pr99139.f90 : New test PR fortran/99368 * gfortran.dg/pr99368.f90 : New test
[Patch, fortran] Fix default type bugs in gfortran [PR99139, PR99368]
The attached patch incorporates two of Steve's "Orphaned Patches" - https://gcc.gnu.org/pipermail/fortran/2023-June/059423.html They have in common that they both involve faults in use of default type and that I was the ultimate cause of the bugs. The patch regtests with the attached testcases. I will commit in the next 24 hours unless there are any objections. Paul Fortran: Fix default type bugs in gfortran [PR99139, PR99368] 2023-07-08 Steve Kargl gcc/fortran PR fortran/99139 PR fortran/99368 * match.cc (gfc_match_namelist): Check for host associated or defined types before applying default type. (gfc_match_select_rank): Apply default type to selector of unlnown type if possible. * resolve.cc (resolve_fl_variable): Do not apply local default initialization to assumed rank entities. gcc/testsuite/ PR fortran/999139 * gfortran.dg/pr99139.f90 : New test PR fortran/99368 * gfortran.dg/pr99368.f90 : New test Fortran: Fix default type bugs in gfortran [PR99139, PR99368] 2023-07-08 Steve Kargl gcc/fortran PR fortran/99139 PR fortran/99368 * match.cc (gfc_match_namelist): Check for host associated or defined types before applying default type. (gfc_match_select_rank): Apply default type to selector of unlnown type if possible. * resolve.cc (resolve_fl_variable): Do not apply local default initialization to assumed rank entities. gcc/testsuite/ PR fortran/999139 * gfortran.dg/pr99139.f90 : New test PR fortran/99368 * gfortran.dg/pr99368.f90 : New test ! { dg-do compile } ! { dg-options "-finit-local-zero" } ! ! Contributed by Gerhard Steinmetz ! ! Original implicitly typed 'x' gave a bad symbol ICE subroutine s1(x) target :: x(..) select rank (y => x) rank (1) rank (2) end select end ! Comment #2: Failed with above option subroutine s2(x, z) real, target :: x(..) real :: z(10) select rank (y => x) ! Error was:Assumed-rank variable y at (1) may only be ! used as actual argument rank (1) rank (2) end select end ! { dg-do compile } ! ! Contributed by Gerhard Steinmetz ! program p type y ! { dg-error "Derived type" } end type contains subroutine s1 namelist /x/ y ! { dg-error "conflicts with namelist object" } character(3) y end subroutine s2 namelist /z/ y ! { dg-error "conflicts with namelist object" } character(3) y end enddiff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc index ca64e59029e..a778bae0b9f 100644 --- a/gcc/fortran/match.cc +++ b/gcc/fortran/match.cc @@ -5622,10 +5622,32 @@ gfc_match_namelist (void) gfc_error_check (); } else - /* If the type is not set already, we set it here to the - implicit default type. It is not allowed to set it - later to any other type. */ - gfc_set_default_type (sym, 0, gfc_current_ns); + { + /* Before the symbol is given an implicit type, check to + see if the symbol is already available in the namespace, + possibly through host association. Importantly, the + symbol may be a user defined type. */ + + gfc_symbol *tmp; + + gfc_find_symbol (sym->name, NULL, 1, ); + if (tmp + && tmp->attr.generic + && (tmp = gfc_find_dt_in_generic (tmp))) + { + if (tmp->attr.flavor == FL_DERIVED) + { + gfc_error ("Derived type %qs at %L conflicts with " + "namelist object %qs at %C", + tmp->name, >declared_at, sym->name); + goto error; + } + } + + /* Set type of the symbol to its implicit default type. It is + not allowed to set it later to any other type. */ + gfc_set_default_type (sym, 0, gfc_current_ns); + } } if (sym->attr.in_namelist == 0 && !gfc_add_in_namelist (>attr, sym->name, NULL)) @@ -6805,8 +6827,20 @@ gfc_match_select_rank (void) gfc_current_ns = gfc_build_block_ns (ns); m = gfc_match (" %n => %e", name, ); + if (m == MATCH_YES) { + /* If expr2 corresponds to an implicitly typed variable, then the + actual type of the variable may not have been set. Set it here. */ + if (!gfc_current_ns->seen_implicit_none + && expr2->expr_type == EXPR_VARIABLE + && expr2->ts.type == BT_UNKNOWN + && expr2->symtree && expr2->symtree->n.sym) + { + gfc_set_default_type (expr2->symtree->n.sym, 0, gfc_current_ns); + expr2->ts.type = expr2->symtree->n.sym->ts.type; + } + expr1 = gfc_get_expr (); expr1->expr_type = EXPR_VARIABLE; expr1->where = expr2->where; diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 8e018b6e7e8..f7cfdfc133f 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -13510,7 +13510,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag) } } - if (sym->value == NULL && sym->attr.referenced) + if (sym->value == NULL && sym->attr.referenced + && !(sym->as && sym->as->type == AS_ASSUMED_RANK)) apply_default_init_local (sym); /* Try to apply a default initialization. */ /* Determine if the
Re: [PATCH] Fortran: fixes for procedures with ALLOCATABLE,INTENT(OUT) arguments [PR92178]
Hi Mikael, Am 08.07.23 um 14:07 schrieb Mikael Morin: here is what I'm finally coming to. This patch fixes my example, but is otherwise untested. The patch has grown enough that I'm tempted to fix my example separately, in its own commit. alright. I've interpreted this as a green light for v2 of my patch and pushed it as r14-2395-gb1079fc88f082d https://gcc.gnu.org/g:b1079fc88f082d3c5b583c8822c08c5647810259 so that you can build upon it. Mikael Thanks, Harald
[committed] cprop: Change return type of predicate functions from int to bool
Also change some internal variables from int to bool. gcc/ChangeLog: * cprop.cc (reg_available_p): Change return type from int to bool. (reg_not_set_p): Ditto. (try_replace_reg): Ditto. Change "success" variable to bool. (cprop_jump): Change return type from int to void and adjust function body accordingly. (constprop_register): Ditto. (cprop_insn): Ditto. Change "changed" variable to bool. (local_cprop_pass): Change return type from int to void and adjust function body accordingly. (bypass_block): Ditto. Change "change", "may_be_loop_header" and "removed_p" variables to bool. (bypass_conditional_jumps): Change return type from int to void and adjust function body accordingly. Change "changed" variable to bool. (one_cprop_pass): Ditto. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Uros. diff --git a/gcc/cprop.cc b/gcc/cprop.cc index 6ec0bda4a24..b7400c9a421 100644 --- a/gcc/cprop.cc +++ b/gcc/cprop.cc @@ -142,10 +142,10 @@ cprop_alloc (unsigned long size) return obstack_alloc (_obstack, size); } -/* Return nonzero if register X is unchanged from INSN to the end +/* Return true if register X is unchanged from INSN to the end of INSN's basic block. */ -static int +static bool reg_available_p (const_rtx x, const rtx_insn *insn ATTRIBUTE_UNUSED) { return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x)); @@ -517,10 +517,10 @@ reset_opr_set_tables (void) CLEAR_REG_SET (reg_set_bitmap); } -/* Return nonzero if the register X has not been set yet [since the +/* Return true if the register X has not been set yet [since the start of the basic block containing INSN]. */ -static int +static bool reg_not_set_p (const_rtx x, const rtx_insn *insn ATTRIBUTE_UNUSED) { return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x)); @@ -722,14 +722,14 @@ find_used_regs (rtx *xptr, void *data ATTRIBUTE_UNUSED) } /* Try to replace all uses of FROM in INSN with TO. - Return nonzero if successful. */ + Return true if successful. */ -static int +static bool try_replace_reg (rtx from, rtx to, rtx_insn *insn) { rtx note = find_reg_equal_equiv_note (insn); rtx src = 0; - int success = 0; + bool success = false; rtx set = single_set (insn); bool check_rtx_costs = true; @@ -765,7 +765,7 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) if (num_changes_pending () && apply_change_group ()) -success = 1; +success = true; /* Try to simplify SET_SRC if we have substituted a constant. */ if (success && set && CONSTANT_P (to)) @@ -790,7 +790,7 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) if (!rtx_equal_p (src, SET_SRC (set)) && validate_change (insn, _SRC (set), src, 0)) - success = 1; + success = true; /* If we've failed perform the replacement, have a single SET to a REG destination and don't yet have a note, add a REG_EQUAL note @@ -808,7 +808,7 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn) if (!rtx_equal_p (dest, SET_DEST (set)) && validate_change (insn, _DEST (set), dest, 0)) -success = 1; + success = true; } /* REG_EQUAL may get simplified into register. @@ -889,10 +889,10 @@ find_avail_set (int regno, rtx_insn *insn, struct cprop_expr *set_ret[2]) JUMP_INSNS. JUMP must be a conditional jump. If SETCC is non-NULL it is the instruction that immediately precedes JUMP, and must be a single SET of a register. FROM is what we will try to replace, - SRC is the constant we will try to substitute for it. Return nonzero + SRC is the constant we will try to substitute for it. Return true if a change was made. */ -static int +static bool cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) { rtx new_rtx, set_src, note_src; @@ -931,7 +931,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) /* If no simplification can be made, then try the next register. */ if (rtx_equal_p (new_rtx, SET_SRC (set))) -return 0; +return false; /* If this is now a no-op delete it, otherwise this must be a valid insn. */ if (new_rtx == pc_rtx) @@ -941,7 +941,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) /* Ensure the value computed inside the jump insn to be equivalent to one computed by setcc. */ if (setcc && modified_in_p (new_rtx, setcc)) - return 0; + return false; if (! validate_unshare_change (jump, _SRC (set), new_rtx, 0)) { /* When (some) constants are not valid in a comparison, and there @@ -955,7 +955,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src) if (!rtx_equal_p (new_rtx, note_src)) set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new_rtx)); - return 0; + return false; }
[committed] gcse: Change return type of predicate functions from int to bool
Also change some internal variables and function arguments from int to bool. gcc/ChangeLog: * gcse.cc (expr_equiv_p): Change return type from int to bool. (oprs_unchanged_p): Change return type from int to void and adjust function body accordingly. (oprs_anticipatable_p): Ditto. (oprs_available_p): Ditto. (insert_expr_in_table): Ditto. Change "antic_p" and "avail_p" arguments to bool. Change "found" variable to bool. (load_killed_in_block_p): Change return type from int to void and adjust function body accordingly. Change "avail_p" argument to bool. (pre_expr_reaches_here_p): Change return type from int to void and adjust function body accordingly. (pre_delete): Ditto. Change "changed" variable to bool. (pre_gcse): Change return type from int to void and adjust function body accordingly. Change "did_insert" and "changed" variables to bool. (one_pre_gcse_pass): Change return type from int to void and adjust function body accordingly. Change "changed" variable to bool. (should_hoist_expr_to_dom): Change return type from int to void and adjust function body accordingly. Change "visited_allocated_locally" variable to bool. (hoist_code): Change return type from int to void and adjust function body accordingly. Change "changed" variable to bool. (one_code_hoisting_pass): Ditto. (pre_edge_insert): Change return type from int to void and adjust function body accordingly. Change "did_insert" variable to bool. (pre_expr_reaches_here_p_work): Change return type from int to void and adjust function body accordingly. (simple_mem): Ditto. (want_to_gcse_p): Change return type from int to void and adjust function body accordingly. (can_assign_to_reg_without_clobbers_p): Update function body for bool return type. (hash_scan_set): Change "antic_p" and "avail_p" variables to bool. (pre_insert_copies): Change "added_copy" variable to bool. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Uros. diff --git a/gcc/gcse.cc b/gcc/gcse.cc index 72832736572..8413c9a18f3 100644 --- a/gcc/gcse.cc +++ b/gcc/gcse.cc @@ -371,7 +371,7 @@ pre_ldst_expr_hasher::hash (const ls_expr *x) hash_rtx (x->pattern, GET_MODE (x->pattern), _not_record_p, NULL, false); } -static int expr_equiv_p (const_rtx, const_rtx); +static bool expr_equiv_p (const_rtx, const_rtx); inline bool pre_ldst_expr_hasher::equal (const ls_expr *ptr1, @@ -454,10 +454,10 @@ static void hash_scan_insn (rtx_insn *, struct gcse_hash_table_d *); static void hash_scan_set (rtx, rtx_insn *, struct gcse_hash_table_d *); static void hash_scan_clobber (rtx, rtx_insn *, struct gcse_hash_table_d *); static void hash_scan_call (rtx, rtx_insn *, struct gcse_hash_table_d *); -static int oprs_unchanged_p (const_rtx, const rtx_insn *, int); -static int oprs_anticipatable_p (const_rtx, const rtx_insn *); -static int oprs_available_p (const_rtx, const rtx_insn *); -static void insert_expr_in_table (rtx, machine_mode, rtx_insn *, int, int, +static bool oprs_unchanged_p (const_rtx, const rtx_insn *, bool); +static bool oprs_anticipatable_p (const_rtx, const rtx_insn *); +static bool oprs_available_p (const_rtx, const rtx_insn *); +static void insert_expr_in_table (rtx, machine_mode, rtx_insn *, bool, bool, HOST_WIDE_INT, struct gcse_hash_table_d *); static unsigned int hash_expr (const_rtx, machine_mode, int *, int); static void record_last_reg_set_info (rtx_insn *, int); @@ -471,42 +471,42 @@ static void dump_hash_table (FILE *, const char *, struct gcse_hash_table_d *); static void compute_local_properties (sbitmap *, sbitmap *, sbitmap *, struct gcse_hash_table_d *); static void mems_conflict_for_gcse_p (rtx, const_rtx, void *); -static int load_killed_in_block_p (const_basic_block, int, const_rtx, int); +static bool load_killed_in_block_p (const_basic_block, int, const_rtx, bool); static void alloc_pre_mem (int, int); static void free_pre_mem (void); static struct edge_list *compute_pre_data (void); -static int pre_expr_reaches_here_p (basic_block, struct gcse_expr *, - basic_block); +static bool pre_expr_reaches_here_p (basic_block, struct gcse_expr *, +basic_block); static void insert_insn_end_basic_block (struct gcse_expr *, basic_block); static void pre_insert_copy_insn (struct gcse_expr *, rtx_insn *); static void pre_insert_copies (void); -static int pre_delete (void); -static int pre_gcse (struct edge_list *); -static int one_pre_gcse_pass (void); +static bool pre_delete (void); +static bool pre_gcse (struct edge_list *); +static bool one_pre_gcse_pass (void); static void add_label_notes (rtx, rtx_insn *); static void alloc_code_hoist_mem (int, int); static void free_code_hoist_mem (void); static void compute_code_hoist_vbeinout (void); static void
Re: [PATCH] Fortran: fixes for procedures with ALLOCATABLE,INTENT(OUT) arguments [PR92178]
Hello, Le 07/07/2023 à 20:23, Harald Anlauf a écrit : Hi Mikael, Am 07.07.23 um 14:21 schrieb Mikael Morin: I'm attaching what I have (lightly) tested so far, which doesn't work. It seems gfc_conv_class_to_class reevaluates part of the original expression, which is not correct after deallocation. this looks much more elegant than my attempt that passed an additional argument to gfc_conv_class_to_class, to achieve what your patch does. Will have a look again tonight. Great. Harald here is what I'm finally coming to. This patch fixes my example, but is otherwise untested. The patch has grown enough that I'm tempted to fix my example separately, in its own commit. Mikaeldiff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index e7c51bae052..1c2af55d436 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -3271,6 +3271,7 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base) gfc_add_block_to_block (block, ); info->descriptor = se.expr; ss_info->string_length = se.string_length; + ss_info->class_container = se.class_container; if (base) { @@ -7687,6 +7688,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) else if (deferred_array_component) se->string_length = ss_info->string_length; + se->class_container = ss_info->class_container; + gfc_free_ss_chain (ss); return; } diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index ebef1a36577..01386bceaeb 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -529,24 +529,10 @@ gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold, } -/* Reset the vptr to the declared type, e.g. after deallocation. */ - -void -gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) +static void +reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_expr) { - gfc_symbol *vtab; - tree vptr; - tree vtable; - gfc_se se; - - /* Evaluate the expression and obtain the vptr from it. */ - gfc_init_se (, NULL); - if (e->rank) -gfc_conv_expr_descriptor (, e); - else -gfc_conv_expr (, e); - gfc_add_block_to_block (block, ); - vptr = gfc_get_vptr_from_expr (se.expr); + tree vptr = gfc_get_vptr_from_expr (class_expr); /* If a vptr is not found, we can do nothing more. */ if (vptr == NULL_TREE) @@ -556,6 +542,9 @@ gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0)); else { + gfc_symbol *vtab; + tree vtable; + /* Return the vptr to the address of the declared type. */ vtab = gfc_find_derived_vtab (e->ts.u.derived); vtable = vtab->backend_decl; @@ -568,6 +557,24 @@ gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) } +/* Reset the vptr to the declared type, e.g. after deallocation. */ + +void +gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) +{ + gfc_se se; + + /* Evaluate the expression and obtain the vptr from it. */ + gfc_init_se (, NULL); + if (e->rank) +gfc_conv_expr_descriptor (, e); + else +gfc_conv_expr (, e); + gfc_add_block_to_block (block, ); + reset_vptr (block, e, se.expr); +} + + /* Reset the len for unlimited polymorphic objects. */ void @@ -1266,6 +1273,8 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, slen = build_zero_cst (size_type_node); } + else if (parmse->class_container != NULL_TREE) +tmp = parmse->class_container; else { /* Remove everything after the last class reference, convert the @@ -3078,6 +3087,11 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr) return; } + if (sym->ts.type == BT_CLASS + && sym->attr.class_ok + && sym->ts.u.derived->attr.is_class) + se->class_container = se->expr; + /* Dereference the expression, where needed. */ se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only, is_classarray); @@ -3135,6 +3149,15 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr) conv_parent_component_references (se, ref); gfc_conv_component_ref (se, ref); + + if (ref->u.c.component->ts.type == BT_CLASS + && ref->u.c.component->attr.class_ok + && ref->u.c.component->ts.u.derived->attr.is_class) + se->class_container = se->expr; + else if (!(ref->u.c.sym->attr.flavor == FL_DERIVED + && ref->u.c.sym->attr.is_class)) + se->class_container = NULL_TREE; + if (!ref->next && ref->u.c.sym->attr.codimension && se->want_pointer && se->descriptor_only) return; @@ -6784,6 +6807,21 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, stmtblock_t block; tree ptr; + /* In case the data reference to deallocate is dependent on + its own content, save the resulting pointer to a variable + and only use that variable from now on, before the + expression becomes invalid. */ + tree t = gfc_build_addr_expr (NULL_TREE, parmse.expr); + t =
Re: [PATCH v4 1/2] c++: implement __is_unsigned built-in trait
Hi, Here is the benchmark result for is_unsigned: https://github.com/ken-matsui/gcc-benches/blob/main/is_unsigned.md#sat-jul--8-041510-am-pdt-2023 Time: -66.908% Peak Memory Usage: -42.5139% Total Memory Usage: -46.3483% Sincerely, Ken Matsui On Sat, Jul 8, 2023 at 4:13 AM Ken Matsui wrote: > > This patch implements built-in trait for std::is_unsigned. > > gcc/cp/ChangeLog: > > * cp-trait.def: Define __is_unsigned. > * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNSIGNED. > * semantics.cc (trait_expr_value): Likewise. > (finish_trait_expr): Likewise. > > gcc/testsuite/ChangeLog: > > * g++.dg/ext/has-builtin-1.C: Test existence of __is_unsigned. > * g++.dg/ext/is_unsigned.C: New test. > > Signed-off-by: Ken Matsui > --- > gcc/cp/constraint.cc | 3 ++ > gcc/cp/cp-trait.def | 1 + > gcc/cp/semantics.cc | 4 ++ > gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 ++ > gcc/testsuite/g++.dg/ext/is_unsigned.C | 47 > 5 files changed, 58 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/ext/is_unsigned.C > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index 8cf0f2d0974..ec8de87d1a1 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -3751,6 +3751,9 @@ diagnose_trait_expr (tree expr, tree args) > case CPTK_IS_UNION: >inform (loc, " %qT is not a union", t1); >break; > +case CPTK_IS_UNSIGNED: > + inform (loc, " %qT is not an unsigned type", t1); > + break; > case CPTK_IS_AGGREGATE: >inform (loc, " %qT is not an aggregate", t1); >break; > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def > index 8b7fece0cc8..1a219243162 100644 > --- a/gcc/cp/cp-trait.def > +++ b/gcc/cp/cp-trait.def > @@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, > "__is_trivially_assignable", 2) > DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", > -1) > DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1) > DEFTRAIT_EXPR (IS_UNION, "__is_union", 1) > +DEFTRAIT_EXPR (IS_UNSIGNED, "__is_unsigned", 1) > DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, > "__reference_constructs_from_temporary", 2) > DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, > "__reference_converts_from_temporary", 2) > /* FIXME Added space to avoid direct usage in GCC 13. */ > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index 8fb47fd179e..2d48894d811 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -12118,6 +12118,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, > tree type2) > case CPTK_IS_UNION: >return type_code1 == UNION_TYPE; > > +case CPTK_IS_UNSIGNED: > + return TYPE_UNSIGNED (type1); > + > case CPTK_IS_ASSIGNABLE: >return is_xible (MODIFY_EXPR, type1, type2); > > @@ -12296,6 +12299,7 @@ finish_trait_expr (location_t loc, cp_trait_kind > kind, tree type1, tree type2) > case CPTK_IS_ENUM: > case CPTK_IS_UNION: > case CPTK_IS_SAME: > +case CPTK_IS_UNSIGNED: >break; > > case CPTK_IS_LAYOUT_COMPATIBLE: > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C > b/gcc/testsuite/g++.dg/ext/has-builtin-1.C > index f343e153e56..20bf8e6cad5 100644 > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C > @@ -146,3 +146,6 @@ > #if !__has_builtin (__remove_cvref) > # error "__has_builtin (__remove_cvref) failed" > #endif > +#if !__has_builtin (__is_unsigned) > +# error "__has_builtin (__is_unsigned) failed" > +#endif > diff --git a/gcc/testsuite/g++.dg/ext/is_unsigned.C > b/gcc/testsuite/g++.dg/ext/is_unsigned.C > new file mode 100644 > index 000..2bb45d209a7 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/ext/is_unsigned.C > @@ -0,0 +1,47 @@ > +// { dg-do compile { target c++11 } } > + > +#include > + > +using namespace __gnu_test; > + > +#define SA(X) static_assert((X),#X) > +#define SA_TEST_CATEGORY(TRAIT, X, expect) \ > + SA(TRAIT(X) == expect); \ > + SA(TRAIT(const X) == expect);\ > + SA(TRAIT(volatile X) == expect); \ > + SA(TRAIT(const volatile X) == expect) > + > +SA_TEST_CATEGORY(__is_unsigned, void, false); > + > +SA_TEST_CATEGORY(__is_unsigned, bool, (bool(-1) > bool(0))); > +SA_TEST_CATEGORY(__is_unsigned, char, (char(-1) > char(0))); > +SA_TEST_CATEGORY(__is_unsigned, signed char, false); > +SA_TEST_CATEGORY(__is_unsigned, unsigned char, true); > +SA_TEST_CATEGORY(__is_unsigned, wchar_t, (wchar_t(-1) > wchar_t(0))); > +SA_TEST_CATEGORY(__is_unsigned, short, false); > +SA_TEST_CATEGORY(__is_unsigned, unsigned short, true); > +SA_TEST_CATEGORY(__is_unsigned, int, false); > +SA_TEST_CATEGORY(__is_unsigned, unsigned int, true); > +SA_TEST_CATEGORY(__is_unsigned, long, false); > +SA_TEST_CATEGORY(__is_unsigned, unsigned long, true); > +SA_TEST_CATEGORY(__is_unsigned, long
[PATCH v4 2/2] libstdc++: use new built-in trait __is_unsigned
This patch lets libstdc++ use new built-in trait __is_unsigned. libstdc++-v3/ChangeLog: * include/std/type_traits (is_unsigned): Use __is_unsigned built-in trait. (is_unsigned_v): Likewise. Signed-off-by: Ken Matsui --- libstdc++-v3/include/std/type_traits | 13 + 1 file changed, 13 insertions(+) diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 0e7a9c9c7f3..7eeb0da7a27 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -884,10 +884,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; /// is_unsigned +#if __has_builtin(__is_unsigned) + template +struct is_unsigned +: public __bool_constant<__is_unsigned(_Tp)> +{ }; +#else template struct is_unsigned : public __and_, __not_>>::type { }; +#endif /// @cond undocumented template @@ -3242,8 +3249,14 @@ template template inline constexpr bool is_signed_v = is_signed<_Tp>::value; + +#if __has_builtin(__is_unsigned) +template + inline constexpr bool is_unsigned_v = __is_unsigned(_Tp); +#else template inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; +#endif template inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); -- 2.41.0
[PATCH v4 1/2] c++: implement __is_unsigned built-in trait
This patch implements built-in trait for std::is_unsigned. gcc/cp/ChangeLog: * cp-trait.def: Define __is_unsigned. * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNSIGNED. * semantics.cc (trait_expr_value): Likewise. (finish_trait_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/ext/has-builtin-1.C: Test existence of __is_unsigned. * g++.dg/ext/is_unsigned.C: New test. Signed-off-by: Ken Matsui --- gcc/cp/constraint.cc | 3 ++ gcc/cp/cp-trait.def | 1 + gcc/cp/semantics.cc | 4 ++ gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 ++ gcc/testsuite/g++.dg/ext/is_unsigned.C | 47 5 files changed, 58 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/is_unsigned.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 8cf0f2d0974..ec8de87d1a1 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3751,6 +3751,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_UNION: inform (loc, " %qT is not a union", t1); break; +case CPTK_IS_UNSIGNED: + inform (loc, " %qT is not an unsigned type", t1); + break; case CPTK_IS_AGGREGATE: inform (loc, " %qT is not an aggregate", t1); break; diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 8b7fece0cc8..1a219243162 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2) DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1) DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1) DEFTRAIT_EXPR (IS_UNION, "__is_union", 1) +DEFTRAIT_EXPR (IS_UNSIGNED, "__is_unsigned", 1) DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2) DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2) /* FIXME Added space to avoid direct usage in GCC 13. */ diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 8fb47fd179e..2d48894d811 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -12118,6 +12118,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_UNION: return type_code1 == UNION_TYPE; +case CPTK_IS_UNSIGNED: + return TYPE_UNSIGNED (type1); + case CPTK_IS_ASSIGNABLE: return is_xible (MODIFY_EXPR, type1, type2); @@ -12296,6 +12299,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_ENUM: case CPTK_IS_UNION: case CPTK_IS_SAME: +case CPTK_IS_UNSIGNED: break; case CPTK_IS_LAYOUT_COMPATIBLE: diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C index f343e153e56..20bf8e6cad5 100644 --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C @@ -146,3 +146,6 @@ #if !__has_builtin (__remove_cvref) # error "__has_builtin (__remove_cvref) failed" #endif +#if !__has_builtin (__is_unsigned) +# error "__has_builtin (__is_unsigned) failed" +#endif diff --git a/gcc/testsuite/g++.dg/ext/is_unsigned.C b/gcc/testsuite/g++.dg/ext/is_unsigned.C new file mode 100644 index 000..2bb45d209a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_unsigned.C @@ -0,0 +1,47 @@ +// { dg-do compile { target c++11 } } + +#include + +using namespace __gnu_test; + +#define SA(X) static_assert((X),#X) +#define SA_TEST_CATEGORY(TRAIT, X, expect) \ + SA(TRAIT(X) == expect); \ + SA(TRAIT(const X) == expect);\ + SA(TRAIT(volatile X) == expect); \ + SA(TRAIT(const volatile X) == expect) + +SA_TEST_CATEGORY(__is_unsigned, void, false); + +SA_TEST_CATEGORY(__is_unsigned, bool, (bool(-1) > bool(0))); +SA_TEST_CATEGORY(__is_unsigned, char, (char(-1) > char(0))); +SA_TEST_CATEGORY(__is_unsigned, signed char, false); +SA_TEST_CATEGORY(__is_unsigned, unsigned char, true); +SA_TEST_CATEGORY(__is_unsigned, wchar_t, (wchar_t(-1) > wchar_t(0))); +SA_TEST_CATEGORY(__is_unsigned, short, false); +SA_TEST_CATEGORY(__is_unsigned, unsigned short, true); +SA_TEST_CATEGORY(__is_unsigned, int, false); +SA_TEST_CATEGORY(__is_unsigned, unsigned int, true); +SA_TEST_CATEGORY(__is_unsigned, long, false); +SA_TEST_CATEGORY(__is_unsigned, unsigned long, true); +SA_TEST_CATEGORY(__is_unsigned, long long, false); +SA_TEST_CATEGORY(__is_unsigned, unsigned long long, true); + +SA_TEST_CATEGORY(__is_unsigned, float, false); +SA_TEST_CATEGORY(__is_unsigned, double, false); +SA_TEST_CATEGORY(__is_unsigned, long double, false); + +#ifndef __STRICT_ANSI__ +// GNU Extensions. +#ifdef __SIZEOF_INT128__ +SA_TEST_CATEGORY(__is_unsigned, unsigned __int128, true); +SA_TEST_CATEGORY(__is_unsigned, __int128, false); +#endif + +#ifdef _GLIBCXX_USE_FLOAT128 +SA_TEST_CATEGORY(__is_unsigned, __float128, false); +#endif +#endif + +// Sanity check.
[committed] doc: Fix typos in Warning Options [PR110596]
Pushed as obvious. -- >8 -- gcc/ChangeLog: PR c++/110595 PR c++/110596 * doc/invoke.texi (Warning Options): Fix typos. --- gcc/doc/invoke.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 594b24d0c2a..3063e71c890 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6730,7 +6730,7 @@ Warn if the compiler does not elide the copy from a local variable to the return value of a function in a context where it is allowed by [class.copy.elision]. This elision is commonly known as the Named Return Value Optimization. For instance, in the example below the -compiler cannot elide copies from both v1 and b2, so it elides neither. +compiler cannot elide copies from both v1 and v2, so it elides neither. @smallexample std::vector f() @@ -7086,7 +7086,7 @@ This warning is enabled by @option{-Wall}. @opindex Wmissing-include-dirs @opindex Wno-missing-include-dirs @item -Wmissing-include-dirs @r{(C, C++, Objective-C, Objective-C++ and Fortran only)} -Warn if a user-supplied include directory does not exist. This opions is disabled +Warn if a user-supplied include directory does not exist. This option is disabled by default for C, C++, Objective-C and Objective-C++. For Fortran, it is partially enabled by default by warning for -I and -J, only. -- 2.41.0
Re: [PATCH] Fortran: simplification of FINDLOC for constant complex arguments [PR110585]
Hi Harald, This is indeed obvious :-) Thanks for the patch. Paul On Fri, 7 Jul 2023 at 19:32, Harald Anlauf via Fortran wrote: > > Dear all, > > I intend to commit the attached obvious patch within 24h unless > someone objects. gfc_compare_expr() did not handle the case of > complex constants, which may be compared for equality. This > case is needed in the simplification of the FINDLOC intrinsic. > > Regtested on x86_64-pc-linux-gnu. > > Thanks, > Harald > -- "If you can't explain it simply, you don't understand it well enough" - Albert Einstein