[r14-2386 Regression] FAIL: gcc.target/i386/pr91681-1.c scan-assembler-not xor on Linux/x86_64

2023-07-08 Thread haochen.jiang via Gcc-patches
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

2023-07-08 Thread Jan Hubicka via Gcc-patches
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

2023-07-08 Thread haochen.jiang via Gcc-patches
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

2023-07-08 Thread Jan Hubicka via Gcc-patches
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]

2023-07-08 Thread Steve Kargl via Gcc-patches
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]

2023-07-08 Thread Harald Anlauf via Gcc-patches

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]

2023-07-08 Thread 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
! { 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]

2023-07-08 Thread Harald Anlauf via Gcc-patches

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

2023-07-08 Thread Uros Bizjak via Gcc-patches
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

2023-07-08 Thread Uros Bizjak via Gcc-patches
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]

2023-07-08 Thread Mikael Morin

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

2023-07-08 Thread Ken Matsui via Gcc-patches
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

2023-07-08 Thread Ken Matsui via Gcc-patches
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

2023-07-08 Thread Ken Matsui via Gcc-patches
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]

2023-07-08 Thread Jonathan Wakely via Gcc-patches
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]

2023-07-08 Thread Paul Richard Thomas via Gcc-patches
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