[RFC][Patch] vect: verify that nelt is greater than one

2023-03-22 Thread Kevin Lee
This is a patch related to 
https://gcc.gnu.org/pipermail/gcc-patches/2023-March/613977.html, 
aiming for gcc14. Since the RISC-V target has vector modes (e.g. VNx1DImode)
with nelt smaller than 2, npat has to match with the nelt to create proper 
vec_perm_indices. 

I tested on x86_64-linux-gnu and didn't cause more failures, but wasn't sure if 
total_elem would be used in the rest of the function. Should there be additional
changes in the vect_grouped_store_supported? Thank you!

gcc/ChangeLog:
Kevin Lee 
* tree-vect-data-refs.cc (vect_grouped_store_supported): Check
if the nelt is greater than one.
---
 gcc/tree-vect-data-refs.cc | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 8daf7bd7dd3..9c09cc973d0 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -5399,17 +5399,20 @@ vect_grouped_store_supported (tree vectype, unsigned 
HOST_WIDE_INT count)
  poly_uint64 nelt = GET_MODE_NUNITS (mode);
 
  /* The encoding has 2 interleaved stepped patterns.  */
- vec_perm_builder sel (nelt, 2, 3);
- sel.quick_grow (6);
+
+unsigned int npat = known_gt(nelt, (unsigned int) 1) ? 2 : 1;
+unsigned int total_elem = npat * 3;
+ vec_perm_builder sel (nelt, npat, 3);
+ sel.quick_grow (total_elem);
  for (i = 0; i < 3; i++)
{
- sel[i * 2] = i;
- sel[i * 2 + 1] = i + nelt;
+ sel[i * npat] = i;
+ sel[i * npat + 1] = i + nelt;
}
  vec_perm_indices indices (sel, 2, nelt);
  if (can_vec_perm_const_p (mode, mode, indices))
{
- for (i = 0; i < 6; i++)
+ for (i = 0; i < total_elem; i++)
sel[i] += exact_div (nelt, 2);
  indices.new_vector (sel, 2, nelt);
  if (can_vec_perm_const_p (mode, mode, indices))
-- 
2.25.1



Re: [PATCH] [testsuite] test for weak_undefined support and add options

2023-03-22 Thread Alexandre Oliva via Gcc-patches
On Mar 18, 2023, Mike Stump  wrote:

> On Mar 15, 2023, at 11:40 PM, Alexandre Oliva  wrote:
>> 
>> On Mar 15, 2023, Alexandre Oliva  wrote:
>> 
>>> Regstrapped on ppc64-linux-gnu.  Also tested (with gcc-12) on multiple
>>> *-vxworks7r2 targets (arm, aarch64, ppc64, x86, x86_64).  Ok to install?
>> 
>> Further testing revealed a problem in my attempted use of lappend in
>> aapcs64.exp, in the previous version of the patch.  Fixed in this one,
>> retested on aarch64-vxworks7r2.  Ok to install?

> Ok.

Thanks.  Marc Poulhies pointed out I'd failed to document the new dg
bits (thanks!).  Fixed below.  I'm going to check it if there are no
objections in the next 24 hours.


[testsuite] test for weak_undefined support and add options

A number of tests that depend on weak undefined symbols fail to
require that support, and arrange to skip some targets and add special
options to others on a test-by-test basis.  Fix this by stating the
requirement explicitly, and adding a proc to return any required
options.

Others rely on weak undefined symbols only to test for the
availability of posix_memalign.  Drop that in favor of dg effective
target support for posix_memalign.


for  gcc/testsuite/ChangeLog

* lib/target-supports.exp (add_options_for_weak_undefined):
New.
(check_effective_target_weak_undefined): Use it.
(check_effective_target_posix_memalign): New.
* doc/sourcebuild.texi: Document them.
* gcc.dg/torture/pr53922.c: Drop skips and custom options in
favor of effective target requirement and added options for
weak_undefined symbols.
* gcc.dg/torture/pr90020.c: Likewise.
* gcc.dg/addr_equal-1.c: Likewise.
* gcc.target/aarch64/aapcs64/aapcs64.exp: Likewise, for
abitest.S-using tests.
* gcc.dg/torture/pr60092.c: Likewise, but in favor of
posix_memalign tests.
* gcc.dg/vect/vect-tail-nomask-1.c: Likewise.
---
 gcc/doc/sourcebuild.texi   |9 ++
 gcc/testsuite/gcc.dg/addr_equal-1.c|5 +---
 gcc/testsuite/gcc.dg/torture/pr53922.c |   10 +--
 gcc/testsuite/gcc.dg/torture/pr60092.c |   12 +
 gcc/testsuite/gcc.dg/torture/pr90020.c |7 +
 gcc/testsuite/gcc.dg/vect/vect-tail-nomask-1.c |   11 +---
 .../gcc.target/aarch64/aapcs64/aapcs64.exp |   17 +++-
 gcc/testsuite/lib/target-supports.exp  |   28 ++--
 8 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 80bef7f0a0e22..c430bceb33ae8 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2697,6 +2697,9 @@ Target supports Newlib.
 GCC was configured with @code{--enable-newlib-nano-formatted-io}, which reduces
 the code size of Newlib formatted I/O functions.
 
+@item posix_memalign
+Target supports @code{posix_memalign}.
+
 @item pow10
 Target provides @code{pow10} function.
 
@@ -2759,6 +2762,9 @@ Target is a VxWorks RTP.
 
 @item wchar
 Target supports wide characters.
+
+@item weak_undefined
+Target supports weak undefined symbols
 @end table
 
 @subsubsection Other attributes
@@ -3130,6 +3136,9 @@ instructions, if any.
 
 @item tls
 Add the target-specific flags needed to use thread-local storage.
+
+@item weak_undefined
+Add the flags needed to enable support for weak undefined symbols.
 @end table
 
 @node Require Support
diff --git a/gcc/testsuite/gcc.dg/addr_equal-1.c 
b/gcc/testsuite/gcc.dg/addr_equal-1.c
index 35fa0102e3063..db65dea4a8d2a 100644
--- a/gcc/testsuite/gcc.dg/addr_equal-1.c
+++ b/gcc/testsuite/gcc.dg/addr_equal-1.c
@@ -1,9 +1,8 @@
-/* { dg-do run { target { nonpic || pie_enabled } } } */
-/* { dg-require-weak "" } */
+/* { dg-do run { target { { nonpic || pie_enabled } && weak_undefined } } } */
 /* { dg-require-alias "" } */
 /* { dg-options "-O2 -fdelete-null-pointer-checks" } */
-/* { dg-skip-if "" { powerpc-ibm-aix* } } */
 /* { dg-skip-if "function pointers can be NULL" { keeps_null_pointer_checks } 
} */
+/* { dg-add-options weak_undefined } */
 void abort (void);
 extern int undef_var0, undef_var1;
 extern __attribute__ ((weak)) int weak_undef_var0;
diff --git a/gcc/testsuite/gcc.dg/torture/pr53922.c 
b/gcc/testsuite/gcc.dg/torture/pr53922.c
index b3f2c1a58f830..07359d6764964 100644
--- a/gcc/testsuite/gcc.dg/torture/pr53922.c
+++ b/gcc/testsuite/gcc.dg/torture/pr53922.c
@@ -1,11 +1,5 @@
-/* { dg-do run } */
-/* { dg-require-weak "" } */
-/* { dg-skip-if "No undefined" { *-*-mingw* } } */
-/* { dg-skip-if "No undefined weak" { *-*-aix* } } */
-/* { dg-skip-if "No undefined weak" { hppa*-*-hpux* && { ! lp64 } } } */
-/* { dg-skip-if "No undefined weak" { nvptx-*-* } } */
-/* { dg-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
-/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } 
*/
+/* { dg-do run { target { weak_undefined } } } */
+/* { 

Re: [PATCH] RISC-V: Fix ICE of RVV compare intrinsic

2023-03-22 Thread Kito Cheng via Gcc-patches
committed as 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6f6eba35b9f06d35ff7bea81969fe905a5584bdc

On Fri, Mar 10, 2023 at 4:09 PM  wrote:
>
> From: Ju-Zhe Zhong 
>
> vfrsub_vf_m.cpp: In function 'int main()':
> vfrsub_vf_m.cpp:5:43: error: invalid argument to built-in function
>5 |   vbool32_t d = __riscv_vmflt_vf_f32m1_b32(c, b, 8);
>  | ~~^
> during RTL pass: expand
> vfrsub_vf_m.cpp:5:43: internal compiler error: Segmentation fault
> 0x19f1b89 crash_signal
>../../../../riscv-gnu-toolchain-trunk/riscv-gcc/gcc/toplev.cc:314
> 0x1472e2f store_expr(tree_node*, rtx_def*, int, bool, bool)
>../../../../riscv-gnu-toolchain-trunk/riscv-gcc/gcc/expr.cc:6348
>
> gcc/ChangeLog:
>
> * config/riscv/riscv-vector-builtins.cc 
> (function_expander::use_compare_insn): Add operand predicate check.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/base/bug-1.c: New test.
>
> ---
>  gcc/config/riscv/riscv-vector-builtins.cc |  9 +++
>  .../gcc.target/riscv/rvv/base/bug-1.c | 79 +++
>  2 files changed, 88 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-1.c
>
> diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
> b/gcc/config/riscv/riscv-vector-builtins.cc
> index fcda3863576..75e65091db3 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -3084,6 +3084,15 @@ function_expander::use_compare_insn (rtx_code rcode, 
> insn_code icode)
>
>rtx op1 = expand_normal (CALL_EXPR_ARG (exp, arg_offset++));
>rtx op2 = expand_normal (CALL_EXPR_ARG (exp, arg_offset++));
> +  if (!insn_operand_matches (icode, opno + 1, op1))
> +op1 = force_reg (mode, op1);
> +  if (!insn_operand_matches (icode, opno + 2, op2))
> +{
> +  if (VECTOR_MODE_P (GET_MODE (op2)))
> +   op2 = force_reg (mode, op2);
> +  else
> +   op2 = force_reg (GET_MODE_INNER (mode), op2);
> +}
>rtx comparison = gen_rtx_fmt_ee (rcode, mask_mode, op1, op2);
>if (!VECTOR_MODE_P (GET_MODE (op2)))
>  comparison = gen_rtx_fmt_ee (rcode, mask_mode, op1,
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-1.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-1.c
> new file mode 100644
> index 000..a8843674e31
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-1.c
> @@ -0,0 +1,79 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O0" } */
> +
> +#include "riscv_vector.h"
> +
> +int
> +f0 ()
> +{
> +  float b;
> +  vfloat32m1_t c;
> +  vbool32_t d = __riscv_vmflt_vf_f32m1_b32 (c, b, 8);
> +  return 0;
> +}
> +
> +int
> +f1 ()
> +{
> +  vfloat32m1_t c;
> +  vbool32_t d = __riscv_vmflt_vf_f32m1_b32 (c, 0, 8);
> +  return 0;
> +}
> +
> +int
> +f2 ()
> +{
> +  vfloat32m1_t c;
> +  vbool32_t d = __riscv_vmflt_vf_f32m1_b32 (c, 55.55, 8);
> +  return 0;
> +}
> +
> +int
> +f3 ()
> +{
> +  int32_t b;
> +  vint32m1_t c;
> +  vbool32_t d = __riscv_vmseq_vx_i32m1_b32 (c, b, 8);
> +  return 0;
> +}
> +
> +int
> +f4 ()
> +{
> +  vint32m1_t c;
> +  vbool32_t d = __riscv_vmseq_vx_i32m1_b32 (c, 11, 8);
> +  return 0;
> +}
> +
> +int
> +f5 ()
> +{
> +  int64_t b;
> +  vint64m1_t c;
> +  vbool64_t d = __riscv_vmseq_vx_i64m1_b64 (c, b, 8);
> +  return 0;
> +}
> +
> +int
> +f6 ()
> +{
> +  vint64m1_t c;
> +  vbool64_t d = __riscv_vmseq_vx_i64m1_b64 (c, 11, 8);
> +  return 0;
> +}
> +
> +int
> +f7 ()
> +{
> +  vint64m1_t c;
> +  vbool64_t d = __riscv_vmseq_vx_i64m1_b64 (c, 0x, 8);
> +  return 0;
> +}
> +
> +int
> +f8 ()
> +{
> +  vint64m1_t c;
> +  vbool64_t d = __riscv_vmseq_vx_i64m1_b64 (c, 0xAA, 8);
> +  return 0;
> +}
> --
> 2.36.3
>


Re: Re: [PATCH] RISC-V: Fix bugs of ternary integer and floating-point ternary intrinsics.

2023-03-22 Thread Kito Cheng via Gcc-patches
committed as 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0e2715176df3787d1470d7b9bde26b1b5e16e1e2

On Mon, Mar 20, 2023 at 8:51 AM juzhe.zh...@rivai.ai
 wrote:
>
> The last patch. Kito is still keep testing with pressure tests.
>
>
>
> juzhe.zh...@rivai.ai
>
> From: Jeff Law
> Date: 2023-03-20 01:03
> To: juzhe.zhong; gcc-patches
> CC: kito.cheng
> Subject: Re: [PATCH] RISC-V: Fix bugs of ternary integer and floating-point 
> ternary intrinsics.
>
>
> On 3/15/23 00:37, juzhe.zh...@rivai.ai wrote:
> > From: Ju-Zhe Zhong 
> >
> > Fix bugs of ternary intrinsic pattern:
> >
> > interger:
> > vnmsac.vv vd, vs1, vs2, vm# vd[i] = -(vs1[i] * vs2[i]) + vd[i]  (minus 
> > op3 (mult op1 op2))
> > vnmsac.vx vd, rs1, vs2, vm# vd[i] = -(x[rs1] * vs2[i]) + vd[i]   (minus 
> > op3 (mult op1 op2))
> >
> > floating-point:
> > # FP multiply-accumulate, overwrites addend
> > vfmacc.vv vd, vs1, vs2, vm# vd[i] = +(vs1[i] * vs2[i]) + vd[i] (plus 
> > (mult (op1 op2)) op3)
> > vfmacc.vf vd, rs1, vs2, vm# vd[i] = +(f[rs1] * vs2[i]) + vd[i] (plus 
> > (mult (op1 op2)) op3)
> >
> >
> > # FP negate-(multiply-accumulate), overwrites subtrahend
> > vfnmacc.vv vd, vs1, vs2, vm   # vd[i] = -(vs1[i] * vs2[i]) - vd[i] (minus 
> > (neg (mult (op1 op2))) op3))
> > vfnmacc.vf vd, rs1, vs2, vm   # vd[i] = -(f[rs1] * vs2[i]) - vd[i] (minus 
> > (neg (mult (op1 op2)) op3))
> > # FP multiply-subtract-accumulator, overwrites subtrahend
> > vfmsac.vv vd, vs1, vs2, vm# vd[i] = +(vs1[i] * vs2[i]) - vd[i] (minus 
> > (mult (op1 op2)) op3)
> > vfmsac.vf vd, rs1, vs2, vm# vd[i] = +(f[rs1] * vs2[i]) - vd[i] (minus 
> > (mult (op1 op2)) op3)
> >
> > # FP negate-(multiply-subtract-accumulator), overwrites minuend
> > vfnmsac.vv vd, vs1, vs2, vm   # vd[i] = -(vs1[i] * vs2[i]) + vd[i] (plus 
> > (neg:(mult (op1 op2))) op3)
> > vfnmsac.vf vd, rs1, vs2, vm   # vd[i] = -(f[rs1] * vs2[i]) + vd[i] (plus 
> > (neg:(mult (op1 op2))) op3)
> >
> > gcc/ChangeLog:
> >
> >  * config/riscv/riscv-vector-builtins-bases.cc: Fix ternary bug.
> >  * config/riscv/vector-iterators.md (nmsac): Ditto.
> >  (nmsub): Ditto.
> >  (msac): Ditto.
> >  (msub): Ditto.
> >  (nmadd): Ditto.
> >  (nmacc): Ditto.
> >  * config/riscv/vector.md (@pred_mul_): Ditto.
> >  (@pred_mul_plus): Ditto.
> >  (*pred_madd): Ditto.
> >  (*pred_macc): Ditto.
> >  (*pred_mul_plus): Ditto.
> >  (@pred_mul_plus_scalar): Ditto.
> >  (*pred_madd_scalar): Ditto.
> >  (*pred_macc_scalar): Ditto.
> >  (*pred_mul_plus_scalar): Ditto.
> >  (*pred_madd_extended_scalar): Ditto.
> >  (*pred_macc_extended_scalar): Ditto.
> >  (*pred_mul_plus_extended_scalar): Ditto.
> >  (@pred_minus_mul): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_nmsub): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_nmsac): Ditto.
> >  (*pred_mul_): Ditto.
> >  (*pred_minus_mul): Ditto.
> >  (@pred_mul__scalar): Ditto.
> >  (@pred_minus_mul_scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred_nmsub_scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred_nmsac_scalar): Ditto.
> >  (*pred_mul__scalar): Ditto.
> >  (*pred_minus_mul_scalar): Ditto.
> >  (*pred__extended_scalar): Ditto.
> >  (*pred_nmsub_extended_scalar): Ditto.
> >  (*pred__extended_scalar): Ditto.
> >  (*pred_nmsac_extended_scalar): Ditto.
> >  (*pred_mul__extended_scalar): Ditto.
> >  (*pred_minus_mul_extended_scalar): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (@pred_neg_mul_): Ditto.
> >  (@pred_mul_neg_): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_): Ditto.
> >  (*pred_neg_mul_): Ditto.
> >  (*pred_mul_neg_): Ditto.
> >  (@pred_neg_mul__scalar): Ditto.
> >  (@pred_mul_neg__scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred__scalar): Ditto.
> >  (*pred_neg_mul__scalar): Ditto.
> >  (*pred_mul_neg__scalar): Ditto.
> >  (@pred_widen_neg_mul_): Ditto.
> >  (@pred_widen_mul_neg_): Ditto.
> >  (@pred_widen_neg_mul__scalar): Ditto.
> >  (@pred_widen_mul_neg__scalar): Ditto.
> It looks like you've got two patches that are almost 100% identical
> except for a few bits in vector.md.  Which is the correct version?
>
> One is dated 3/14/23 00:30 the other 3/15/23: 04:07.
>
> jeff
>


Re: [PATCH] RISC-V: Fix RVV ICE && runtine fail

2023-03-22 Thread Kito Cheng via Gcc-patches
committd as 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=a481eed8fd01837cdf011ea9a17853505080a888
with comment tweaks

On Mon, Mar 20, 2023 at 12:30 PM  wrote:
>
> From: Ju-Zhe Zhong 
>
> gcc/ChangeLog:
>
> * config/riscv/riscv-vsetvl.cc (eliminate_insn): Fix bugs.
> (insert_vsetvl): Ditto.
> (pass_vsetvl::emit_local_forward_vsetvls): Ditto.
> * config/riscv/riscv-vsetvl.h (enum vsetvl_type): Ditto.
> * config/riscv/vector.md: Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * g++.target/riscv/rvv/base/bug-16.C: New test.
> * g++.target/riscv/rvv/base/bug-17.C: New test.
>
> ---
>  gcc/config/riscv/riscv-vsetvl.cc  |  31 +-
>  gcc/config/riscv/riscv-vsetvl.h   |   1 +
>  gcc/config/riscv/vector.md|   4 +-
>  .../g++.target/riscv/rvv/base/bug-16.C| 443 ++
>  .../g++.target/riscv/rvv/base/bug-17.C| 406 
>  5 files changed, 876 insertions(+), 9 deletions(-)
>  create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/bug-16.C
>  create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/bug-17.C
>
> diff --git a/gcc/config/riscv/riscv-vsetvl.cc 
> b/gcc/config/riscv/riscv-vsetvl.cc
> index f4c1773da0d..b5f5301ea43 100644
> --- a/gcc/config/riscv/riscv-vsetvl.cc
> +++ b/gcc/config/riscv/riscv-vsetvl.cc
> @@ -686,7 +686,7 @@ eliminate_insn (rtx_insn *rinsn)
>  delete_insn (rinsn);
>  }
>
> -static void
> +static vsetvl_type
>  insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
>const vector_insn_info , const vector_insn_info 
> _info)
>  {
> @@ -697,14 +697,14 @@ insert_vsetvl (enum emit_type emit_type, rtx_insn 
> *rinsn,
>  {
>emit_vsetvl_insn (VSETVL_VTYPE_CHANGE_ONLY, emit_type, info, NULL_RTX,
> rinsn);
> -  return;
> +  return VSETVL_VTYPE_CHANGE_ONLY;
>  }
>
>if (info.has_avl_imm ())
>  {
>emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, info, NULL_RTX,
> rinsn);
> -  return;
> +  return VSETVL_DISCARD_RESULT;
>  }
>
>if (info.has_avl_no_reg ())
> @@ -716,14 +716,14 @@ insert_vsetvl (enum emit_type emit_type, rtx_insn 
> *rinsn,
> {
>   emit_vsetvl_insn (VSETVL_VTYPE_CHANGE_ONLY, emit_type, info, 
> NULL_RTX,
> rinsn);
> - return;
> + return VSETVL_VTYPE_CHANGE_ONLY;
> }
>/* Otherwise use an AVL of 0 to avoid depending on previous vl.  */
>vl_vtype_info new_info = info;
>new_info.set_avl_info (avl_info (const0_rtx, nullptr));
>emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, new_info, NULL_RTX,
> rinsn);
> -  return;
> +  return VSETVL_DISCARD_RESULT;
>  }
>
>/* Use X0 as the DestReg unless AVLReg is X0. We also need to change the
> @@ -735,7 +735,7 @@ insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
>rtx vl_op = info.get_avl_reg_rtx ();
>gcc_assert (!vlmax_avl_p (vl_op));
>emit_vsetvl_insn (VSETVL_NORMAL, emit_type, info, vl_op, rinsn);
> -  return;
> +  return VSETVL_NORMAL;
>  }
>
>emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, info, NULL_RTX, rinsn);
> @@ -745,6 +745,7 @@ insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
>fprintf (dump_file, "Update VL/VTYPE info, previous info=");
>prev_info.dump (dump_file);
>  }
> +  return VSETVL_DISCARD_RESULT;
>  }
>
>  /* If X contains any LABEL_REF's, add REG_LABEL_OPERAND notes for them
> @@ -2760,6 +2761,7 @@ pass_vsetvl::emit_local_forward_vsetvls (const bb_info 
> *bb)
>for (insn_info *insn : bb->real_nondebug_insns ())
>  {
>const vector_insn_info prev_info = curr_info;
> +  enum vsetvl_type type = NUM_VSETVL_TYPE;
>transfer_before (curr_info, insn);
>
>if (has_vtype_op (insn->rtl ()))
> @@ -2771,10 +2773,25 @@ pass_vsetvl::emit_local_forward_vsetvls (const 
> bb_info *bb)
> = m_vector_manager->vector_insn_infos[insn->uid ()];
>   if (!require.compatible_p (
> static_cast (prev_info)))
> -   insert_vsetvl (EMIT_BEFORE, insn->rtl (), require, prev_info);
> +   type = insert_vsetvl (EMIT_BEFORE, insn->rtl (), require,
> + prev_info);
> }
> }
>
> +  /* Fix the issue of following sequence:
> +vsetivli zero, 5
> +
> +vsetvli zero, zero
> +vmv.x.s (demand AVL = 8).
> +
> +incorrect: vsetvli zero, zero ===> Since the curr_info is AVL = 8.
> +correct: vsetivli zero, 8
> +vadd (demand AVL = 8).  */
> +  if (type == VSETVL_VTYPE_CHANGE_ONLY)
> +   {
> + /* Update the curr_info to be real correct AVL.  */
> + curr_info.set_avl_info (prev_info.get_avl_info ());
> +   }
>transfer_after (curr_info, insn);

Re: [PATCH] RISC-V: Fix redundant vmv1r.v instruction in vmsge.vx codegen

2023-03-22 Thread Kito Cheng via Gcc-patches
LGTM, but pending this to the GCC 14 queue.

On Wed, Mar 22, 2023 at 8:16 PM  wrote:
>
> From: Ju-Zhe Zhong 
>
> Current expansion of vmsge will make RA produce redundant vmv1r.v.
>
> testcase:
> void f1 (void * in, void *out, int32_t x)
> {
> vbool32_t mask = *(vbool32_t*)in;
> asm volatile ("":::"memory");
> vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
> vint32m1_t v2 = __riscv_vle32_v_i32m1_m (mask, in, 4);
> vbool32_t m3 = __riscv_vmsge_vx_i32m1_b32 (v, x, 4);
> vbool32_t m4 = __riscv_vmsge_vx_i32m1_b32_mu (mask, m3, v, x, 4);
> m4 = __riscv_vmsge_vv_i32m1_b32_m (m4, v2, v2, 4);
> __riscv_vsm_v_b32 (out, m4, 4);
> }
>
> Before this patch:
> f1:
> vsetvli a5,zero,e8,mf4,ta,ma
> vlm.v   v0,0(a0)
> vsetivlizero,4,e32,m1,ta,mu
> vle32.v v3,0(a0)
> vle32.v v2,0(a0),v0.t
> vmslt.vxv1,v3,a2
> vmnot.m v1,v1
> vmslt.vxv1,v3,a2,v0.t
> vmxor.mmv1,v1,v0
> vmv1r.v v0,v1
> vmsge.vvv2,v2,v2,v0.t
> vsm.v   v2,0(a1)
> ret
>
> After this patch:
> f1:
> vsetvli a5,zero,e8,mf4,ta,ma
> vlm.v   v0,0(a0)
> vsetivlizero,4,e32,m1,ta,mu
> vle32.v v3,0(a0)
> vle32.v v2,0(a0),v0.t
> vmslt.vxv1,v3,a2
> vmnot.m v1,v1
> vmslt.vxv1,v3,a2,v0.t
> vmxor.mmv0,v1,v0
> vmsge.vvv2,v2,v2,v0.t
> vsm.v   v2,0(a1)
> ret
>
>
> gcc/ChangeLog:
>
> * config/riscv/vector.md: Fix redundant vmv1r.v.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/base/binop_vx_constraint-150.c: Adapt assembly 
> check.
>
> ---
>  gcc/config/riscv/vector.md| 15 +++
>  .../riscv/rvv/base/binop_vx_constraint-150.c  |  2 +-
>  2 files changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
> index ebb014aecb1..f06d68be80f 100644
> --- a/gcc/config/riscv/vector.md
> +++ b/gcc/config/riscv/vector.md
> @@ -4111,6 +4111,7 @@
>  {
>enum rtx_code code = GET_CODE (operands[3]);
>rtx undef = RVV_VUNDEF (mode);
> +  rtx tmp = gen_reg_rtx (mode);
>if (code == GEU && rtx_equal_p (operands[5], const0_rtx))
>  {
>/* If vmsgeu with 0 immediate, expand it to vmset.  */
> @@ -4157,12 +4158,11 @@
> - pseudoinstruction: vmsge{u}.vx vd, va, x
> - expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd.  */
>   emit_insn (
> -   gen_pred_cmp_scalar (operands[0], operands[1], operands[2],
> +   gen_pred_cmp_scalar (tmp, operands[1], operands[2],
> operands[3], operands[4], operands[5],
> operands[6], operands[7], 
> operands[8]));
>   emit_insn (gen_pred_nand (operands[0], CONSTM1_RTX (mode),
> -   undef, operands[0], operands[0],
> -   operands[6], operands[8]));
> +   undef, tmp, tmp, operands[6], 
> operands[8]));
> }
>else
> {
> @@ -4171,13 +4171,12 @@
>   /* masked va >= x, vd == v0
> - pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
> - expansion: vmslt{u}.vx vt, va, x;  vmandn.mm vd, vd, vt.  */
> - rtx reg = gen_reg_rtx (mode);
>   emit_insn (gen_pred_cmp_scalar (
> -   reg, CONSTM1_RTX (mode), undef, operands[3], operands[4],
> +   tmp, CONSTM1_RTX (mode), undef, operands[3], operands[4],
> operands[5], operands[6], operands[7], operands[8]));
>   emit_insn (
> gen_pred_andnot (operands[0], CONSTM1_RTX (mode), 
> undef,
> -  operands[1], reg, operands[6], 
> operands[8]));
> +  operands[1], tmp, operands[6], 
> operands[8]));
> }
>   else
> {
> @@ -4186,10 +4185,10 @@
> - expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0.
>   */
>   emit_insn (gen_pred_cmp_scalar (
> -   operands[0], operands[1], operands[2], operands[3], 
> operands[4],
> +   tmp, operands[1], operands[2], operands[3], operands[4],
> operands[5], operands[6], operands[7], operands[8]));
>   emit_insn (gen_pred (XOR, mode, operands[0],
> -  CONSTM1_RTX (mode), undef, operands[0],
> +  CONSTM1_RTX (mode), undef, tmp,
>operands[1], operands[6], operands[8]));
> }
> }
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-150.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-150.c
> index 55a222f47ea..e92a8115f09 100644

Re: [PATCH] RISC-V: Fix ICE in LRA for LMUL < 1 vector spillings

2023-03-22 Thread Kito Cheng via Gcc-patches
Committed as 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=cd0c433e5faba9a18f64881cd761a53a530aa798
with comment tweak.

On Wed, Mar 22, 2023 at 10:50 AM  wrote:
>
> From: Ju-Zhe Zhong 
>
> gcc/ChangeLog:
>
> * config/riscv/riscv-protos.h (emit_vlmax_vsetvl): Define as global.
> (emit_vlmax_op): Ditto.
> * config/riscv/riscv-v.cc (get_sew): New function.
> (emit_vlmax_vsetvl): Adapt function.
> (emit_pred_op): Ditto.
> (emit_vlmax_op): Ditto.
> (emit_nonvlmax_op): Ditto.
> (legitimize_move): Fix LRA ICE.
> (gen_no_side_effects_vsetvl_rtx): Adapt function.
> * config/riscv/vector.md (@mov_lra): New 
> pattern.
> (@mov_lra): Ditto.
> (*mov_lra): Ditto.
> (*mov_lra): Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/base/binop_vv_constraint-4.c: Adapt testcase.
> * gcc.target/riscv/rvv/base/binop_vv_constraint-6.c: Ditto.
> * gcc.target/riscv/rvv/base/binop_vx_constraint-127.c: Ditto.
> * gcc.target/riscv/rvv/base/spill-1.c: Ditto.
> * gcc.target/riscv/rvv/base/spill-2.c: Ditto.
> * gcc.target/riscv/rvv/base/spill-3.c: Ditto.
> * gcc.target/riscv/rvv/base/spill-5.c: Ditto.
> * gcc.target/riscv/rvv/base/spill-7.c: Ditto.
> * g++.target/riscv/rvv/base/bug-18.C: New test.
> * gcc.target/riscv/rvv/base/merge_constraint-3.c: New test.
> * gcc.target/riscv/rvv/base/merge_constraint-4.c: New test.
>
> ---
>  gcc/config/riscv/riscv-protos.h   |   2 +
>  gcc/config/riscv/riscv-v.cc   |  67 +--
>  gcc/config/riscv/vector.md|  56 ++
>  .../g++.target/riscv/rvv/base/bug-18.C| 140 +++
>  .../riscv/rvv/base/binop_vv_constraint-4.c|   1 +
>  .../riscv/rvv/base/binop_vv_constraint-6.c|   1 +
>  .../riscv/rvv/base/binop_vx_constraint-127.c  |   2 +-
>  .../riscv/rvv/base/merge_constraint-3.c   |  95 ++
>  .../riscv/rvv/base/merge_constraint-4.c   |  28 +++
>  .../gcc.target/riscv/rvv/base/spill-1.c   | 168 +-
>  .../gcc.target/riscv/rvv/base/spill-2.c   | 112 ++--
>  .../gcc.target/riscv/rvv/base/spill-3.c   |  56 +++---
>  .../gcc.target/riscv/rvv/base/spill-5.c   |  26 +--
>  .../gcc.target/riscv/rvv/base/spill-7.c   | 161 +
>  14 files changed, 636 insertions(+), 279 deletions(-)
>  create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/bug-18.C
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/merge_constraint-3.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/merge_constraint-4.c
>
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index f35aaf35b48..060dddbdc22 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -157,7 +157,9 @@ bool check_builtin_call (location_t, vec, 
> unsigned int,
>tree, unsigned int, tree *);
>  bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
>  bool legitimize_move (rtx, rtx, machine_mode);
> +void emit_vlmax_vsetvl (machine_mode, rtx);
>  void emit_vlmax_op (unsigned, rtx, rtx, machine_mode);
> +void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
>  void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
>  enum vlmul_type get_vlmul (machine_mode);
>  unsigned int get_ratio (machine_mode);
> diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
> index 9b83ef6ea5e..d7b77fd6123 100644
> --- a/gcc/config/riscv/riscv-v.cc
> +++ b/gcc/config/riscv/riscv-v.cc
> @@ -98,6 +98,15 @@ private:
>expand_operand m_ops[MAX_OPERANDS];
>  };
>
> +static unsigned
> +get_sew (machine_mode mode)
> +{
> +  unsigned int sew = GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
> +  ? 8
> +  : GET_MODE_BITSIZE (GET_MODE_INNER (mode));
> +  return sew;
> +}
> +
>  /* Return true if X is a const_vector with all duplicate elements, which is 
> in
> the range between MINVAL and MAXVAL.  */
>  bool
> @@ -109,13 +118,10 @@ const_vec_all_same_in_range_p (rtx x, HOST_WIDE_INT 
> minval,
>   && IN_RANGE (INTVAL (elt), minval, maxval));
>  }
>
> -static rtx
> -emit_vlmax_vsetvl (machine_mode vmode)
> +void
> +emit_vlmax_vsetvl (machine_mode vmode, rtx vl)
>  {
> -  rtx vl = gen_reg_rtx (Pmode);
> -  unsigned int sew = GET_MODE_CLASS (vmode) == MODE_VECTOR_BOOL
> -  ? 8
> -  : GET_MODE_BITSIZE (GET_MODE_INNER (vmode));
> +  unsigned int sew = get_sew (vmode);
>enum vlmul_type vlmul = get_vlmul (vmode);
>unsigned int ratio = calculate_ratio (sew, vlmul);
>
> @@ -125,8 +131,6 @@ emit_vlmax_vsetvl (machine_mode vmode)
>const0_rtx));
>else
>  emit_insn (gen_vlmax_avl (Pmode, vl, gen_int_mode (ratio, Pmode)));
> -
> -  return vl;
>  }
>
>  /* Calculate 

Re: [PATCH] RISC-V: Fix PR109228

2023-03-22 Thread Kito Cheng via Gcc-patches
committed as 
https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=116a8678840f9f52ec14639ff07e302a8c429f32
with few comment tweak.

On Wed, Mar 22, 2023 at 1:06 PM  wrote:
>
> From: Ju-Zhe Zhong 
>
> This patch fix PR109228
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109228
>
> gcc/ChangeLog:
>
> * config/riscv/riscv-vector-builtins-bases.cc (class vlenb): Add 
> __riscv_vlenb support.
> (BASE): Ditto.
> * config/riscv/riscv-vector-builtins-bases.h: Ditto.
> * config/riscv/riscv-vector-builtins-functions.def (vlenb): Ditto.
> * config/riscv/riscv-vector-builtins-shapes.cc (struct vlenb_def): 
> Ditto.
> (SHAPE): Ditto.
> * config/riscv/riscv-vector-builtins-shapes.h: Ditto.
> * config/riscv/riscv-vector-builtins.cc: Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/base/vlenb-1.c: New test.
>
> ---
>  .../riscv/riscv-vector-builtins-bases.cc  | 17 +++
>  .../riscv/riscv-vector-builtins-bases.h   |  1 +
>  .../riscv/riscv-vector-builtins-functions.def |  1 +
>  .../riscv/riscv-vector-builtins-shapes.cc | 25 ++
>  .../riscv/riscv-vector-builtins-shapes.h  |  1 +
>  gcc/config/riscv/riscv-vector-builtins.cc |  7 +++
>  .../gcc.target/riscv/rvv/base/vlenb-1.c   | 46 +++
>  7 files changed, 98 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlenb-1.c
>
> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc 
> b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 839eb66efb2..52467bbc961 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -1658,6 +1658,21 @@ public:
>}
>  };
>
> +/* Implements vlenb.  */
> +class vlenb : public function_base
> +{
> +public:
> +  bool apply_vl_p () const override { return false; }
> +
> +  rtx expand (function_expander ) const override
> +  {
> +machine_mode mode = GET_MODE (e.target);
> +rtx vlenb = gen_int_mode (BYTES_PER_RISCV_VECTOR, mode);
> +emit_move_insn (e.target, vlenb);
> +return e.target;
> +  }
> +};
> +
>  static CONSTEXPR const vsetvl vsetvl_obj;
>  static CONSTEXPR const vsetvl vsetvlmax_obj;
>  static CONSTEXPR const loadstore vle_obj;
> @@ -1868,6 +1883,7 @@ static CONSTEXPR const vset vset_obj;
>  static CONSTEXPR const vget vget_obj;
>  static CONSTEXPR const read_vl read_vl_obj;
>  static CONSTEXPR const vleff vleff_obj;
> +static CONSTEXPR const vlenb vlenb_obj;
>
>  /* Declare the function base NAME, pointing it to an instance
> of class _obj.  */
> @@ -2084,5 +2100,6 @@ BASE (vset)
>  BASE (vget)
>  BASE (read_vl)
>  BASE (vleff)
> +BASE (vlenb)
>
>  } // end namespace riscv_vector
> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h 
> b/gcc/config/riscv/riscv-vector-builtins-bases.h
> index 14e8a55cd97..0196f80b69e 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.h
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
> @@ -240,6 +240,7 @@ extern const function_base *const vset;
>  extern const function_base *const vget;
>  extern const function_base *const read_vl;
>  extern const function_base *const vleff;
> +extern const function_base *const vlenb;
>  }
>
>  } // end namespace riscv_vector
> diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def 
> b/gcc/config/riscv/riscv-vector-builtins-functions.def
> index 198ccfd86b7..3f1513cb9fd 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-functions.def
> +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
> @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
>
>  /* Internal helper functions for gimple fold use.  */
>  DEF_RVV_FUNCTION (read_vl, read_vl, none_preds, p_none_void_ops)
> +DEF_RVV_FUNCTION (vlenb, vlenb, none_preds, ul_none_void_ops)
>
>  /* 6. Configuration-Setting Instructions.  */
>
> diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc 
> b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> index edb0d34b81c..0682f81400a 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> @@ -553,6 +553,30 @@ struct fault_load_def : public build_base
>}
>  };
>
> +/* vlenb_def class.  */
> +struct vlenb_def : public function_shape
> +{
> +  void build (function_builder ,
> + const function_group_info ) const override
> +  {
> +auto_vec argument_types;
> +function_instance function_instance (group.base_name, *group.base,
> +*group.shape, 
> group.ops_infos.types[0],
> +group.preds[0], _infos);
> +b.add_unique_function (function_instance, (*group.shape),
> +  long_unsigned_type_node, argument_types);
> +  }
> +
> +  char *get_name (function_builder , const function_instance ,
> + bool overloaded_p) const override
> +  {
> +if (overloaded_p)
> +  

[pushed] c++: local class in nested generic lambda [PR109241]

2023-03-22 Thread Jason Merrill via Gcc-patches
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

In this testcase, the tree walk to look for bare parameter packs was
confused by finding a type with no TREE_BINFO.  But it should be fine that
it's unset; we already checked for unexpanded packs at parse time.

I also tried doing the partial instantiation of the local class, which is
probably the long-term direction we want to go, but for stage 4 let's go
with this safer change.

PR c++/109241

gcc/cp/ChangeLog:

* pt.cc (find_parameter_packs_r): Handle null TREE_BINFO.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/lambda-generic-local-class2.C: New test.
---
 gcc/cp/pt.cc| 12 
 .../g++.dg/cpp1y/lambda-generic-local-class2.C  | 13 +
 2 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class2.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 90bcaa78701..40deedc9ba9 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4069,10 +4069,14 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, 
void* data)
 case TAG_DEFN:
   t = TREE_TYPE (t);
   if (CLASS_TYPE_P (t))
-   /* Local class, need to look through the whole definition.  */
-   for (tree bb : BINFO_BASE_BINFOS (TYPE_BINFO (t)))
- cp_walk_tree (_TYPE (bb), _parameter_packs_r,
-   ppd, ppd->visited);
+   {
+ /* Local class, need to look through the whole definition.
+TYPE_BINFO might be unset for a partial instantiation.  */
+ if (TYPE_BINFO (t))
+   for (tree bb : BINFO_BASE_BINFOS (TYPE_BINFO (t)))
+ cp_walk_tree (_TYPE (bb), _parameter_packs_r,
+   ppd, ppd->visited);
+   }
   else
/* Enum, look at the values.  */
for (tree l = TYPE_VALUES (t); l; l = TREE_CHAIN (l))
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class2.C 
b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class2.C
new file mode 100644
index 000..83856de1f41
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class2.C
@@ -0,0 +1,13 @@
+// PR c++/109241
+// { dg-do compile { target c++14 } }
+// { dg-options "" } no pedantic
+
+void g() {
+  [](auto) {
+[](auto) {
+  ({
+struct A {};
+  });
+};
+  }(1);
+}

base-commit: cd0c433e5faba9a18f64881cd761a53a530aa798
-- 
2.31.1



[PATCH v2 #2/2] [rs6000] adjust return_pc debug attrs

2023-03-22 Thread Alexandre Oliva via Gcc-patches


Some of the rs6000 call patterns, on some ABIs, issue multiple opcodes
out of a single call insn, but the call (bl) or jump (b) is not always
the last opcode in the sequence.

This does not seem to be a problem for exception handling tables, but
the return_pc attribute in the call graph output in dwarf2+ debug
information, that takes the address of a label output right after the
call, does not match the value of the link register even for non-tail
calls.  E.g., with ABI_AIX or ABI_ELFv2, such code as:

  foo ();

outputs:

  bl foo
  nop
 LVL#:
[...]
  .8byte .LVL#  # DW_AT_call_return_pc

but debug info consumers may rely on the return_pc address, and draw
incorrect conclusions from its off-by-4 value.

This patch uses the infrastructure for targets to add an offset to the
label issued after the call_insn to set the call_return_pc attribute,
on rs6000, to account for opcodes issued after actual call opcode as
part of call insns output patterns.

Regstrapped on x86_64-linux-gnu and ppc64-linux-gnu.  Ok to install?


for  gcc/ChangeLog

* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
---
 gcc/config/rs6000/rs6000.cc |   19 +++
 1 file changed, 19 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8e0b0d022db2f..e55117159b270 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1760,6 +1760,9 @@ static const struct attribute_spec 
rs6000_attribute_table[] =
 
 #undef TARGET_UPDATE_IPA_FN_TARGET_INFO
 #define TARGET_UPDATE_IPA_FN_TARGET_INFO rs6000_update_ipa_fn_target_info
+
+#undef TARGET_CALL_OFFSET_RETURN_LABEL
+#define TARGET_CALL_OFFSET_RETURN_LABEL rs6000_call_offset_return_label
 
 
 /* Processor table.  */
@@ -14593,6 +14596,22 @@ rs6000_assemble_integer (rtx x, unsigned int size, int 
aligned_p)
   return default_assemble_integer (x, size, aligned_p);
 }
 
+/* Return the offset to be added to the label output after CALL_INSN
+   to compute the address to be placed in DW_AT_call_return_pc.  */
+
+static int
+rs6000_call_offset_return_label (rtx_insn *call_insn)
+{
+  /* All rs6000 CALL_INSN output patterns start with a b or bl, always
+ a 4-byte instruction, but some output patterns issue other
+ opcodes afterwards.  The return label is issued after the entire
+ call insn, including any such post-call opcodes.  Instead of
+ figuring out which cases need adjustments, we compute the offset
+ back to the address of the call opcode proper, then add the
+ constant 4 bytes, to get the address after that opcode.  */
+  return 4 - get_attr_length (call_insn);
+}
+
 /* Return a template string for assembly to emit when making an
external call.  FUNOP is the call mem argument operand number.  */
 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH v2 #1/2] enable adjustment of return_pc debug attrs

2023-03-22 Thread oliva--- via Gcc-patches


This patch introduces infrastructure for targets to add an offset to
the label issued after the call_insn to set the call_return_pc
attribute.  This will be used on rs6000, that sometimes issues another
instruction after the call proper as part of a call insn.

Regstrapped on x86_64-linux-gnu and ppc64-linux-gnu.  Ok to install?


for  gcc/ChangeLog

* target.def (call_offset_return_label): New hook.
* gcc/doc/tm.texi.in (TARGET_CALL_OFFSET_RETURN_LABEL): Add
placeholder.
* gcc/doc/tm.texi: Rebuild.
* dwarf2out.cc (struct call_arg_loc_node): Record call_insn
instad of call_arg_loc_note.
(add_AT_lbl_id): Add optional offset argument.
(gen_call_site_die): Compute and pass on a return pc offset.
(gen_subprogram_die): Move call_arg_loc_note computation...
(dwarf2out_var_location): ... from here.  Set call_insn.
---
 gcc/doc/tm.texi|7 +++
 gcc/doc/tm.texi.in |2 ++
 gcc/dwarf2out.cc   |   26 +-
 gcc/target.def |9 +
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c4a92a5ebee90..44e4c18ad5c0a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5426,6 +5426,13 @@ except the last are treated as named.
 You need not define this hook if it always returns @code{false}.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_CALL_OFFSET_RETURN_LABEL (rtx_insn 
*@var{call_insn})
+While generating call-site debug info for a CALL insn, or a SEQUENCE
+insn starting with a CALL, this target hook is invoked to compute the
+offset to be added to the debug label emitted after the call to obtain
+the return address that should be recorded as the return PC.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_CALL_ARGS (rtx, @var{tree})
 While generating RTL for a function call, this target hook is invoked once
 for each argument passed to the function, either a register returned by
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 4075e71624c04..68856978fe364 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3785,6 +3785,8 @@ These machine description macros help implement varargs:
 
 @hook TARGET_STRICT_ARGUMENT_NAMING
 
+@hook TARGET_CALL_OFFSET_RETURN_LABEL
+
 @hook TARGET_CALL_ARGS
 
 @hook TARGET_END_CALL_ARGS
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 1711ad2c2da31..d1db918c43900 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -3584,7 +3584,7 @@ typedef struct var_loc_list_def var_loc_list;
 
 /* Call argument location list.  */
 struct GTY ((chain_next ("%h.next"))) call_arg_loc_node {
-  rtx GTY (()) call_arg_loc_note;
+  rtx_insn * GTY (()) call_insn;
   const char * GTY (()) label;
   tree GTY (()) block;
   bool tail_call_p;
@@ -3768,7 +3768,8 @@ static void remove_addr_table_entry (addr_table_entry *);
 static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool);
 static inline rtx AT_addr (dw_attr_node *);
 static void add_AT_symview (dw_die_ref, enum dwarf_attribute, const char *);
-static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *,
+  int = 0);
 static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
 static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
 static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
@@ -5327,14 +5328,17 @@ add_AT_symview (dw_die_ref die, enum dwarf_attribute 
attr_kind,
 
 static inline void
 add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind,
-   const char *lbl_id)
+  const char *lbl_id, int offset)
 {
   dw_attr_node attr;
 
   attr.dw_attr = attr_kind;
   attr.dw_attr_val.val_class = dw_val_class_lbl_id;
   attr.dw_attr_val.val_entry = NULL;
-  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
+  if (!offset)
+attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
+  else
+attr.dw_attr_val.v.val_lbl_id = xasprintf ("%s%+i", lbl_id, offset);
   if (dwarf_split_debug_info)
 attr.dw_attr_val.val_entry
 = add_addr_table_entry (attr.dw_attr_val.v.val_lbl_id,
@@ -23405,7 +23409,9 @@ gen_call_site_die (tree decl, dw_die_ref subr_die,
   if (stmt_die == NULL)
 stmt_die = subr_die;
   die = new_die (dwarf_TAG (DW_TAG_call_site), stmt_die, NULL_TREE);
-  add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc), ca_loc->label);
+  add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc),
+ca_loc->label,
+targetm.calls.call_offset_return_label (ca_loc->call_insn));
   if (ca_loc->tail_call_p)
 add_AT_flag (die, dwarf_AT (DW_AT_call_tail_call), 1);
   if (ca_loc->symbol_ref)
@@ -24092,11 +24098,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
  dw_die_ref die = NULL;
  rtx tloc = NULL_RTX, tlocc = NULL_RTX;
+ rtx call_arg_loc_note
+ 

Re: [PATCH] [rs6000] adjust return_pc debug attrs

2023-03-22 Thread Alexandre Oliva via Gcc-patches
On Mar 13, 2023, Segher Boessenkool  wrote:

> Hi!
> This is stage 1 stuff (or does it fix some regression or such?)

> On Fri, Mar 03, 2023 at 03:00:02PM -0300, Alexandre Oliva wrote:
>> Some of the rs6000 call patterns, on some ABIs, issue multiple opcodes
>> out of a single call insn, but the call (bl) or jump (b) is not always
>> the last opcode in the sequence.

> Yes.  On most architectures you can get multiple machine instructions of
> course (for long calls for example), but on rs6000 (with some ABIs, in
> some circumstances) we generate a nop insn after calls, so that the
> linker has a spot to insert fixup code after calls (typically to restore
> the r2 contents, but it could be anything).

Thanks.  I wasn't entirely sure that the linker would never ever relax
the call sequence, moving the bl to the second instruction in the pair,
or that no 64-bit call variant existed or would come into existence.


> Subtracting 4 from what we currently return is very fragile.

Agreed.

> The actual return address is *always* the address of the branch insn
> plus 4, can't you use that?

Yup, given this piece of knowledge I didn't have, I agree that's a far
saner approach.  I'll post a new version of the patch, now broken up
into rs6000-specific and machine-independent, momentarily.

> (Does the GCC code handle delay slots here, btw?

It does, in that the label is output after the insn sequence.

>> This patch introduces infrastructure for targets to add an offset to
>> the label issued after the call_insn to set the call_return_pc
>> attribute, and uses that on rs6000 to account for nop and l opcodes
>> issued after actual call opcode as part of call insns output patterns.

> What is an "l opcode"?

I have a vague recollection of seeing call sequences ended by loads.
Ah, yes, rs6000_indirect_call_template_1 outputs ld or lwz, depending on
TARGET_64BIT, in both speculate and non-speculate cases after the branch
in ABI_AIX and ABI_ELFv2 calls.  I understand the l in ld and lwz stands
for 'load', and so I meant 'load' updates, but I guess in the context of
calls the 'l' can indeed be misleading.  Anyway, that complexity is gone
thanks to your suggestion.

>> +/* Return the offset to be added to the label output after CALL_INSN
>> +   to compute the address to be placed in DW_AT_call_return_pc.  Some
>> +   call insns output nop or l after bl, so the return address would be
>> +   wrong without this offset.  */
>> +
>> +static int
>> +rs6000_call_offset_return_label (rtx_insn *call_insn)
>> +{
>> +  /* We don't expect SEQUENCEs in this port.  */
>> +  gcc_checking_assert (GET_CODE (call_insn) == CALL_INSN);

> That is not doing what the comment says.

It is.  The documented interface, in the .def file, states that it must
be either a CALL_INSN or a SEQUENCE.

> But, is the assert useful at all anyway, won't the callers have
> checked for this already?

No, the callers would let a SEQUENCE through, if there was one.  But
rs6000 won't ever see one, because there are no delay slots.

My rationale to put it in was to (i) confirm that the case of SEQUENCEs
was considered and needs not be handled in this port, and (ii) should
someone take inspiration from this implementation of the hook for a port
that supported delay slots, it would have to be handled.


>> +  enum attr_call_needs_return_offset cnro
>> += get_attr_call_needs_return_offset (call_insn);
>> +
>> +  if (cnro == CALL_NEEDS_RETURN_OFFSET_NONE)
>> +return 0;

>   if (get_attr_call_needs_return_offset (call_insn)
>   == CALL_NEEDS_RETURN_OFFSET_NONE)
> return 0;

> Shorter, simpler, doesn't need a variable for which you have no good
> name :-)

I happen to not share your subjective preference, but I don't mind
following that style in code you maintain.


>> +  if (rs6000_pcrel_p ())
>> +return 0;

> Why this?  Please look at what actual code is generated, don't assume
> you don't need anything here if we generate pcrel code?

It was not an assumption, I took the conditions from the code, both from
output functions in rs6000.cc and from call patterns in rs6000.md.

Both rs6000_call_template_1 and rs6000_indirect_call_template_1 test for
rs6000_pcrel_p() and then output b or bl opcodes without any subsequence
instruction.  This test mirrors those.



>> +  else if (DEFAULT_ABI == ABI_V4)
>> +return 0;
>> +  else if (DEFAULT_ABI == ABI_DARWIN)
>> +return 0;
>> +  else
>> +return 0;
>> +}

> The first two of these are superfluous.

Of course.  But mirroring the structure of the corresponding code makes
it easier to understand, and to check that the correspondence is there.
But now that style aspect is irrelevant, it's obviated by your suggested
alternate implementation.

Thanks,

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask 

[PATCH] libstdc++: use __bool_constant instead of integral_constant

2023-03-22 Thread Ken Matsui via Gcc-patches
In the type_traits header, both integral_constant and __bool_constant
are used. This patch unifies those usages into __bool_constant.

libstdc++-v3/ChangeLog:

* include/std/type_traits: Use __bool_constant instead of
integral_constant.
---
 libstdc++-v3/include/std/type_traits | 32 ++--
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 2bd607a8b8f..bc6982f9e64 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -578,19 +578,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_enum
   template
 struct is_enum
-: public integral_constant
+: public __bool_constant<__is_enum(_Tp)>
 { };
 
   /// is_union
   template
 struct is_union
-: public integral_constant
+: public __bool_constant<__is_union(_Tp)>
 { };
 
   /// is_class
   template
 struct is_class
-: public integral_constant
+: public __bool_constant<__is_class(_Tp)>
 { };
 
   /// is_function
@@ -784,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_trivial
   template
 struct is_trivial
-: public integral_constant
+: public __bool_constant<__is_trivial(_Tp)>
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -793,7 +793,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_trivially_copyable
   template
 struct is_trivially_copyable
-: public integral_constant
+: public __bool_constant<__is_trivially_copyable(_Tp)>
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -802,7 +802,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_standard_layout
   template
 struct is_standard_layout
-: public integral_constant
+: public __bool_constant<__is_standard_layout(_Tp)>
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -817,7 +817,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct
 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial")
 is_pod
-: public integral_constant
+: public __bool_constant<__is_pod(_Tp)>
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -831,7 +831,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct
 _GLIBCXX17_DEPRECATED
 is_literal_type
-: public integral_constant
+: public __bool_constant<__is_literal_type(_Tp)>
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -840,13 +840,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_empty
   template
 struct is_empty
-: public integral_constant
+: public __bool_constant<__is_empty(_Tp)>
 { };
 
   /// is_polymorphic
   template
 struct is_polymorphic
-: public integral_constant
+: public __bool_constant<__is_polymorphic(_Tp)>
 { };
 
 #if __cplusplus >= 201402L
@@ -855,14 +855,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// @since C++14
   template
 struct is_final
-: public integral_constant
+: public __bool_constant<__is_final(_Tp)>
 { };
 #endif
 
   /// is_abstract
   template
 struct is_abstract
-: public integral_constant
+: public __bool_constant<__is_abstract(_Tp)>
 { };
 
   /// @cond undocumented
@@ -873,7 +873,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 struct __is_signed_helper<_Tp, true>
-: public integral_constant
+: public __bool_constant<_Tp(-1) < _Tp(0)>
 { };
   /// @endcond
 
@@ -1333,7 +1333,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// has_virtual_destructor
   template
 struct has_virtual_destructor
-: public integral_constant
+: public __bool_constant<__has_virtual_destructor(_Tp)>
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1392,7 +1392,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_same
 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME
-: public integral_constant
+: public __bool_constant<__is_same(_Tp, _Up)>
 #else
 : public false_type
 #endif
@@ -1408,7 +1408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_base_of
   template
 struct is_base_of
-: public integral_constant
+: public __bool_constant<__is_base_of(_Base, _Derived)>
 { };
 
 #if __has_builtin(__is_convertible)
-- 
2.40.0



[PATCH v2 2/2] libstdc++: use new built-in trait __is_unsigned

2023-03-22 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.
---
 libstdc++-v3/include/std/type_traits | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 2bd607a8b8f..8d5a05cd0a6 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
-- 
2.40.0



[PATCH v2 1/2] c++: implement __is_unsigned built-in trait

2023-03-22 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.
---
 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 273d15ab097..bc4c3d3ec57 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3747,6 +3747,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 bac593c0094..9f1fff9043e 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 87c2e8a7111..d43e2543490 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12031,6 +12031,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);
 
@@ -12200,6 +12203,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.

[PATCH 2/2] libstdc++: use new built-in trait __is_volatile

2023-03-22 Thread Ken Matsui via Gcc-patches
This patch lets libstdc++ use new built-in trait __is_volatile.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_volatile): Use __is_volatile built-in
trait.
---
 libstdc++-v3/include/std/type_traits | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 2bd607a8b8f..c50c8dba396 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -773,6 +773,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
 
   /// is_volatile
+#if __has_builtin(__is_volatile)
+  template
+struct is_volatile
+: public __bool_constant<__is_volatile(_Tp)>
+{ };
+#else
   template
 struct is_volatile
 : public false_type { };
@@ -780,6 +786,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
-- 
2.40.0



[PATCH 1/2] c++: implement __is_volatile built-in trait

2023-03-22 Thread Ken Matsui via Gcc-patches
This patch implements built-in trait for std::is_volatile.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_VOLATILE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_volatile.
* g++.dg/ext/is_volatile.C: New test.
---
 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_volatile.C   | 19 +++
 5 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 273d15ab097..1da8e8a9780 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3747,6 +3747,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
+case CPTK_IS_VOLATILE:
+  inform (loc, "  %qT is not a volatile 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 bac593c0094..b89b82bb26b 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_VOLATILE, "__is_volatile", 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 99a76e3ed65..70ea0e83abb 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -11993,6 +11993,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_ENUM:
   return type_code1 == ENUMERAL_TYPE;
 
+case CPTK_IS_VOLATILE:
+  return CP_TYPE_VOLATILE_P (type1);
+
 case CPTK_IS_FINAL:
   return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);
 
@@ -12201,6 +12204,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_VOLATILE:
   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..7ad640f141b 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_volatile)
+# error "__has_builtin (__is_volatile) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_volatile.C 
b/gcc/testsuite/g++.dg/ext/is_volatile.C
new file mode 100644
index 000..004e397e5e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_volatile.C
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+// Positive tests.
+SA(__is_volatile(volatile int));
+SA(__is_volatile(const volatile int));
+SA(__is_volatile(vClassType));
+SA(__is_volatile(cvClassType));
+
+// Negative tests.
+SA(!__is_volatile(int));
+SA(!__is_volatile(const int));
+SA(!__is_volatile(ClassType));
+SA(!__is_volatile(cClassType));
-- 
2.40.0



[committed] libstdc++: Fix assigning nullptr to std::atomic> (LWG 3893)

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux. Pushed to trunk.

-- >8 --

LWG voted this to Tentatively Ready recently.

libstdc++-v3/ChangeLog:

* include/bits/shared_ptr_atomic.h (atomic::operator=(nullptr_t)):
Add overload, as per LWG 3893.
* testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc:
Check assignment from nullptr.
---
 libstdc++-v3/include/bits/shared_ptr_atomic.h| 6 ++
 .../20_util/shared_ptr/atomic/atomic_shared_ptr.cc   | 9 +
 2 files changed, 15 insertions(+)

diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h 
b/libstdc++-v3/include/bits/shared_ptr_atomic.h
index d142616f485..2295b48e732 100644
--- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
+++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
@@ -650,6 +650,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   operator=(shared_ptr<_Tp> __desired) noexcept
   { _M_impl.swap(__desired, memory_order_seq_cst); }
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3893. LWG 3661 broke atomic> a; a = nullptr;
+  void
+  operator=(nullptr_t) noexcept
+  { store(nullptr); }
+
   shared_ptr<_Tp>
   exchange(shared_ptr<_Tp> __desired,
   memory_order __o = memory_order_seq_cst) noexcept
diff --git 
a/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc 
b/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc
index a1902745a3e..54cf2621ea1 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc
@@ -145,6 +145,14 @@ test_counting()
   VERIFY( counter == 2 );
 }
 
+void
+test_lwg3893()
+{
+  // LWG 3893. LWG 3661 broke atomic> a; a = nullptr;
+  std::atomic> a;
+  a = nullptr;
+}
+
 int
 main()
 {
@@ -152,4 +160,5 @@ main()
   test_atomic_shared_ptr();
   test_wait_notify();
   test_counting();
+  test_lwg3893();
 }
-- 
2.39.2



Re: [PATCH v2 1/2] c++: implement __is_unsigned built-in trait

2023-03-22 Thread Ken Matsui via Gcc-patches
It seems I missed including Jonathan in the new patch. Could you
please take a look?

On Tue, Mar 21, 2023 at 10:07 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.
> ---
>  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 273d15ab097..bc4c3d3ec57 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -3747,6 +3747,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 bac593c0094..9f1fff9043e 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 87c2e8a7111..d43e2543490 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12031,6 +12031,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);
>
> @@ -12200,6 +12203,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);
> 

Re: [PATCH] testsuite: always use UTF-8 in scan-sarif-file[-not] [PR105959]

2023-03-22 Thread Mike Stump via Gcc-patches
On Mar 20, 2023, at 3:06 PM, David Malcolm via Gcc-patches 
 wrote:
> 
> c-c++-common/diagnostic-format-sarif-file-4.c is a test case for
> quoting non-ASCII source code in a SARIF diagnostic log.
> 
> The SARIF standard mandates that .sarif files are UTF-8 encoded.
> 
> PR testsuite/105959 notes that the test case fails when the system
> encoding is not UTF-8, such as when the "make" invocation is prefixed
> with LC_ALL=C, whereas it works with in a UTF-8-locale.
> 
> The root cause is that dg-scan opens the file for reading using the
> "system" encoding; I believe it is falling back to treating all files as
> effectively ISO 8859-1 in a non-UTF-8 locale.
> 
> This patch fixes things by adding a mechanism to dg-scan to allow
> callers to (optionally) specify an encoding to use when reading the
> file, and updating scan-sarif-file (and the -not variant) to always
> use UTF-8 when calling dg-scan, fixing the test case with LC_ALL=C.

> OK for trunk?

Ok.

Go patch committed: Add missing Slice_info_expression::do_traverse

2023-03-22 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend adds the missing
Slice_info_expression::do_traverse method.  Lack of the method caused
https://go.dev/issue/59169.  The test case is
https://go.dev/cl/478217.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline and GCC 12 branch.

Ian
187edaf5e88b548db4e6790b723be1f8d1dab2d5
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 4a1a4c8c021..8c8025dec2e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-8c786f716c58d7973623c2b9293e2ad360877817
+9ffd6e679ff0e3a908d0ec2ed5c6efa1de827c3f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index a1e3733aa1d..3d7e78711bd 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -4410,6 +4410,10 @@ class Slice_info_expression : public Expression
   { return this->slice_info_; }
 
  protected:
+  int
+  do_traverse(Traverse* traverse)
+  { return Expression::traverse(>slice_, traverse); }
+
   Type*
   do_type();
 


Re: [committed] libstdc++: Add missing __cpp_lib_format macro to

2023-03-22 Thread Jonathan Wakely via Gcc-patches
On Wed, 22 Mar 2023 at 19:46, Jonathan Wakely  wrote:

>
>
> On Wed, 22 Mar 2023 at 17:59, Daniel Krügler 
> wrote:
>
>> Am Mi., 22. März 2023 um 18:53 Uhr schrieb Jonathan Wakely via
>> Libstdc++ :
>> >
>> > Tested powerpc64le-linux, pushed to trunk.
>> >
>> > -- >8--
>> >
>> > libstdc++-v3/ChangeLog:
>> >
>> > * include/std/version (__cpp_lib_format): Define.
>> > * testsuite/std/format/functions/format.cc: Check it.
>> > ---
>> >  libstdc++-v3/include/std/version  |  1 +
>> >  .../testsuite/std/format/functions/format.cc  | 15 +++
>> >  2 files changed, 16 insertions(+)
>> >
>> > diff --git a/libstdc++-v3/include/std/version
>> b/libstdc++-v3/include/std/version
>> > index 25ebfc3e512..a19c39c6cdd 100644
>> > --- a/libstdc++-v3/include/std/version
>> > +++ b/libstdc++-v3/include/std/version
>> > @@ -277,6 +277,7 @@
>> >  #define __cpp_lib_constexpr_utility 201811L
>> >  #define __cpp_lib_constexpr_vector 201907L
>> >  #define __cpp_lib_erase_if 202002L
>> > +#define __cpp_lib_format 202106L
>>
>> Shouldn't the value be 202207L? (This of-course of your conforming
>> completeness)
>>
>>
> Well spotted!
>
> The historical values listed in SD-6 are included in a comment in :
>
> // 201907 Text Formatting, Integration of chrono, printf corner cases.
> // 202106 std::format improvements.
> // 202110 Fixing locale handling in chrono formatters, generator-like
> types.
> // 202207 Encodings in localized formatting of chrono, basic-format-string.
> #define __cpp_lib_format 202106L
>
> The libstdc++ support only got as far as 202106 so far :-)
>
> (We actually do implement the support for generator-like types from
> P2418R2 and the std::basic_format_string change from P2508R1, but can't
> bump the value to 202207 until the other changes are supported too.)
>
> I might still find time to finish P2372R3 and P2419R2 for GCC 13, but no
> promises.
>

Hmm, actually maybe I already did all of P2372R3 as part of the 
formatting, so it should be 202110. And for P2419R2 we could say that the
implementation-defined set of locales is empty ... but that's pretty poor
QoI.

There are also some more changes in C++23 (P2572 and P2675) which aren't
done yet.


Re: [committed] libstdc++: Add missing __cpp_lib_format macro to

2023-03-22 Thread Jonathan Wakely via Gcc-patches
On Wed, 22 Mar 2023 at 17:59, Daniel Krügler 
wrote:

> Am Mi., 22. März 2023 um 18:53 Uhr schrieb Jonathan Wakely via
> Libstdc++ :
> >
> > Tested powerpc64le-linux, pushed to trunk.
> >
> > -- >8--
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/std/version (__cpp_lib_format): Define.
> > * testsuite/std/format/functions/format.cc: Check it.
> > ---
> >  libstdc++-v3/include/std/version  |  1 +
> >  .../testsuite/std/format/functions/format.cc  | 15 +++
> >  2 files changed, 16 insertions(+)
> >
> > diff --git a/libstdc++-v3/include/std/version
> b/libstdc++-v3/include/std/version
> > index 25ebfc3e512..a19c39c6cdd 100644
> > --- a/libstdc++-v3/include/std/version
> > +++ b/libstdc++-v3/include/std/version
> > @@ -277,6 +277,7 @@
> >  #define __cpp_lib_constexpr_utility 201811L
> >  #define __cpp_lib_constexpr_vector 201907L
> >  #define __cpp_lib_erase_if 202002L
> > +#define __cpp_lib_format 202106L
>
> Shouldn't the value be 202207L? (This of-course of your conforming
> completeness)
>
>
Well spotted!

The historical values listed in SD-6 are included in a comment in :

// 201907 Text Formatting, Integration of chrono, printf corner cases.
// 202106 std::format improvements.
// 202110 Fixing locale handling in chrono formatters, generator-like types.
// 202207 Encodings in localized formatting of chrono, basic-format-string.
#define __cpp_lib_format 202106L

The libstdc++ support only got as far as 202106 so far :-)

(We actually do implement the support for generator-like types from P2418R2
and the std::basic_format_string change from P2508R1, but can't bump the
value to 202207 until the other changes are supported too.)

I might still find time to finish P2372R3 and P2419R2 for GCC 13, but no
promises.


[pushed] c++: array bound partial ordering [PR108390]

2023-03-22 Thread Jason Merrill via Gcc-patches
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

fold_convert doesn't work with a dependent argument, and problematically
differed from the corresponding fold+build_nop further down in the
function.  So change it to match.

PR c++/108390

gcc/cp/ChangeLog:

* pt.cc (unify): Use fold of build_nop instead of fold_convert.

gcc/testsuite/ChangeLog:

* g++.dg/template/partial-order3.C: New test.
---
 gcc/cp/pt.cc   | 8 +---
 gcc/testsuite/g++.dg/template/partial-order3.C | 6 ++
 2 files changed, 11 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/partial-order3.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 056b8c7abad..90bcaa78701 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -24635,8 +24635,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  if ((strict & UNIFY_ALLOW_INTEGER)
  && TREE_TYPE (targ) && TREE_TYPE (arg)
  && CP_INTEGRAL_TYPE_P (TREE_TYPE (targ)))
-   /* We're deducing from an array bound, the type doesn't matter.  */
-   arg = fold_convert (TREE_TYPE (targ), arg);
+   /* We're deducing from an array bound, the type doesn't matter.
+  This conversion should match the one below.  */
+   arg = fold (build_nop (TREE_TYPE (targ), arg));
  int x = !cp_tree_equal (targ, arg);
  if (x)
unify_inconsistency (explain_p, parm, targ, arg);
@@ -24684,7 +24685,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
   && CP_INTEGRAL_TYPE_P (tparm))
/* Convert the ARG to the type of PARM; the deduced non-type
   template argument must exactly match the types of the
-  corresponding parameter.  */
+  corresponding parameter.  This conversion should match the
+  one above.  */
arg = fold (build_nop (tparm, arg));
   else if (uses_template_parms (tparm))
{
diff --git a/gcc/testsuite/g++.dg/template/partial-order3.C 
b/gcc/testsuite/g++.dg/template/partial-order3.C
new file mode 100644
index 000..154505321bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/partial-order3.C
@@ -0,0 +1,6 @@
+// PR c++/108390
+// { dg-do compile { target c++11 } }
+
+template  long f(int(*)[t], T(*)[t]);
+template int f(int(*)[i], T(*)[i]) = delete;
+int n = f(0, 0);

base-commit: 3e791f45ded89626bc1f9f8013728f6e035801b2
-- 
2.31.1



[PATCH, committed] Fortran: improve checking of FINAL subroutine arguments [PR104572]

2023-03-22 Thread Harald Anlauf via Gcc-patches
Dear all,

I've committed the attached simple patch after discussion with
Steve (see PR).  We need to reject alternate return arguments
of FINAL subroutines.

Regtested on x86_64-pc-linux-gnu.

Thanks,
Harald

From 3e791f45ded89626bc1f9f8013728f6e035801b2 Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Wed, 22 Mar 2023 19:20:41 +0100
Subject: [PATCH] Fortran: improve checking of FINAL subroutine arguments
 [PR104572]

gcc/fortran/ChangeLog:

	PR fortran/104572
	* resolve.cc (gfc_resolve_finalizers): Argument of a FINAL subroutine
	cannot be an alternate return.

gcc/testsuite/ChangeLog:

	PR fortran/104572
	* gfortran.dg/pr104572.f90: New test.

Co-authored-by: Steven G. Kargl 
---
 gcc/fortran/resolve.cc |  7 +++
 gcc/testsuite/gfortran.dg/pr104572.f90 | 14 ++
 2 files changed, 21 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/pr104572.f90

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 1a03e458d99..f6ec76acb0b 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -13986,6 +13986,13 @@ gfc_resolve_finalizers (gfc_symbol* derived, bool *finalizable)
 	}
   arg = dummy_args->sym;

+  if (!arg)
+	{
+	  gfc_error ("Argument of FINAL procedure at %L must be of type %qs",
+		 >proc_sym->declared_at, derived->name);
+	  goto error;
+	}
+
   if (arg->as && arg->as->type == AS_ASSUMED_RANK
 	  && ((list != derived->f2k_derived->finalizers) || list->next))
 	{
diff --git a/gcc/testsuite/gfortran.dg/pr104572.f90 b/gcc/testsuite/gfortran.dg/pr104572.f90
new file mode 100644
index 000..59fd688d798
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104572.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-additional-options "-w" }
+! PR fortran/104572 - ICE in gfc_resolve_finalizers
+! Contributed by G. Steinmetz
+
+module m
+  type t
+   contains
+ final :: s
+  end type
+contains
+  subroutine s(*) ! { dg-error "Argument of FINAL procedure" }
+  end
+end
--
2.35.3



Re: [PATCH] Remove TARGET_GEN_MEMSET_SCRATCH_RTX since it's not used anymore.

2023-03-22 Thread H.J. Lu via Gcc-patches
On Wed, Mar 22, 2023 at 3:19 AM Richard Biener
 wrote:
>
> On Wed, Mar 22, 2023 at 8:07 AM Uros Bizjak  wrote:
> >
> > On Wed, Mar 22, 2023 at 3:59 AM liuhongt  wrote:
> > >
> > > The target hook is only used by i386, and the current definition is
> > > same as default gen_reg_rtx. So there's no need for this target hook.
> > >
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > > Ok for trunk(or GCC14)?
> > >
> > > gcc/ChangeLog:
> > >
> > > * builtins.cc (builtin_memset_read_str): Replace
> > > targetm.gen_memset_scratch_rtx with gen_reg_rtx.
> > > (builtin_memset_gen_str): Ditto.
> > > * config/i386/i386-expand.cc
> > > (ix86_convert_const_wide_int_to_broadcast): Replace
> > > ix86_gen_scratch_sse_rtx with gen_reg_rtx.
> > > (ix86_expand_vector_move): Ditto.
> > > * config/i386/i386-protos.h (ix86_gen_scratch_sse_rtx):
> > > Removed.
> > > * config/i386/i386.cc (ix86_gen_scratch_sse_rtx): Removed.
> > > (TARGET_GEN_MEMSET_SCRATCH_RTX): Removed.
> > > * doc/tm.texi: Remove TARGET_GEN_MEMSET_SCRATCH_RTX.
> > > * doc/tm.texi.in: Ditto.
> > > * target.def: Ditto.
> >
> > Looks trivial enough for gcc13, so OK for x86 part.
> >
> > Needs also OK from a middle-end reviewer.
>
> Is/was the code ever exercised for non-x86?  HJ, what was the reason to
> abstract this?
>
> OK if HJ thinks it was really unnecessary abstraction unlikely to be
> required by another target.

OK with me.

Thanks.

> Richard.
>
> > Thanks,
> > Uros.
> >
> > > ---
> > >  gcc/builtins.cc|  4 ++--
> > >  gcc/config/i386/i386-expand.cc |  6 +++---
> > >  gcc/config/i386/i386-protos.h  |  2 --
> > >  gcc/config/i386/i386.cc| 12 
> > >  gcc/doc/tm.texi|  7 ---
> > >  gcc/doc/tm.texi.in |  2 --
> > >  gcc/target.def |  9 -
> > >  7 files changed, 5 insertions(+), 37 deletions(-)
> > >
> > > diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> > > index 90246e214d6..8026e2001b7 100644
> > > --- a/gcc/builtins.cc
> > > +++ b/gcc/builtins.cc
> > > @@ -4212,7 +4212,7 @@ builtin_memset_read_str (void *data, void *prev,
> > > return const_vec;
> > >
> > >/* Use the move expander with CONST_VECTOR.  */
> > > -  target = targetm.gen_memset_scratch_rtx (mode);
> > > +  target = gen_reg_rtx (mode);
> > >emit_move_insn (target, const_vec);
> > >return target;
> > >  }
> > > @@ -4256,7 +4256,7 @@ builtin_memset_gen_str (void *data, void *prev,
> > >  the memset expander.  */
> > >insn_code icode = optab_handler (vec_duplicate_optab, mode);
> > >
> > > -  target = targetm.gen_memset_scratch_rtx (mode);
> > > +  target = gen_reg_rtx (mode);
> > >class expand_operand ops[2];
> > >create_output_operand ([0], target, mode);
> > >create_input_operand ([1], (rtx) data, QImode);
> > > diff --git a/gcc/config/i386/i386-expand.cc 
> > > b/gcc/config/i386/i386-expand.cc
> > > index c1300dc4e26..1e3ce4b7c3f 100644
> > > --- a/gcc/config/i386/i386-expand.cc
> > > +++ b/gcc/config/i386/i386-expand.cc
> > > @@ -338,7 +338,7 @@ ix86_convert_const_wide_int_to_broadcast 
> > > (machine_mode mode, rtx op)
> > >machine_mode vector_mode;
> > >if (!mode_for_vector (broadcast_mode, nunits).exists (_mode))
> > >  gcc_unreachable ();
> > > -  rtx target = ix86_gen_scratch_sse_rtx (vector_mode);
> > > +  rtx target = gen_reg_rtx (vector_mode);
> > >bool ok = ix86_expand_vector_init_duplicate (false, vector_mode,
> > >target,
> > >GEN_INT (val_broadcast));
> > > @@ -686,7 +686,7 @@ ix86_expand_vector_move (machine_mode mode, rtx 
> > > operands[])
> > >if (!register_operand (op0, mode)
> > >   && !register_operand (op1, mode))
> > > {
> > > - rtx scratch = ix86_gen_scratch_sse_rtx (mode);
> > > + rtx scratch = gen_reg_rtx (mode);
> > >   emit_move_insn (scratch, op1);
> > >   op1 = scratch;
> > > }
> > > @@ -728,7 +728,7 @@ ix86_expand_vector_move (machine_mode mode, rtx 
> > > operands[])
> > >&& !register_operand (op0, mode)
> > >&& !register_operand (op1, mode))
> > >  {
> > > -  rtx tmp = ix86_gen_scratch_sse_rtx (GET_MODE (op0));
> > > +  rtx tmp = gen_reg_rtx (GET_MODE (op0));
> > >emit_move_insn (tmp, op1);
> > >emit_move_insn (op0, tmp);
> > >return;
> > > diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> > > index bfb2198265a..71ae95ffef7 100644
> > > --- a/gcc/config/i386/i386-protos.h
> > > +++ b/gcc/config/i386/i386-protos.h
> > > @@ -50,8 +50,6 @@ extern void ix86_reset_previous_fndecl (void);
> > >
> > >  extern bool ix86_using_red_zone (void);
> > >
> > > -extern rtx ix86_gen_scratch_sse_rtx (machine_mode);
> > > 

Re: [committed] libstdc++: Add missing __cpp_lib_format macro to

2023-03-22 Thread Daniel Krügler via Gcc-patches
Am Mi., 22. März 2023 um 18:53 Uhr schrieb Jonathan Wakely via
Libstdc++ :
>
> Tested powerpc64le-linux, pushed to trunk.
>
> -- >8--
>
> libstdc++-v3/ChangeLog:
>
> * include/std/version (__cpp_lib_format): Define.
> * testsuite/std/format/functions/format.cc: Check it.
> ---
>  libstdc++-v3/include/std/version  |  1 +
>  .../testsuite/std/format/functions/format.cc  | 15 +++
>  2 files changed, 16 insertions(+)
>
> diff --git a/libstdc++-v3/include/std/version 
> b/libstdc++-v3/include/std/version
> index 25ebfc3e512..a19c39c6cdd 100644
> --- a/libstdc++-v3/include/std/version
> +++ b/libstdc++-v3/include/std/version
> @@ -277,6 +277,7 @@
>  #define __cpp_lib_constexpr_utility 201811L
>  #define __cpp_lib_constexpr_vector 201907L
>  #define __cpp_lib_erase_if 202002L
> +#define __cpp_lib_format 202106L

Shouldn't the value be 202207L? (This of-course of your conforming completeness)

Thanks,

- Daniel


[committed] libstdc++: Remove std::formatter specialization

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

This was approved in Issaquah as LWG 3833.

libstdc++-v3/ChangeLog:

* include/std/format (formatter): Do not
define partial speclialization, as per LWG 3833.
* testsuite/std/format/formatter/requirements.cc: Check it.
---
 libstdc++-v3/include/std/format   | 22 ---
 .../std/format/formatter/requirements.cc  |  9 
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 0e40bce5c15..72b6b450ad1 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1882,28 +1882,6 @@ namespace __format
   __format::__formatter_str<_CharT> _M_f;
 };
 
-  template<__format::__char _CharT, size_t _Nm>
-struct formatter
-{
-  formatter() = default;
-
-  [[__gnu__::__always_inline__]]
-  constexpr typename basic_format_parse_context<_CharT>::iterator
-  parse(basic_format_parse_context<_CharT>& __pc)
-  { return _M_f.parse(__pc); }
-
-  template
-   typename basic_format_context<_Out, _CharT>::iterator
-   format(const _CharT (&__u)[_Nm],
-  basic_format_context<_Out, _CharT>& __fc) const
-   { return _M_f.format({__u, _Nm}, __fc); }
-
-  constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); }
-
-private:
-  __format::__formatter_str<_CharT> _M_f;
-};
-
   template
 struct formatter, char>
 {
diff --git a/libstdc++-v3/testsuite/std/format/formatter/requirements.cc 
b/libstdc++-v3/testsuite/std/format/formatter/requirements.cc
index 3bff8bdbd5d..7d95f7fafe9 100644
--- a/libstdc++-v3/testsuite/std/format/formatter/requirements.cc
+++ b/libstdc++-v3/testsuite/std/format/formatter/requirements.cc
@@ -51,6 +51,15 @@ test_specializations() // [format.formatter.spec]
   static_assert( ! std::is_move_constructible_v );
   static_assert( ! std::is_copy_assignable_v );
   static_assert( ! std::is_move_assignable_v );
+
+  // LWG 3833. Remove specialization
+  // template struct formatter
+  using Farr = std::format_context::formatter_type;
+  static_assert( ! std::is_default_constructible_v );
+  static_assert( ! std::is_copy_constructible_v );
+  static_assert( ! std::is_move_constructible_v );
+  static_assert( ! std::is_copy_assignable_v );
+  static_assert( ! std::is_move_assignable_v );
 }
 
 int main()
-- 
2.39.2



[committed] libstdc++: Define __cpp_lib_constexpr_algorithms in (LWG 3792)

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

We actually defined this macro in  at one point, but I removed
it in r10-7901-g2025db692e9ed1.

libstdc++-v3/ChangeLog:

* include/std/utility (__cpp_lib_constexpr_algorithms): Define,
as per LWG 3792.
* testsuite/20_util/exchange/constexpr.cc: Check for it.
---
 libstdc++-v3/include/std/utility | 4 
 libstdc++-v3/testsuite/20_util/exchange/constexpr.cc | 6 ++
 2 files changed, 10 insertions(+)

diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 43d8765228c..006b19c00fc 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -86,6 +86,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201402L
 #define __cpp_lib_exchange_function 201304L
 
+#if __cplusplus > 201703L
+# define __cpp_lib_constexpr_algorithms 201806L
+#endif
+
   /// Assign @p __new_val to @p __obj and return its previous value.
   template 
 _GLIBCXX20_CONSTEXPR
diff --git a/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc 
b/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc
index 6c130f772f8..2ec13044681 100644
--- a/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc
+++ b/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc
@@ -20,6 +20,12 @@
 
 #include 
 
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature test macro for constexpr std::exchange is missing in 
"
+#elif __cpp_lib_constexpr_algorithms < 201806L
+# error "Feature test macro for constexpr std::exchange has wrong value in 
"
+#endif
+
 constexpr bool
 test()
 {
-- 
2.39.2



[committed] libstdc++: Add missing __cpp_lib_format macro to

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

libstdc++-v3/ChangeLog:

* include/std/version (__cpp_lib_format): Define.
* testsuite/std/format/functions/format.cc: Check it.
---
 libstdc++-v3/include/std/version  |  1 +
 .../testsuite/std/format/functions/format.cc  | 15 +++
 2 files changed, 16 insertions(+)

diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 25ebfc3e512..a19c39c6cdd 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -277,6 +277,7 @@
 #define __cpp_lib_constexpr_utility 201811L
 #define __cpp_lib_constexpr_vector 201907L
 #define __cpp_lib_erase_if 202002L
+#define __cpp_lib_format 202106L
 #define __cpp_lib_generic_unordered_lookup 201811L
 #define __cpp_lib_interpolate 201902L
 #ifdef _GLIBCXX_HAS_GTHREADS
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc 
b/libstdc++-v3/testsuite/std/format/functions/format.cc
index 7a155208a48..2a1b1560394 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -2,6 +2,21 @@
 // { dg-do run { target c++20 } }
 
 #include 
+
+#ifndef __cpp_lib_format
+# error "Feature test macro for std::format is missing in "
+#elif __cpp_lib_format < 202106L
+# error "Feature test macro for std::format has wrong value in "
+#endif
+
+#undef __cpp_lib_format
+#include 
+#ifndef __cpp_lib_format
+# error "Feature test macro for std::format is missing in "
+#elif __cpp_lib_format < 202106L
+# error "Feature test macro for std::format has wrong value in "
+#endif
+
 #include 
 #include 
 #include 
-- 
2.39.2



[committed] libstdc++: Make std::istream_iterator copy ctor constexpr (LWG 3600)

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

As explained in LWG 3600, we never implemented a C++0x change that made
the copy constructor of std::istream_iterator defined as defaulted. That
would be an ABI break, so the resolution of LWG 3600 is to not require
it to be trivial, but just constexpr and conditionally noexcept. This
applies that resolution.

libstdc++-v3/ChangeLog:

* include/bits/stream_iterator.h (istream_iterator): Add
constexpr to copy constructor, as per LWG 3600.
* testsuite/24_iterators/istream_iterator/cons/constexpr.cc:
Check copy construction.
---
 libstdc++-v3/include/bits/stream_iterator.h  | 1 +
 .../24_iterators/istream_iterator/cons/constexpr.cc  | 5 +
 2 files changed, 6 insertions(+)

diff --git a/libstdc++-v3/include/bits/stream_iterator.h 
b/libstdc++-v3/include/bits/stream_iterator.h
index 298d4406afd..9dc4a550be6 100644
--- a/libstdc++-v3/include/bits/stream_iterator.h
+++ b/libstdc++-v3/include/bits/stream_iterator.h
@@ -80,6 +80,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   : _M_stream(std::__addressof(__s)), _M_ok(true)
   { _M_read(); }
 
+  _GLIBCXX_CONSTEXPR
   istream_iterator(const istream_iterator& __obj)
   _GLIBCXX_NOEXCEPT_IF(is_nothrow_copy_constructible<_Tp>::value)
   : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
diff --git 
a/libstdc++-v3/testsuite/24_iterators/istream_iterator/cons/constexpr.cc 
b/libstdc++-v3/testsuite/24_iterators/istream_iterator/cons/constexpr.cc
index 824cd93ecbe..95fda572d8e 100644
--- a/libstdc++-v3/testsuite/24_iterators/istream_iterator/cons/constexpr.cc
+++ b/libstdc++-v3/testsuite/24_iterators/istream_iterator/cons/constexpr.cc
@@ -24,5 +24,10 @@ int main()
 {
   __gnu_test::constexpr_default_constructible test;
   test.operator()>();
+
+  // LWG 3600. Making istream_iterator copy constructor trivial is an ABI break
+  __gnu_test::constexpr_single_value_constructible test2;
+  test2.operator(), std::istream_iterator>();
+
   return 0;
 }
-- 
2.39.2



[committed] libstdc++: Use rvalues in std::string::resize_and_overwrite (LWG 3645)

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

Previously the C++23 draft required that the callback arguments were
lvalues, which was overvable by the callback. LWG 3645 removes that
overspecification, so we can pass rvalues and the user can't modify
our local variables. I've used auto(p) to produce rvalues, which is only
supported since Clang 15, but I think that's OK for a C++23 feature.

While making this change I noticed that we weren't correctly enforcing
the requirement that the callback returns an integer-like type. Add
better assertions for the type and value.

libstdc++-v3/ChangeLog:

* include/bits/basic_string.tcc (basic_string::resize_and_overwrite):
Pass rvalues to the callback, as now allowed by LWG 3645.
Enforce preconditions on the return value.
* 
testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc:
Adjust.
---
 libstdc++-v3/include/bits/basic_string.tcc   | 9 ++---
 .../basic_string/capacity/char/resize_and_overwrite.cc   | 8 +---
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/bits/basic_string.tcc 
b/libstdc++-v3/include/bits/basic_string.tcc
index cfbc78a3108..99fdbeee5ad 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -592,9 +592,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_type _M_r;
   };
   _Terminator __term{this};
-  const size_type __n2 [[maybe_unused]] = __n;
-  __term._M_r = std::move(__op)(__p, __n);
-  _GLIBCXX_DEBUG_ASSERT(__term._M_r >= 0 && __term._M_r <= __n2);
+  auto __r = std::move(__op)(auto(__p), auto(__n));
+  static_assert(ranges::__detail::__is_integer_like);
+  _GLIBCXX_DEBUG_ASSERT(__r >= 0 && __r <= __n);
+  __term._M_r = size_type(__r);
+  if (__term._M_r > __n)
+   __builtin_unreachable();
 }
 #endif // C++23
 
diff --git 
a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
 
b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
index a336b55f4a1..f716030dad7 100644
--- 
a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
+++ 
b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc
@@ -84,9 +84,11 @@ test03()
   VERIFY( s == std::string(42, 'a') );
   VERIFY( s[42] == '\0' );
 
-  s.resize_and_overwrite(0, [](auto&& p, auto&& n) {
-static_assert( std::is_same_v );
-static_assert( std::is_same_v );
+  s.resize_and_overwrite(0, [](auto p, auto n) {
+// N.B. these requirements were relaxed by LWG 3645:
+// resize_and_overwrite is overspecified to call its callback with lvalues
+static_assert( std::is_same_v );
+static_assert( std::is_same_v );
 return 0;
   });
 }
-- 
2.39.2



[committed] libstdc++: Add allocator-extended constructors to std::match_results (LWG 2195)

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

This was approved in Issaquah last month.

libstdc++-v3/ChangeLog:

* include/bits/regex.h (match_results): Add allocator-extended
copy and move constructors, as per LWG 2195.
* testsuite/28_regex/match_results/ctors/char/alloc.cc: New test.
---
 libstdc++-v3/include/bits/regex.h | 10 
 .../match_results/ctors/char/alloc.cc | 56 +++
 2 files changed, 66 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/28_regex/match_results/ctors/char/alloc.cc

diff --git a/libstdc++-v3/include/bits/regex.h 
b/libstdc++-v3/include/bits/regex.h
index 386f4be9f4a..79903fad1e5 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -1826,6 +1826,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
   ~match_results() = default;
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2195. Missing constructors for match_results
+
+  match_results(const match_results& __m, const _Alloc& __a)
+  : _Base_type(__m, __a) { }
+
+  match_results(match_results&& __m, const _Alloc& __a)
+  noexcept(noexcept(_Base_type(std::move(__m), __a)))
+  : _Base_type(std::move(__m), __a) { }
+
   ///@}
 
   // 28.10.2, state:
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/alloc.cc 
b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/alloc.cc
new file mode 100644
index 000..bb5e7a91bd7
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/alloc.cc
@@ -0,0 +1,56 @@
+// { dg-do run { target c++11 } }
+
+#include 
+#include 
+#include 
+
+// LWG 2195. Missing constructors for match_results
+
+void
+test01()
+{
+  using Alloc = std::cmatch::allocator_type;
+  std::cmatch m1;
+  std::cmatch m2(m1, m1.get_allocator());
+  VERIFY( m2 == m1 );
+
+  static_assert( ! std::is_nothrow_constructible(),
+"Allocator-extended copy ctor is potentially-throwing" );
+
+  std::cmatch m3(std::move(m1), m2.get_allocator());
+  VERIFY( m3 == m2 );
+
+  // Libstdc++ extension:
+  static_assert( std::is_nothrow_constructible(),
+"Allocator-extended move ctor is non-throwing" );
+}
+
+void
+test02()
+{
+  using Alloc = __gnu_test::uneq_allocator;
+  using MR = std::match_results;
+
+  MR m1(Alloc(1));
+  MR m2(m1, Alloc(2));
+  VERIFY( m2 == m1 );
+
+  static_assert( ! std::is_nothrow_constructible(),
+"Allocator-extended copy ctor is potentially-throwing" );
+
+  MR m3(std::move(m1), Alloc(3));
+  VERIFY( m3 == m2 );
+
+  static_assert( ! std::is_nothrow_constructible(),
+"Allocator-extended move ctor is potentially-throwing" );
+}
+
+int main()
+{
+  test01();
+  test02();
+}
-- 
2.39.2



[committed] libstdc++: Add comment to (LWG 3720)

2023-03-22 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8--

libstdc++-v3/ChangeLog:

* include/std/format: Add a comment noting that the resolution
of LWG 3720 has been applied..
---
 libstdc++-v3/include/std/format | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index b1e627048de..0e40bce5c15 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3119,6 +3119,8 @@ namespace __format
// 3721. Allow an arg-id with a value of zero for width
else if constexpr (sizeof(_Tp) <= sizeof(long long))
  {
+   // _GLIBCXX_RESOLVE_LIB_DEFECTS
+   // 3720. Restrict the valid types of arg-id for width and precision
if constexpr (__is_unsigned_integer<_Tp>::value)
  return __arg;
else if constexpr (__is_signed_integer<_Tp>::value)
-- 
2.39.2



[pushed] [PR109137] LRA: Do not repeat inheritance and live range splitting in case of asm error

2023-03-22 Thread Vladimir Makarov via Gcc-patches

The following patch solves

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109137

The patch was successfully bootstrapped and tested on x86-64.

commit 81d762cbec9685c2f2571da21d48f42c42eff33b
Author: Vladimir N. Makarov 
Date:   Wed Mar 22 12:33:11 2023 -0400

LRA: Do not repeat inheritance and live range splitting in case of asm error

LRA was trying to do live range splitting again and again as there were
no enough regs for asm.  This patch solves the problem.

PR target/109137

gcc/ChangeLog:

* lra.cc (lra): Do not repeat inheritance and live range splitting
when asm error is found.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr109137.c: New.

diff --git a/gcc/lra.cc b/gcc/lra.cc
index f7fdd601e71..eb3ee1f8b63 100644
--- a/gcc/lra.cc
+++ b/gcc/lra.cc
@@ -2453,7 +2453,7 @@ lra (FILE *f)
 		  lra_hard_reg_split_p = true;
 		}
 	}
-	  while (fails_p);
+	  while (fails_p && !lra_asm_error_p);
 	  if (! live_p) {
 	/* We need the correct reg notes for work of constraint sub-pass.  */
 	lra_create_live_ranges (true, true);
diff --git a/gcc/testsuite/gcc.target/i386/pr109137.c b/gcc/testsuite/gcc.target/i386/pr109137.c
new file mode 100644
index 000..ffd8e8c574b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr109137.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-m32 -O3 -march=znver1 -fPIC -mfpmath=sse -w" } */
+#include 
+typedef struct {
+  char bytestream_end;
+} CABACContext;
+int get_cabac___trans_tmp_3, get_cabac_tmp, get_cabac_c,
+decode_cabac_mb_intra4x4_pred_mode_mode, ff_h264_decode_mb_cabac_h_0,
+ff_h264_decode_mb_cabac_bit;
+typedef struct {
+  char intra4x4_pred_mode_cache[2];
+} H264SliceContext;
+H264SliceContext ff_h264_decode_mb_cabac_sl;
+void ff_h264_decode_mb_cabac(void) {
+  memset((void*)ff_h264_decode_mb_cabac_h_0, 6, 48);
+  int i;
+  for (;; i++) {
+__asm__(""/* { dg-error "'asm' operand has impossible constraints" } */
+: "="(ff_h264_decode_mb_cabac_bit), "="(get_cabac_c),
+  "="(get_cabac_c), "="(get_cabac_tmp)
+: "r"(get_cabac___trans_tmp_3),
+  "r"(__builtin_offsetof(CABACContext, bytestream_end))
+: "ecx");
+ff_h264_decode_mb_cabac_sl.intra4x4_pred_mode_cache[i] =
+decode_cabac_mb_intra4x4_pred_mode_mode;
+  }
+}
+


Re: [PATCH] tree-optimization/109237 - last_stmt is possibly slow

2023-03-22 Thread Bernhard Reutner-Fischer via Gcc-patches
On 22 March 2023 13:29:52 CET, Richard Biener via Gcc-patches 
 wrote:

>The alternative would be to change last_stmt, explicitely introducing
>last_nondebug_stmt.  I remember we chickened out and made last_stmt
>conservative here but not anticipating the compile-time issues this
>creates.  I count 227 last_stmt and 12 last_and_only_stmt uses.

In https://inbox.sourceware.org/gcc-help/20211121010713.1452267f@nbbrfq/ i 
asked if maybe
---8<---
1) last_stmt
wouldn't it be more efficient if tree-cfg.c:: last_stmt() would
gimple_seq_last_nondebug_stmt (bb_seq (bb)) ? That would set stmt=NULL
only after the loop it seems..



[pushed] c++: attribute on dtor in template [PR108795]

2023-03-22 Thread Jason Merrill via Gcc-patches
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

Since r7-2549 we were throwing away the explicit C:: when we found that ~C
has an attribute that we treat as making its type dependent.

PR c++/108795

gcc/cp/ChangeLog:

* semantics.cc (finish_id_expression_1): Check scope before
returning id_expression.

gcc/testsuite/ChangeLog:

* g++.dg/ext/attr-tsafe1.C: New test.
---
 gcc/cp/semantics.cc|  1 +
 gcc/testsuite/g++.dg/ext/attr-tsafe1.C | 14 ++
 2 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/attr-tsafe1.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 87c2e8a7111..99a76e3ed65 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4238,6 +4238,7 @@ finish_id_expression_1 (tree id_expression,
: CP_ID_KIND_UNQUALIFIED)));
 
   if (dependent_p
+ && !scope
  && DECL_P (decl)
  && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
/* Dependent type attributes on the decl mean that the TREE_TYPE is
diff --git a/gcc/testsuite/g++.dg/ext/attr-tsafe1.C 
b/gcc/testsuite/g++.dg/ext/attr-tsafe1.C
new file mode 100644
index 000..20c319f154d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-tsafe1.C
@@ -0,0 +1,14 @@
+// PR c++/108795
+
+template  void g (T x)
+{
+  struct C
+  {
+__attribute__((transaction_safe)) ~C();
+  };
+  C::~C(); // { dg-error "" }
+}
+void f ()
+{
+  g (5);
+}

base-commit: d3a6f174543816600b1f472997d492088e4e396a
-- 
2.31.1



Re: Should -ffp-contract=off the default on GCC?

2023-03-22 Thread Qing Zhao via Gcc-patches


> On Mar 22, 2023, at 9:57 AM, Richard Biener via Gcc-patches 
>  wrote:
> 
> On Wed, Mar 22, 2023 at 1:26 PM Alexander Monakov  wrote:
>> 
>> 
>> On Wed, 22 Mar 2023, Richard Biener wrote:
>> 
>>> I think it's even less realistic to expect users to know the details of
>>> floating-point math.  So I doubt any such sentence will be helpful
>>> besides spreading some FUD?
>> 
>> I think it's closer to "fundamental notions" rather than "details". For
>> users who bother to read the GCC manual there's a decent chance it wouldn't
>> be for naught.
>> 
>> For documentation, I was thinking
>> 
>>  Together with -fexcess-precision=standard, -ffp-contract=off
>>  is necessary to ensure that rounding of intermediate results to precision
>>  implied by the source code and the FLT_EVAL_METHOD macro is not
>>  omitted by the compiler.
> 
> that sounds good to me

Shall we add such clarification to our Gcc13 doc? That should be helpful if we 
keep the currently default.

Qing
> 
>> Alexander



Re: [PATCH] c++: Avoid duplicate diagnostic calling unavailable function [PR109177]

2023-03-22 Thread Jason Merrill via Gcc-patches

On 3/22/23 07:32, Alex Coplan wrote:

Hi,

As the PR shows, we currently emit duplicate diagnostics for calls to
functions marked with __attribute__((unavailable)). This patch fixes
that.

I'm not sure whether it's considered acceptable to add the include of
decl.h to call.cc (in order to get at deprecated_state). It would be
useful to get some feedback on that.


That's fine.


Bootstrapped/regtested on aarch64-linux-gnu, OK for trunk?


OK.


gcc/cp/ChangeLog:

PR c++/109177
* call.cc (build_over_call): Use make_temp_override to suppress
both unavailable and deprecated warnings when calling
build_addr_func.

gcc/testsuite/ChangeLog:

PR c++/109177
* g++.dg/ext/pr109177.C: New test.




Re: [PATCH] wwwdocs: Clarify experimental status of C++17 prior to GCC 9

2023-03-22 Thread Jason Merrill via Gcc-patches

On 3/22/23 06:42, Jonathan Wakely wrote:

We don't currently have a single page where you can find out when
support for a given standard became non-experimental (you have to look
through all the gcc-X/changes.html pages to find it). I think we should
have that info on the cxx-status.html page. This adds it for C++17, and
we can do the same for C++20 when we declare that stable.

OK for wwwdocs?


OK.


-- >8 --

Also link to library docs for C++20 and add a cxx2a anchor which is used
by some old links.
---
  htdocs/projects/cxx-status.html | 20 
  1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/htdocs/projects/cxx-status.html b/htdocs/projects/cxx-status.html
index b5362bba..7f59e5a2 100644
--- a/htdocs/projects/cxx-status.html
+++ b/htdocs/projects/cxx-status.html
@@ -402,10 +402,12 @@
  -->

  
-  C++20 Support in GCC

+  C++20 Support in GCC
  
GCC has experimental support for the latest revision of the C++

-  standard, which was published in 2020.
+  standard, which was published in 2020.
+  The status of C++20 library features is described in
+  https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2020;>the library 
documentation.
  
C++20 features are available since GCC 8. To enable C++20

support, add the command-line parameter -std=c++20
@@ -988,14 +990,16 @@
  
GCC has almost full support for the previous revision of the C++

standard, which was published in 2017.
-  Some library features are missing or incomplete, as described in
+  The status of C++17 library features is described in
https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2017;>the 
library documentation.

  
-  C++17 features are available since GCC 5.  This mode is the default

-  in GCC 11; it can be explicitly selected with the -std=c++17
-  command-line flag, or -std=gnu++17 to enable GNU extensions
-  as well.
+  C++17 mode is the default since GCC 11; it can be explicitly selected
+  with the -std=c++17 command-line flag, or
+  -std=gnu++17 to enable GNU extensions as well.
+  Some C++17 features are available since GCC 5, but support was experimental
+  and the ABI of C++17 features was not stable until GCC 9.
+  
  
C++17 Language Features
  
@@ -1315,7 +1319,7 @@
  
GCC has full support for the of the 2014 C++ standard.
  
-  This mode is the default in GCC 6.1 up until GCC 10 (including); it can

+  This mode is the default in GCC 6.1 up until GCC 10 (inclusive); it can
be explicitly selected with the -std=c++14 command-line flag,
or -std=gnu++14 to enable GNU extensions as well.
  




Re: Should -ffp-contract=off the default on GCC?

2023-03-22 Thread Qing Zhao via Gcc-patches


> On Mar 22, 2023, at 8:33 AM, Alexander Monakov  wrote:
> 
> 
> On Mon, 20 Mar 2023, Jakub Jelinek via Gcc-patches wrote:
> 
>> On Mon, Mar 20, 2023 at 10:05:57PM +, Qing Zhao via Gcc-patches wrote:
>>> My question: is the above section the place in C standard “explicitly 
>>> allows contractions”? If not, where it is in C standard?
>> 
>> http://port70.net/%7Ensz/c/c99/n1256.html#6.5p8
>> http://port70.net/%7Ensz/c/c99/n1256.html#note78
>> http://port70.net/%7Ensz/c/c99/n1256.html#F.6
> 
> C only allows contractions within expressions, not across statements (i.e.
> either -ffp-contract=on or -ffp-contract=off would be compliant, but not
> our default -ffp-contract=fast).

Oh, thanks for the info.

Just read the documentation of -fp-contract=style again: -:)

"
-ffp-contract=style
-ffp-contract=off disables floating-point expression contraction. 
-ffp-contract=fast enables floating-point expression contraction such as 
forming of fused multiply-add operations if the target has native support for 
them. -ffp-contract=on enables floating-point expression contraction if allowed 
by the language standard. This is currently not implemented and treated equal 
to -ffp-contract=off.

The default is -ffp-contract=fast.”

I was a little confused about the difference between -ffp-contract=fast and 
-ffp-contract=on previously,  now I understand.  

So, looks like that it's -ffp-contract=on that is compliant with C standard, 
but not -ffp-contract=fast?  (However, my understanding from the above doc and 
also from the GCC source code is, currently, -ffp-contract=on is not 
implemented and is equal to -fp-contract=off).

Therefore, the default value of -fp-contract=fast is NOT compliant with the 
language standard? 

Do I miss anything here?

> 
> Unrestricted contraction across statements together with other optimizations
> gives rise to difficult-to-debug issues such as PR 106902.

Just read this bug’s comments, yes, I agree.

Qing
> 
> Alexander



Re: Should -ffp-contract=off the default on GCC?

2023-03-22 Thread Richard Biener via Gcc-patches
On Wed, Mar 22, 2023 at 1:26 PM Alexander Monakov  wrote:
>
>
> On Wed, 22 Mar 2023, Richard Biener wrote:
>
> > I think it's even less realistic to expect users to know the details of
> > floating-point math.  So I doubt any such sentence will be helpful
> > besides spreading some FUD?
>
> I think it's closer to "fundamental notions" rather than "details". For
> users who bother to read the GCC manual there's a decent chance it wouldn't
> be for naught.
>
> For documentation, I was thinking
>
>   Together with -fexcess-precision=standard, -ffp-contract=off
>   is necessary to ensure that rounding of intermediate results to precision
>   implied by the source code and the FLT_EVAL_METHOD macro is not
>   omitted by the compiler.

that sounds good to me

> Alexander


[pushed] analyzer: fix false +ves from -Wanalyzer-deref-before-check due to inlining [PR109239]

2023-03-22 Thread David Malcolm via Gcc-patches
The patch has this effect on my integration tests of -fanalyzer:

  Comparison:
GOOD: 129(17.70% -> 17.92%)
 BAD: 600 -> 591 (-9)

which is purely due to improvements to -Wanalyzer-deref-before-check
on the Linux kernel:

  -Wanalyzer-deref-before-check:
GOOD: 1(4.55% -> 7.69%)
 BAD: 21 -> 12 (-9)
 Known false positives: 16 -> 10 (-6)
   linux-5.10.162: 7 -> 1 (-6)
 Suspected false positives: 3 -> 0 (-3)
   linux-5.10.162: 3 -> 0 (-3)

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-6800-g0c652ebbf79bd1.

gcc/analyzer/ChangeLog:
PR analyzer/109239
* program-point.cc: Include "analyzer/inlining-iterator.h".
(program_point::effectively_intraprocedural_p): New function.
* program-point.h (program_point::effectively_intraprocedural_p):
New decl.
* sm-malloc.cc (deref_before_check::emit): Use it when rejecting
interprocedural cases, so that we reject interprocedural cases
that have become intraprocedural due to inlining.

gcc/testsuite/ChangeLog:
PR analyzer/109239
* gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/program-point.cc |  42 +
 gcc/analyzer/program-point.h  |   3 +
 gcc/analyzer/sm-malloc.cc |   9 +-
 .../deref-before-check-pr109239-linux-bus.c   | 153 ++
 4 files changed, 203 insertions(+), 4 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c

diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index 0ab55face16..f2d6490f0c0 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "shortest-paths.h"
 #include "analyzer/exploded-graph.h"
 #include "analyzer/analysis-plan.h"
+#include "analyzer/inlining-iterator.h"
 
 #if ENABLE_ANALYZER
 
@@ -719,6 +720,47 @@ program_point::get_next () const
 }
 }
 
+/* Return true iff POINT_A and POINT_B share the same function and
+   call_string, both directly, and when attempting to undo inlining
+   information.  */
+
+bool
+program_point::effectively_intraprocedural_p (const program_point _a,
+ const program_point _b)
+{
+  /* First, compare without considering inlining info.  */
+  if (point_a.get_function ()
+  != point_b.get_function ())
+return false;
+  if (_a.get_call_string ()
+  != _b.get_call_string ())
+return false;
+
+  /* Consider inlining info; they must have originally come from
+ the same function and have been inlined in the same way.  */
+  location_t loc_a = point_a.get_location ();
+  location_t loc_b = point_b.get_location ();
+  inlining_iterator iter_a (loc_a);
+  inlining_iterator iter_b (loc_b);
+  while (!(iter_a.done_p () || iter_b.done_p ()))
+{
+  if (iter_a.done_p () || iter_b.done_p ())
+   return false;
+
+  if (iter_a.get_fndecl () != iter_b.get_fndecl ())
+   return false;
+  if (iter_a.get_callsite () != iter_b.get_callsite ())
+   return false;
+  if (iter_a.get_block () != iter_b.get_block ())
+   return false;
+
+  iter_a.next ();
+  iter_b.next ();
+}
+
+  return true;
+}
+
 #if CHECKING_P
 
 namespace selftest {
diff --git a/gcc/analyzer/program-point.h b/gcc/analyzer/program-point.h
index d1f8480fa8c..7df3b69c513 100644
--- a/gcc/analyzer/program-point.h
+++ b/gcc/analyzer/program-point.h
@@ -299,6 +299,9 @@ public:
 
   program_point get_next () const;
 
+  static bool effectively_intraprocedural_p (const program_point _a,
+const program_point _b);
+
  private:
   program_point (const function_point _point)
   : m_function_point (fn_point),
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 16883d301d5..74701375409 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -1520,10 +1520,11 @@ public:
 if (!m_check_enode)
   return false;
 /* Only emit the warning for intraprocedural cases.  */
-if (m_deref_enode->get_function () != m_check_enode->get_function ())
-  return false;
-if (_deref_enode->get_point ().get_call_string ()
-   != _check_enode->get_point ().get_call_string ())
+const program_point _point = m_deref_enode->get_point ();
+const program_point _point = m_check_enode->get_point ();
+
+if (!program_point::effectively_intraprocedural_p (deref_point,
+  check_point))
   return false;
 
 /* Reject the warning if the check occurs within a macro defintion.
diff --git 
a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c 
b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c
new file mode 100644
index 

Re: [PATCH] tree-optimization/109237 - last_stmt is possibly slow

2023-03-22 Thread Jakub Jelinek via Gcc-patches
On Wed, Mar 22, 2023 at 12:29:52PM +, Richard Biener wrote:
> Most uses of last_stmt are interested in control transfer stmts
> and for the testcase gimple_purge_dead_eh_edges shows up in
> the profile.  But last_stmt looks past trailing debug stmts but
> those would be rejected by GIMPLEs verify_flow_info.  The following
> adds possible_ctrl_stmt besides last_stmt which does not look
> past trailing debug stmts and adjusts gimple_purge_dead_eh_edges.
> 
> I've put checking code into possible_ctrl_stmt that it will not
> miss a control statement if the real last stmt is a debug stmt.
> 
> The alternative would be to change last_stmt, explicitely introducing
> last_nondebug_stmt.  I remember we chickened out and made last_stmt
> conservative here but not anticipating the compile-time issues this
> creates.  I count 227 last_stmt and 12 last_and_only_stmt uses.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
> 
> Any opinions?  I probably lean towards s/last_stmt/last_nondebug_stmt/
> in next stage1 and then adding last_stmt and changing some
> uses back - through for maintainance that's going to be a
> nightmare (or maybe not, a "wrong" last_stmt should be safe to
> backport and a last_nondebug_stmt will fail to build).
> 
> Richard.
> 
>   PR tree-optimization/109237
>   * tree-cfg.h (possible_ctrl_stmt): New function returning
>   the last stmt not skipping debug stmts.
>   (gimple_purge_dead_eh_edges): Use it.

LGTM.  But finding out which of those 227+12 calls want to skip
debug stmts and which don't will be a nightmare...

Jakub



Re: Should -ffp-contract=off the default on GCC?

2023-03-22 Thread Alexander Monakov via Gcc-patches


On Mon, 20 Mar 2023, Jakub Jelinek via Gcc-patches wrote:

> On Mon, Mar 20, 2023 at 10:05:57PM +, Qing Zhao via Gcc-patches wrote:
> > My question: is the above section the place in C standard “explicitly 
> > allows contractions”? If not, where it is in C standard?
> 
> http://port70.net/%7Ensz/c/c99/n1256.html#6.5p8
> http://port70.net/%7Ensz/c/c99/n1256.html#note78
> http://port70.net/%7Ensz/c/c99/n1256.html#F.6

C only allows contractions within expressions, not across statements (i.e.
either -ffp-contract=on or -ffp-contract=off would be compliant, but not
our default -ffp-contract=fast).

Unrestricted contraction across statements together with other optimizations
gives rise to difficult-to-debug issues such as PR 106902.

Alexander


[PATCH] tree-optimization/109237 - last_stmt is possibly slow

2023-03-22 Thread Richard Biener via Gcc-patches
Most uses of last_stmt are interested in control transfer stmts
and for the testcase gimple_purge_dead_eh_edges shows up in
the profile.  But last_stmt looks past trailing debug stmts but
those would be rejected by GIMPLEs verify_flow_info.  The following
adds possible_ctrl_stmt besides last_stmt which does not look
past trailing debug stmts and adjusts gimple_purge_dead_eh_edges.

I've put checking code into possible_ctrl_stmt that it will not
miss a control statement if the real last stmt is a debug stmt.

The alternative would be to change last_stmt, explicitely introducing
last_nondebug_stmt.  I remember we chickened out and made last_stmt
conservative here but not anticipating the compile-time issues this
creates.  I count 227 last_stmt and 12 last_and_only_stmt uses.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Any opinions?  I probably lean towards s/last_stmt/last_nondebug_stmt/
in next stage1 and then adding last_stmt and changing some
uses back - through for maintainance that's going to be a
nightmare (or maybe not, a "wrong" last_stmt should be safe to
backport and a last_nondebug_stmt will fail to build).

Richard.

PR tree-optimization/109237
* tree-cfg.h (possible_ctrl_stmt): New function returning
the last stmt not skipping debug stmts.
(gimple_purge_dead_eh_edges): Use it.
---
 gcc/tree-cfg.cc | 22 +-
 gcc/tree-cfg.h  |  1 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index a9fcc7fd050..e167596209b 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -2947,6 +2947,26 @@ first_non_label_stmt (basic_block bb)
   return !gsi_end_p (i) ? gsi_stmt (i) : NULL;
 }
 
+/* Return the last statement of a basic block BB that's possibly control
+   altering.  Compared to last_stmt this will return a debug stmt if that
+   is the last stmt.  */
+
+gimple *
+possible_ctrl_stmt (basic_block bb)
+{
+  gimple_stmt_iterator i = gsi_last_bb (bb);
+  if (gsi_end_p (i))
+return NULL;
+  if (flag_checking && is_gimple_debug (gsi_stmt (i)))
+{
+  /* Verify that if the real last stmt is a debug stmt the
+last non-debug stmt isn't control altering.  */
+  gimple *last = last_stmt (bb);
+  gcc_assert (!last || !stmt_ends_bb_p (last));
+}
+  return gsi_stmt (i);
+}
+
 /* Return the last statement in basic block BB.  */
 
 gimple *
@@ -8990,7 +9010,7 @@ gimple_purge_dead_eh_edges (basic_block bb)
   bool changed = false;
   edge e;
   edge_iterator ei;
-  gimple *stmt = last_stmt (bb);
+  gimple *stmt = possible_ctrl_stmt (bb);
 
   if (stmt && stmt_can_throw_internal (cfun, stmt))
 return false;
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 9b56a68fe9d..7c6a9a4f16b 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -61,6 +61,7 @@ extern bool assert_unreachable_fallthru_edge_p (edge);
 extern void delete_tree_cfg_annotations (function *);
 extern gphi *get_virtual_phi (basic_block);
 extern gimple *first_stmt (basic_block);
+extern gimple *possible_ctrl_stmt (basic_block);
 extern gimple *last_stmt (basic_block);
 extern gimple *last_and_only_stmt (basic_block);
 extern bool verify_gimple_in_seq (gimple_seq, bool = true);
-- 
2.35.3


Re: Should -ffp-contract=off the default on GCC?

2023-03-22 Thread Alexander Monakov via Gcc-patches


On Wed, 22 Mar 2023, Richard Biener wrote:

> I think it's even less realistic to expect users to know the details of
> floating-point math.  So I doubt any such sentence will be helpful
> besides spreading some FUD?

I think it's closer to "fundamental notions" rather than "details". For
users who bother to read the GCC manual there's a decent chance it wouldn't
be for naught.

For documentation, I was thinking

  Together with -fexcess-precision=standard, -ffp-contract=off
  is necessary to ensure that rounding of intermediate results to precision
  implied by the source code and the FLT_EVAL_METHOD macro is not
  omitted by the compiler.

Alexander


Re: [PATCH v2 1/2] libstdc++: also use sendfile for big files

2023-03-22 Thread Jonathan Wakely via Gcc-patches
On Wed, 22 Mar 2023 at 12:18, Jonathan Wakely wrote:

> On Wed, 22 Mar 2023 at 12:14, Jonathan Wakely wrote:
>
>>
>>
>> On Mon, 20 Mar 2023 at 22:30, Jonathan Wakely via Libstdc++ <
>> libstd...@gcc.gnu.org> wrote:
>>
>>> On 20/03/23 22:27 +, Jonathan Wakely wrote:
>>> >On 06/03/23 20:52 +0100, Jannik Glückert wrote:
>>> >>we were previously only using sendfile for files smaller than 2GB, as
>>> >>sendfile needs to be called repeatedly for files bigger than that.
>>> >>
>>> >>some quick numbers, copying a 16GB file, average of 10 repetitions:
>>> >>   old:
>>> >>   real: 13.4s
>>> >>   user: 0.14s
>>> >>   sys : 7.43s
>>> >>   new:
>>> >>   real: 8.90s
>>> >>   user: 0.00s
>>> >>   sys : 3.68s
>>> >>
>>> >>Additionally, this fixes
>>> >>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108178
>>> >>
>>> >>libstdc++-v3/ChangeLog:
>>> >>
>>> >>   * acinclude.m4 (_GLIBCXX_HAVE_LSEEK): define
>>> >>   * config.h.in: Regenerate.
>>> >>   * configure: Regenerate.
>>> >>   * src/filesystem/ops-common.h: enable sendfile for files
>>> >> >2GB in std::filesystem::copy_file, skip zero-length files
>>>
>>> Also, the ChangeLog entry needs to be indented with tabs, name the
>>> changed functions, and should be complete sentences, e.g.
>>>
>>> * acinclude.m4 (_GLIBCXX_HAVE_LSEEK): Define.
>>> * config.h.in: Regenerate.
>>> * configure: Regenerate.
>>> * src/filesystem/ops-common.h (copy_file_sendfile): Define new
>>> function for sendfile logic. Loop to support large files. Skip
>>> zero-length files.
>>> (do_copy_file): Use it.
>>>
>>>
>> Here's what I plan to commit in a few weeks when GCC 14 Stage 1 opens.
>>
>>
>>
> And similarly for the copy_file_range change.
>

And finally, here's the fix for PR libstdc++/108178, replacing the
zero-size check with checking for EOF in the source file
commit 3d994f1998c8f2efc2c8f5744615e92661bde46f
Author: Jonathan Wakely 
Date:   Tue Mar 21 12:29:08 2023

libstdc++: Make std::filesystem::copy_file work for procfs [PR108178]

The size reported by stat is always zero for some special files such as
those under /proc, which means the current copy_file implementation
thinks there is nothing to copy. Instead of trusting the stat value, try
to read a character from a streambuf and check for EOF.

libstdc++-v3/ChangeLog:

PR libstdc++/108178
* src/filesystem/ops-common.h (do_copy_file): Check for empty
files by trying to read a character.
* testsuite/27_io/filesystem/operations/copy_file_108178.cc:
New test.

diff --git a/libstdc++-v3/src/filesystem/ops-common.h 
b/libstdc++-v3/src/filesystem/ops-common.h
index 906436b484e..a28cbeb10b5 100644
--- a/libstdc++-v3/src/filesystem/ops-common.h
+++ b/libstdc++-v3/src/filesystem/ops-common.h
@@ -618,11 +618,16 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
 if (sbout.is_open())
   out.fd = -1;
 
-if (from_st->st_size && !(std::ostream() << ))
-  {
-   ec = std::make_error_code(std::errc::io_error);
-   return false;
-  }
+// ostream::operator<<(streambuf*) fails if it extracts no characters,
+// so don't try to use it for empty files. But from_st->st_size == 0 for
+// some special files (e.g. procfs, see PR libstdc++/108178) so just try
+// to read a character to decide whether there is anything to copy or not.
+if (sbin.sgetc() != char_traits::eof())
+  if (!(std::ostream() << ))
+   {
+ ec = std::make_error_code(std::errc::io_error);
+ return false;
+   }
 
 if (!sbout.close() || !sbin.close())
   {
diff --git 
a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file_108178.cc 
b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file_108178.cc
new file mode 100644
index 000..25135834e21
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy_file_108178.cc
@@ -0,0 +1,33 @@
+// { dg-do run { target c++17 } }
+// { dg-require-filesystem-ts "" }
+
+// C++17 30.10.15.4 Copy [fs.op.copy_file]
+
+#include 
+#include 
+#include  // getpid
+#include 
+#include 
+
+namespace fs = std::filesystem;
+
+void
+test_procfs() // PR libstdc++/108178
+{
+  auto pid = ::getpid();
+  std::string from = "/proc/" + std::to_string(pid) + "/status";
+  if (fs::exists(from))
+  {
+auto to = __gnu_test::nonexistent_path();
+fs::copy_file(from, to);
+std::ifstream f(to);
+VERIFY(f.is_open());
+VERIFY(f.peek() != std::char_traits::eof());
+fs::remove(to);
+  }
+}
+
+int main()
+{
+  test_procfs();
+}


Re: [PATCH v2 1/2] libstdc++: also use sendfile for big files

2023-03-22 Thread Jonathan Wakely via Gcc-patches
On Wed, 22 Mar 2023 at 12:14, Jonathan Wakely wrote:

>
>
> On Mon, 20 Mar 2023 at 22:30, Jonathan Wakely via Libstdc++ <
> libstd...@gcc.gnu.org> wrote:
>
>> On 20/03/23 22:27 +, Jonathan Wakely wrote:
>> >On 06/03/23 20:52 +0100, Jannik Glückert wrote:
>> >>we were previously only using sendfile for files smaller than 2GB, as
>> >>sendfile needs to be called repeatedly for files bigger than that.
>> >>
>> >>some quick numbers, copying a 16GB file, average of 10 repetitions:
>> >>   old:
>> >>   real: 13.4s
>> >>   user: 0.14s
>> >>   sys : 7.43s
>> >>   new:
>> >>   real: 8.90s
>> >>   user: 0.00s
>> >>   sys : 3.68s
>> >>
>> >>Additionally, this fixes
>> >>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108178
>> >>
>> >>libstdc++-v3/ChangeLog:
>> >>
>> >>   * acinclude.m4 (_GLIBCXX_HAVE_LSEEK): define
>> >>   * config.h.in: Regenerate.
>> >>   * configure: Regenerate.
>> >>   * src/filesystem/ops-common.h: enable sendfile for files
>> >> >2GB in std::filesystem::copy_file, skip zero-length files
>>
>> Also, the ChangeLog entry needs to be indented with tabs, name the
>> changed functions, and should be complete sentences, e.g.
>>
>> * acinclude.m4 (_GLIBCXX_HAVE_LSEEK): Define.
>> * config.h.in: Regenerate.
>> * configure: Regenerate.
>> * src/filesystem/ops-common.h (copy_file_sendfile): Define new
>> function for sendfile logic. Loop to support large files. Skip
>> zero-length files.
>> (do_copy_file): Use it.
>>
>>
> Here's what I plan to commit in a few weeks when GCC 14 Stage 1 opens.
>
>
>
And similarly for the copy_file_range change.
commit 2ad500e358c03ef63af1540d44645df582a4809c
Author: Jannik Glückert 
Date:   Wed Mar 8 18:37:43 2023

libstdc++: Use copy_file_range for filesystem::copy_file

copy_file_range is a recent-ish syscall for copying files. It is similar
to sendfile but allows filesystem-specific optimizations. Common are:
Reflinks: BTRFS, XFS, ZFS (does not implement the syscall yet)
Server-side copy: NFS, SMB, Ceph

If copy_file_range is not available for the given files, fall back to
sendfile / userspace copy.

libstdc++-v3/ChangeLog:

* acinclude.m4 (_GLIBCXX_USE_COPY_FILE_RANGE): Define.
* config.h.in: Regenerate.
* configure: Regenerate.
* src/filesystem/ops-common.h (copy_file_copy_file_range):
Define new function.
(do_copy_file): Use it.

Signed-off-by: Jannik Glückert 

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 85a09a5a869..4cf02dc6e4e 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4581,6 +4581,7 @@ dnl  _GLIBCXX_USE_UTIMENSAT
 dnl  _GLIBCXX_USE_ST_MTIM
 dnl  _GLIBCXX_USE_FCHMOD
 dnl  _GLIBCXX_USE_FCHMODAT
+dnl  _GLIBCXX_USE_COPY_FILE_RANGE
 dnl  _GLIBCXX_USE_SENDFILE
 dnl  HAVE_LINK
 dnl  HAVE_LSEEK
@@ -4779,6 +4780,25 @@ dnl
   if test $glibcxx_cv_truncate = yes; then
 AC_DEFINE(HAVE_TRUNCATE, 1, [Define if truncate is available in 
.])
   fi
+dnl
+  AC_CACHE_CHECK([for copy_file_range that can copy files],
+glibcxx_cv_copy_file_range, [dnl
+case "${target_os}" in
+  linux*)
+   GCC_TRY_COMPILE_OR_LINK(
+ [#include ],
+ [copy_file_range(1, nullptr, 2, nullptr, 1, 0);],
+ [glibcxx_cv_copy_file_range=yes],
+ [glibcxx_cv_copy_file_range=no])
+   ;;
+  *)
+   glibcxx_cv_copy_file_range=no
+   ;;
+esac
+  ])
+  if test $glibcxx_cv_copy_file_range = yes; then
+AC_DEFINE(_GLIBCXX_USE_COPY_FILE_RANGE, 1, [Define if copy_file_range is 
available in .])
+  fi
 dnl
   AC_CACHE_CHECK([for sendfile that can copy files],
 glibcxx_cv_sendfile, [dnl
diff --git a/libstdc++-v3/src/filesystem/ops-common.h 
b/libstdc++-v3/src/filesystem/ops-common.h
index 7874a95488a..906436b484e 100644
--- a/libstdc++-v3/src/filesystem/ops-common.h
+++ b/libstdc++-v3/src/filesystem/ops-common.h
@@ -49,6 +49,9 @@
 #ifdef NEED_DO_COPY_FILE
 # include 
 # include 
+# ifdef _GLIBCXX_USE_COPY_FILE_RANGE
+#  include  // copy_file_range
+# endif
 # ifdef _GLIBCXX_USE_SENDFILE
 #  include  // sendfile
 #  include  // lseek
@@ -359,6 +362,32 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
   }
 
 #ifdef NEED_DO_COPY_FILE
+#ifdef _GLIBCXX_USE_COPY_FILE_RANGE
+  bool
+  copy_file_copy_file_range(int fd_in, int fd_out, size_t length) noexcept
+  {
+// a zero-length file is either empty, or not copyable by this syscall
+// return early to avoid the syscall cost
+if (length == 0)
+  {
+errno = EINVAL;
+return false;
+  }
+size_t bytes_left = length;
+off64_t off_in = 0, off_out = 0;
+ssize_t bytes_copied;
+do
+  {
+   bytes_copied = ::copy_file_range(fd_in, _in, fd_out, _out,
+bytes_left, 0);
+   bytes_left -= bytes_copied;
+  }
+while (bytes_left > 0 && 

[PATCH] RISC-V: Fix redundant vmv1r.v instruction in vmsge.vx codegen

2023-03-22 Thread juzhe . zhong
From: Ju-Zhe Zhong 

Current expansion of vmsge will make RA produce redundant vmv1r.v.

testcase:
void f1 (void * in, void *out, int32_t x)
{
vbool32_t mask = *(vbool32_t*)in;
asm volatile ("":::"memory");
vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
vint32m1_t v2 = __riscv_vle32_v_i32m1_m (mask, in, 4);
vbool32_t m3 = __riscv_vmsge_vx_i32m1_b32 (v, x, 4);
vbool32_t m4 = __riscv_vmsge_vx_i32m1_b32_mu (mask, m3, v, x, 4);
m4 = __riscv_vmsge_vv_i32m1_b32_m (m4, v2, v2, 4);
__riscv_vsm_v_b32 (out, m4, 4);
}

Before this patch:
f1:
vsetvli a5,zero,e8,mf4,ta,ma
vlm.v   v0,0(a0)
vsetivlizero,4,e32,m1,ta,mu
vle32.v v3,0(a0)
vle32.v v2,0(a0),v0.t
vmslt.vxv1,v3,a2
vmnot.m v1,v1
vmslt.vxv1,v3,a2,v0.t
vmxor.mmv1,v1,v0
vmv1r.v v0,v1
vmsge.vvv2,v2,v2,v0.t
vsm.v   v2,0(a1)
ret

After this patch:
f1:
vsetvli a5,zero,e8,mf4,ta,ma
vlm.v   v0,0(a0)
vsetivlizero,4,e32,m1,ta,mu
vle32.v v3,0(a0)
vle32.v v2,0(a0),v0.t
vmslt.vxv1,v3,a2
vmnot.m v1,v1
vmslt.vxv1,v3,a2,v0.t
vmxor.mmv0,v1,v0
vmsge.vvv2,v2,v2,v0.t
vsm.v   v2,0(a1)
ret


gcc/ChangeLog:

* config/riscv/vector.md: Fix redundant vmv1r.v.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/binop_vx_constraint-150.c: Adapt assembly 
check.

---
 gcc/config/riscv/vector.md| 15 +++
 .../riscv/rvv/base/binop_vx_constraint-150.c  |  2 +-
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index ebb014aecb1..f06d68be80f 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -4111,6 +4111,7 @@
 {
   enum rtx_code code = GET_CODE (operands[3]);
   rtx undef = RVV_VUNDEF (mode);
+  rtx tmp = gen_reg_rtx (mode);
   if (code == GEU && rtx_equal_p (operands[5], const0_rtx))
 {
   /* If vmsgeu with 0 immediate, expand it to vmset.  */
@@ -4157,12 +4158,11 @@
- pseudoinstruction: vmsge{u}.vx vd, va, x
- expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd.  */
  emit_insn (
-   gen_pred_cmp_scalar (operands[0], operands[1], operands[2],
+   gen_pred_cmp_scalar (tmp, operands[1], operands[2],
operands[3], operands[4], operands[5],
operands[6], operands[7], operands[8]));
  emit_insn (gen_pred_nand (operands[0], CONSTM1_RTX (mode),
-   undef, operands[0], operands[0],
-   operands[6], operands[8]));
+   undef, tmp, tmp, operands[6], 
operands[8]));
}
   else
{
@@ -4171,13 +4171,12 @@
  /* masked va >= x, vd == v0
- pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
- expansion: vmslt{u}.vx vt, va, x;  vmandn.mm vd, vd, vt.  */
- rtx reg = gen_reg_rtx (mode);
  emit_insn (gen_pred_cmp_scalar (
-   reg, CONSTM1_RTX (mode), undef, operands[3], operands[4],
+   tmp, CONSTM1_RTX (mode), undef, operands[3], operands[4],
operands[5], operands[6], operands[7], operands[8]));
  emit_insn (
gen_pred_andnot (operands[0], CONSTM1_RTX (mode), undef,
-  operands[1], reg, operands[6], operands[8]));
+  operands[1], tmp, operands[6], operands[8]));
}
  else
{
@@ -4186,10 +4185,10 @@
- expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0.
  */
  emit_insn (gen_pred_cmp_scalar (
-   operands[0], operands[1], operands[2], operands[3], operands[4],
+   tmp, operands[1], operands[2], operands[3], operands[4],
operands[5], operands[6], operands[7], operands[8]));
  emit_insn (gen_pred (XOR, mode, operands[0],
-  CONSTM1_RTX (mode), undef, operands[0],
+  CONSTM1_RTX (mode), undef, tmp,
   operands[1], operands[6], operands[8]));
}
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-150.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-150.c
index 55a222f47ea..e92a8115f09 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-150.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-150.c
@@ -18,4 +18,4 @@ void f1 (void * in, void *out, int32_t x)
 /* { dg-final { scan-assembler-times 
{vmslt\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t} 1 } } */
 /* { dg-final { 

Re: [PATCH v2 1/2] libstdc++: also use sendfile for big files

2023-03-22 Thread Jonathan Wakely via Gcc-patches
On Mon, 20 Mar 2023 at 22:30, Jonathan Wakely via Libstdc++ <
libstd...@gcc.gnu.org> wrote:

> On 20/03/23 22:27 +, Jonathan Wakely wrote:
> >On 06/03/23 20:52 +0100, Jannik Glückert wrote:
> >>we were previously only using sendfile for files smaller than 2GB, as
> >>sendfile needs to be called repeatedly for files bigger than that.
> >>
> >>some quick numbers, copying a 16GB file, average of 10 repetitions:
> >>   old:
> >>   real: 13.4s
> >>   user: 0.14s
> >>   sys : 7.43s
> >>   new:
> >>   real: 8.90s
> >>   user: 0.00s
> >>   sys : 3.68s
> >>
> >>Additionally, this fixes
> >>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108178
> >>
> >>libstdc++-v3/ChangeLog:
> >>
> >>   * acinclude.m4 (_GLIBCXX_HAVE_LSEEK): define
> >>   * config.h.in: Regenerate.
> >>   * configure: Regenerate.
> >>   * src/filesystem/ops-common.h: enable sendfile for files
> >> >2GB in std::filesystem::copy_file, skip zero-length files
>
> Also, the ChangeLog entry needs to be indented with tabs, name the
> changed functions, and should be complete sentences, e.g.
>
> * acinclude.m4 (_GLIBCXX_HAVE_LSEEK): Define.
> * config.h.in: Regenerate.
> * configure: Regenerate.
> * src/filesystem/ops-common.h (copy_file_sendfile): Define new
> function for sendfile logic. Loop to support large files. Skip
> zero-length files.
> (do_copy_file): Use it.
>
>
Here's what I plan to commit in a few weeks when GCC 14 Stage 1 opens.
commit c177825f952bb353cdf412f46f45539b8992abe1
Author: Jannik Glückert 
Date:   Mon Mar 6 19:52:08 2023

libstdc++: Also use sendfile for big files

We were previously only using sendfile for files smaller than 2GB, as
sendfile needs to be called repeatedly for files bigger than that.

Some quick numbers, copying a 16GB file, average of 10 repetitions:
old:
real: 13.4s
user: 0.14s
sys : 7.43s
new:
real: 8.90s
user: 0.00s
sys : 3.68s

libstdc++-v3/ChangeLog:

* acinclude.m4 (_GLIBCXX_HAVE_LSEEK): Define.
* config.h.in: Regenerate.
* configure: Regenerate.
* src/filesystem/ops-common.h (copy_file_sendfile): Define new
function for sendfile logic. Loop to support large files. Skip
zero-length files.
(do_copy_file): Use it.

Signed-off-by: Jannik Glückert 

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 5136c0571e8..85a09a5a869 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4583,6 +4583,7 @@ dnl  _GLIBCXX_USE_FCHMOD
 dnl  _GLIBCXX_USE_FCHMODAT
 dnl  _GLIBCXX_USE_SENDFILE
 dnl  HAVE_LINK
+dnl  HAVE_LSEEK
 dnl  HAVE_READLINK
 dnl  HAVE_SYMLINK
 dnl
@@ -4718,25 +4719,6 @@ dnl
   if test $glibcxx_cv_fchmodat = yes; then
 AC_DEFINE(_GLIBCXX_USE_FCHMODAT, 1, [Define if fchmodat is available in 
.])
   fi
-dnl
-  AC_CACHE_CHECK([for sendfile that can copy files],
-glibcxx_cv_sendfile, [dnl
-case "${target_os}" in
-  gnu* | linux* | solaris* | uclinux*)
-   GCC_TRY_COMPILE_OR_LINK(
- [#include ],
- [sendfile(1, 2, (off_t*)0, sizeof 1);],
- [glibcxx_cv_sendfile=yes],
- [glibcxx_cv_sendfile=no])
-   ;;
-  *)
-   glibcxx_cv_sendfile=no
-   ;;
-esac
-  ])
-  if test $glibcxx_cv_sendfile = yes; then
-AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in 
.])
-  fi
 dnl
   AC_CACHE_CHECK([for link],
 glibcxx_cv_link, [dnl
@@ -4749,6 +4731,18 @@ dnl
   if test $glibcxx_cv_link = yes; then
 AC_DEFINE(HAVE_LINK, 1, [Define if link is available in .])
   fi
+dnl
+  AC_CACHE_CHECK([for lseek],
+glibcxx_cv_lseek, [dnl
+GCC_TRY_COMPILE_OR_LINK(
+  [#include ],
+  [lseek(1, 0, SEEK_SET);],
+  [glibcxx_cv_lseek=yes],
+  [glibcxx_cv_lseek=no])
+  ])
+  if test $glibcxx_cv_lseek = yes; then
+AC_DEFINE(HAVE_LSEEK, 1, [Define if lseek is available in .])
+  fi
 dnl
   AC_CACHE_CHECK([for readlink],
 glibcxx_cv_readlink, [dnl
@@ -4785,6 +4779,25 @@ dnl
   if test $glibcxx_cv_truncate = yes; then
 AC_DEFINE(HAVE_TRUNCATE, 1, [Define if truncate is available in 
.])
   fi
+dnl
+  AC_CACHE_CHECK([for sendfile that can copy files],
+glibcxx_cv_sendfile, [dnl
+case "${target_os}" in
+  gnu* | linux* | solaris* | uclinux*)
+   GCC_TRY_COMPILE_OR_LINK(
+ [#include ],
+ [sendfile(1, 2, (off_t*)0, sizeof 1);],
+ [glibcxx_cv_sendfile=yes],
+ [glibcxx_cv_sendfile=no])
+   ;;
+  *)
+   glibcxx_cv_sendfile=no
+   ;;
+esac
+  ])
+  if test $glibcxx_cv_sendfile = yes && test $glibcxx_cv_lseek = yes; then
+AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in 
.])
+  fi
 dnl
   AC_CACHE_CHECK([for fdopendir],
 glibcxx_cv_fdopendir, [dnl
diff --git 

[PATCH] c++: Avoid duplicate diagnostic calling unavailable function [PR109177]

2023-03-22 Thread Alex Coplan via Gcc-patches
Hi,

As the PR shows, we currently emit duplicate diagnostics for calls to
functions marked with __attribute__((unavailable)). This patch fixes
that.

I'm not sure whether it's considered acceptable to add the include of
decl.h to call.cc (in order to get at deprecated_state). It would be
useful to get some feedback on that.

Bootstrapped/regtested on aarch64-linux-gnu, OK for trunk?

Thanks,
Alex

gcc/cp/ChangeLog:

PR c++/109177
* call.cc (build_over_call): Use make_temp_override to suppress
both unavailable and deprecated warnings when calling
build_addr_func.

gcc/testsuite/ChangeLog:

PR c++/109177
* g++.dg/ext/pr109177.C: New test.
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index c52a09b9be2..d5e8ccc07d3 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "internal-fn.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "decl.h"
 #include "gcc-rich-location.h"
 
 /* The various kinds of conversion.  */
@@ -10413,10 +10414,11 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
 }
   else
 {
-  /* If FN is marked deprecated, then we've already issued a deprecated-use
-warning from mark_used above, so avoid redundantly issuing another one
-from build_addr_func.  */
-  warning_sentinel w (warn_deprecated_decl);
+  /* If FN is marked deprecated or unavailable, then we've already
+issued a diagnostic from mark_used above, so avoid redundantly
+issuing another one from build_addr_func.  */
+  auto w = make_temp_override (deprecated_state,
+  UNAVAILABLE_DEPRECATED_SUPPRESS);
 
   fn = build_addr_func (fn, complain);
   if (fn == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/ext/pr109177.C 
b/gcc/testsuite/g++.dg/ext/pr109177.C
new file mode 100644
index 000..cc322f650af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/pr109177.C
@@ -0,0 +1,6 @@
+// { dg-do compile }
+void foo() __attribute__((unavailable));
+void bar () {
+  foo (); // { dg-bogus "is unavailable.*is unavailable" }
+  // { dg-error "is unavailable" "" { target *-*-* } .-1 }
+}


[PATCH] wwwdocs: Clarify experimental status of C++17 prior to GCC 9

2023-03-22 Thread Jonathan Wakely via Gcc-patches
We don't currently have a single page where you can find out when
support for a given standard became non-experimental (you have to look
through all the gcc-X/changes.html pages to find it). I think we should
have that info on the cxx-status.html page. This adds it for C++17, and
we can do the same for C++20 when we declare that stable.

OK for wwwdocs?

-- >8 --

Also link to library docs for C++20 and add a cxx2a anchor which is used
by some old links.
---
 htdocs/projects/cxx-status.html | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/htdocs/projects/cxx-status.html b/htdocs/projects/cxx-status.html
index b5362bba..7f59e5a2 100644
--- a/htdocs/projects/cxx-status.html
+++ b/htdocs/projects/cxx-status.html
@@ -402,10 +402,12 @@
 -->
   
 
-  C++20 Support in GCC
+  C++20 Support in GCC
 
   GCC has experimental support for the latest revision of the C++
-  standard, which was published in 2020.
+  standard, which was published in 2020.
+  The status of C++20 library features is described in
+  https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2020;>the
 library documentation.
 
   C++20 features are available since GCC 8. To enable C++20
   support, add the command-line parameter -std=c++20
@@ -988,14 +990,16 @@
 
   GCC has almost full support for the previous revision of the C++
   standard, which was published in 2017.
-  Some library features are missing or incomplete, as described in
+  The status of C++17 library features is described in
   https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2017;>the
 library documentation.
   
 
-  C++17 features are available since GCC 5.  This mode is the default
-  in GCC 11; it can be explicitly selected with the -std=c++17
-  command-line flag, or -std=gnu++17 to enable GNU extensions
-  as well.
+  C++17 mode is the default since GCC 11; it can be explicitly selected
+  with the -std=c++17 command-line flag, or
+  -std=gnu++17 to enable GNU extensions as well.
+  Some C++17 features are available since GCC 5, but support was experimental
+  and the ABI of C++17 features was not stable until GCC 9.
+  
 
   C++17 Language Features
 
@@ -1315,7 +1319,7 @@
 
   GCC has full support for the of the 2014 C++ standard.
 
-  This mode is the default in GCC 6.1 up until GCC 10 (including); it can
+  This mode is the default in GCC 6.1 up until GCC 10 (inclusive); it can
   be explicitly selected with the -std=c++14 command-line flag,
   or -std=gnu++14 to enable GNU extensions as well.
 
-- 
2.39.2



Re: [PATCH] Remove TARGET_GEN_MEMSET_SCRATCH_RTX since it's not used anymore.

2023-03-22 Thread Jakub Jelinek via Gcc-patches
On Wed, Mar 22, 2023 at 11:18:33AM +0100, Richard Biener via Gcc-patches wrote:
> Is/was the code ever exercised for non-x86?  HJ, what was the reason to
> abstract this?

Initially the hook looked like
rtx
ix86_gen_scratch_sse_rtx (machine_mode mode)
{
  if (TARGET_SSE)
return gen_rtx_REG (mode, (TARGET_64BIT
  ? LAST_REX_SSE_REG
  : LAST_SSE_REG));
  else
return gen_reg_rtx (mode);
}
on x86, but then PR104704 changed it to the same definition as the default
hook.  So I think it is fine to remove it.

> OK if HJ thinks it was really unnecessary abstraction unlikely to be
> required by another target.

Jakub



Re: [PATCH] Remove TARGET_GEN_MEMSET_SCRATCH_RTX since it's not used anymore.

2023-03-22 Thread Richard Biener via Gcc-patches
On Wed, Mar 22, 2023 at 8:07 AM Uros Bizjak  wrote:
>
> On Wed, Mar 22, 2023 at 3:59 AM liuhongt  wrote:
> >
> > The target hook is only used by i386, and the current definition is
> > same as default gen_reg_rtx. So there's no need for this target hook.
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > Ok for trunk(or GCC14)?
> >
> > gcc/ChangeLog:
> >
> > * builtins.cc (builtin_memset_read_str): Replace
> > targetm.gen_memset_scratch_rtx with gen_reg_rtx.
> > (builtin_memset_gen_str): Ditto.
> > * config/i386/i386-expand.cc
> > (ix86_convert_const_wide_int_to_broadcast): Replace
> > ix86_gen_scratch_sse_rtx with gen_reg_rtx.
> > (ix86_expand_vector_move): Ditto.
> > * config/i386/i386-protos.h (ix86_gen_scratch_sse_rtx):
> > Removed.
> > * config/i386/i386.cc (ix86_gen_scratch_sse_rtx): Removed.
> > (TARGET_GEN_MEMSET_SCRATCH_RTX): Removed.
> > * doc/tm.texi: Remove TARGET_GEN_MEMSET_SCRATCH_RTX.
> > * doc/tm.texi.in: Ditto.
> > * target.def: Ditto.
>
> Looks trivial enough for gcc13, so OK for x86 part.
>
> Needs also OK from a middle-end reviewer.

Is/was the code ever exercised for non-x86?  HJ, what was the reason to
abstract this?

OK if HJ thinks it was really unnecessary abstraction unlikely to be
required by another target.

Richard.

> Thanks,
> Uros.
>
> > ---
> >  gcc/builtins.cc|  4 ++--
> >  gcc/config/i386/i386-expand.cc |  6 +++---
> >  gcc/config/i386/i386-protos.h  |  2 --
> >  gcc/config/i386/i386.cc| 12 
> >  gcc/doc/tm.texi|  7 ---
> >  gcc/doc/tm.texi.in |  2 --
> >  gcc/target.def |  9 -
> >  7 files changed, 5 insertions(+), 37 deletions(-)
> >
> > diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> > index 90246e214d6..8026e2001b7 100644
> > --- a/gcc/builtins.cc
> > +++ b/gcc/builtins.cc
> > @@ -4212,7 +4212,7 @@ builtin_memset_read_str (void *data, void *prev,
> > return const_vec;
> >
> >/* Use the move expander with CONST_VECTOR.  */
> > -  target = targetm.gen_memset_scratch_rtx (mode);
> > +  target = gen_reg_rtx (mode);
> >emit_move_insn (target, const_vec);
> >return target;
> >  }
> > @@ -4256,7 +4256,7 @@ builtin_memset_gen_str (void *data, void *prev,
> >  the memset expander.  */
> >insn_code icode = optab_handler (vec_duplicate_optab, mode);
> >
> > -  target = targetm.gen_memset_scratch_rtx (mode);
> > +  target = gen_reg_rtx (mode);
> >class expand_operand ops[2];
> >create_output_operand ([0], target, mode);
> >create_input_operand ([1], (rtx) data, QImode);
> > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> > index c1300dc4e26..1e3ce4b7c3f 100644
> > --- a/gcc/config/i386/i386-expand.cc
> > +++ b/gcc/config/i386/i386-expand.cc
> > @@ -338,7 +338,7 @@ ix86_convert_const_wide_int_to_broadcast (machine_mode 
> > mode, rtx op)
> >machine_mode vector_mode;
> >if (!mode_for_vector (broadcast_mode, nunits).exists (_mode))
> >  gcc_unreachable ();
> > -  rtx target = ix86_gen_scratch_sse_rtx (vector_mode);
> > +  rtx target = gen_reg_rtx (vector_mode);
> >bool ok = ix86_expand_vector_init_duplicate (false, vector_mode,
> >target,
> >GEN_INT (val_broadcast));
> > @@ -686,7 +686,7 @@ ix86_expand_vector_move (machine_mode mode, rtx 
> > operands[])
> >if (!register_operand (op0, mode)
> >   && !register_operand (op1, mode))
> > {
> > - rtx scratch = ix86_gen_scratch_sse_rtx (mode);
> > + rtx scratch = gen_reg_rtx (mode);
> >   emit_move_insn (scratch, op1);
> >   op1 = scratch;
> > }
> > @@ -728,7 +728,7 @@ ix86_expand_vector_move (machine_mode mode, rtx 
> > operands[])
> >&& !register_operand (op0, mode)
> >&& !register_operand (op1, mode))
> >  {
> > -  rtx tmp = ix86_gen_scratch_sse_rtx (GET_MODE (op0));
> > +  rtx tmp = gen_reg_rtx (GET_MODE (op0));
> >emit_move_insn (tmp, op1);
> >emit_move_insn (op0, tmp);
> >return;
> > diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> > index bfb2198265a..71ae95ffef7 100644
> > --- a/gcc/config/i386/i386-protos.h
> > +++ b/gcc/config/i386/i386-protos.h
> > @@ -50,8 +50,6 @@ extern void ix86_reset_previous_fndecl (void);
> >
> >  extern bool ix86_using_red_zone (void);
> >
> > -extern rtx ix86_gen_scratch_sse_rtx (machine_mode);
> > -
> >  extern unsigned int ix86_regmode_natural_size (machine_mode);
> >  extern bool ix86_check_builtin_isa_match (unsigned int fcode);
> >  #ifdef RTX_CODE
> > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> > index 5d0e4739a84..6a8734c2346 100644
> > --- a/gcc/config/i386/i386.cc
> > +++ 

[PATCH] match.pd: Fix up fneg/fadd simplification [PR109230]

2023-03-22 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase is miscompiled on aarch64-linux.  match.pd
has a simplification for addsub, where it negates one of the vectors
in twice as large floating point element vector (effectively negating every
other element) and then doing addition.
But a requirement for that is that the permutation picks the right elements,
in particular 0, nelts+1, 2, nelts+3, 4, nelts+5, ...
The pattern tests this with sel.series_p (0, 2, 0, 2) check, which as
documented verifies that the even elements of the permutation mask are
identity, but doesn't say anything about the others.
The following patch fixes it by also checking that the odd elements
start at nelts + 1 with the same step of 2.

Bootstrapped/regtested on aarch64-linux, x86_64-linux and i686-linux,
ok for trunk?

2023-03-22  Jakub Jelinek  

PR tree-optimization/109230
* match.pd (fneg/fadd simplify): Verify also odd permutation indexes.

* gcc.dg/pr109230.c: New test.

--- gcc/match.pd.jj 2023-02-18 12:38:30.967022708 +0100
+++ gcc/match.pd2023-03-21 19:59:40.209634256 +0100
@@ -8096,6 +8096,7 @@ and,
scalar_mode inner_mode = GET_MODE_INNER (vec_mode);
  }
  (if (sel.series_p (0, 2, 0, 2)
+ && sel.series_p (1, 2, nelts + 1, 2)
  && GET_MODE_2XWIDER_MODE (inner_mode).exists (_elt_mode)
  && multiple_p (GET_MODE_NUNITS (vec_mode), 2, _nunits)
  && related_vector_mode (vec_mode, wide_elt_mode,
--- gcc/testsuite/gcc.dg/pr109230.c.jj  2023-03-21 20:03:52.811979268 +0100
+++ gcc/testsuite/gcc.dg/pr109230.c 2023-03-21 20:03:35.884224342 +0100
@@ -0,0 +1,31 @@
+/* PR tree-optimization/109230 */
+/* { dg-do run } */
+/* { dg-options "-O2 -Wno-psabi" } */
+
+#if __SIZEOF_FLOAT__ == __SIZEOF_INT__
+typedef float V __attribute__((vector_size (4 * sizeof (float;
+typedef int VI __attribute__((vector_size (4 * sizeof (float;
+
+__attribute__((noipa)) V
+foo (V x, V y)
+{
+  V a = x - y;
+  V b = y + x;
+  return __builtin_shuffle (b, a, (VI) { 0, 5, 2, 3 });
+}
+
+int
+main ()
+{
+  V a = (V) { 1.0f, 2.0f, 3.0f, 4.0f };
+  V b = (V) { 8.0f, 9.0f, 10.0f, 11.0f };
+  V c = foo (a, b);
+  if (c[0] != 9.0f || c[1] != -7.0f || c[2] != 13.0f || c[3] != 15.0f)
+__builtin_abort ();
+}
+#else
+int
+main ()
+{
+}
+#endif

Jakub



Re: Should -ffp-contract=off the default on GCC?

2023-03-22 Thread Richard Biener via Gcc-patches
On Tue, Mar 21, 2023 at 7:18 PM Jeff Law via Gcc-patches
 wrote:
>
>
>
> On 3/21/23 12:12, Alexander Monakov wrote:
> >>> Yes, it’s better to know the details of languages standard. -:)
> >>> However, I don’t think that this is a realistic expectation to the 
> >>> compiler
> >>> users:  to know all the details of a language standard.
> >> Umm, they really do need to know that stuff.
> >>
> >> If the developer fails to understand the language standard, then they're
> >> likely going to write code that is ultimately undefined or doesn't behave 
> >> in
> >> they expect.  How is the compiler supposed to guess what the developer
> >> originally intended?  How should the compiler handle the case when two
> >> developers have different understandings of how a particular piece of code
> >> should work?  In the end it's the language standard that defines how all 
> >> this
> >> stuff should work.
> >>
> >> Failure to understand the language is a common problem and we do try to 
> >> emit
> >> various diagnostics to help developers avoid writing non-conformant code.  
> >> But
> >> ultimately if a developer fails to understand the language standard, then
> >> they're going to be surprised by the behavior of their code.
> >
> > W h a t.
> >
> > This subthread concerns documenting the option better ("Without clearly
> > documenting such warnings ...").
> >
> > Are you arguing against adding a brief notice to the documentation blurb for
> > the -ffp-contract= option?
> I was merely chiming in on Qing's statement that it is not realistic to
> expect users to know the details of the language standard.

I think it's even less realistic to expect users to know the details of
floating-point math.  So I doubt any such sentence will be helpful
besides spreading some FUD?

>
>
> Jeff


Re: [wwwdocs] Document support for znver4 in gcc-13/changes.html

2023-03-22 Thread Richard Biener via Gcc-patches
On Tue, Mar 21, 2023 at 8:25 PM Martin Jambor  wrote:
>
> Hello,
>
> is the following item documenting that gcc13 can generate code for Zen 4
> OK for the changes.html file on the web?

OK.  Note the gcc-12 changes for the upcoming 12.3 need something similar
as most of the changes were backported.

Richard.

> Thanks,
>
> Martin
>
>
> diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
> index 4fae1f7a..f8e9560c 100644
> --- a/htdocs/gcc-13/changes.html
> +++ b/htdocs/gcc-13/changes.html
> @@ -530,6 +530,10 @@ a work-in-progress.
>  -march=graniterapids.
>  The switch enables the AMX-FP16 and PREFETCHI ISA extensions.
>
> +  GCC now supports AMD CPUs based on the znver4 core
> +via -march=znver4.  The switch makes GCC consider
> +using 512 bit vectors when auto-vectorizing.
> +  
>  
>
>  


[PATCH] rtl-optimization/109237 - speedup bb_is_just_return

2023-03-22 Thread Richard Biener via Gcc-patches
For the testcase bb_is_just_return is on top of the profile, changing
it to walk BB insns backwards puts it off the profile.  That's because
in the forward walk you have to process possibly many debug insns
but in a backward walk you very likely run into control insns first.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

OK?

For the record, the profile was (after the delete_trivially_dead_insns 
fix)

Samples: 289K of event 'cycles:u', Event count (approx.): 384226334976  

Overhead   Samples  Command  Shared Object Symbol   

   3.52%  9747  cc1  cc1   [.] bb_is_just_return
   
#

and after the fix bb_is_just_return has no recorded samples anymore.

Thanks,
Richard.

PR rtl-optimization/109237
* cfgcleanup.cc (bb_is_just_return): Walk insns backwards.
---
 gcc/cfgcleanup.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cfgcleanup.cc b/gcc/cfgcleanup.cc
index 194e0e5de12..4cd33878ef3 100644
--- a/gcc/cfgcleanup.cc
+++ b/gcc/cfgcleanup.cc
@@ -2608,7 +2608,7 @@ bb_is_just_return (basic_block bb, rtx_insn **ret, 
rtx_insn **use)
   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
 return false;
 
-  FOR_BB_INSNS (bb, insn)
+  FOR_BB_INSNS_REVERSE (bb, insn)
 if (NONDEBUG_INSN_P (insn))
   {
rtx pat = PATTERN (insn);
-- 
2.35.3


[PATCH] rtl-optimization/109237 - quadraticness in delete_trivially_dead_insns

2023-03-22 Thread Richard Biener via Gcc-patches
The following addresses quadraticness in processing debug insns
in delete_trivially_dead_insns and insn_live_p by using TREE_VISITED
on the INSN_VAR_LOCATION_DECL to indicate a later debug bind
with the same decl and no intervening real insn or debug marker.
That gets rid of the NEXT_INSN walk in insn_live_p in favor of
first clearing TREE_VISITED in the first loop over insn and
the book-keeping of decls we set the bit since we need to clear
them when visiting a real or debug marker insn.

That improves the time spent in delete_trivially_dead_insns from
10.6s to 2.2s for the testcase.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

PR rtl-optimization/109237
* cse.cc (insn_live_p): Remove NEXT_INSN walk, instead check
TREE_VISITED on INSN_VAR_LOCATION_DECL.
(delete_trivially_dead_insns): Maintain TREE_VISITED on
active debug bind INSN_VAR_LOCATION_DECL.
---
 gcc/cse.cc | 39 ---
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/gcc/cse.cc b/gcc/cse.cc
index 8fbda4ecc86..204047b0e0b 100644
--- a/gcc/cse.cc
+++ b/gcc/cse.cc
@@ -6906,22 +6906,12 @@ insn_live_p (rtx_insn *insn, int *counts)
 }
   else if (DEBUG_INSN_P (insn))
 {
-  rtx_insn *next;
-
   if (DEBUG_MARKER_INSN_P (insn))
return true;
 
-  for (next = NEXT_INSN (insn); next; next = NEXT_INSN (next))
-   if (NOTE_P (next))
- continue;
-   else if (!DEBUG_INSN_P (next))
- return true;
-   /* If we find an inspection point, such as a debug begin stmt,
-  we want to keep the earlier debug insn.  */
-   else if (DEBUG_MARKER_INSN_P (next))
- return true;
-   else if (INSN_VAR_LOCATION_DECL (insn) == INSN_VAR_LOCATION_DECL (next))
- return false;
+  if (DEBUG_BIND_INSN_P (insn)
+ && TREE_VISITED (INSN_VAR_LOCATION_DECL (insn)))
+   return false;
 
   return true;
 }
@@ -7007,8 +6997,11 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg)
   counts = XCNEWVEC (int, nreg * 3);
   for (insn = insns; insn; insn = NEXT_INSN (insn))
if (DEBUG_BIND_INSN_P (insn))
- count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
-  NULL_RTX, 1);
+ {
+   count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
+NULL_RTX, 1);
+   TREE_VISITED (INSN_VAR_LOCATION_DECL (insn)) = 0;
+ }
else if (INSN_P (insn))
  {
count_reg_usage (insn, counts, NULL_RTX, 1);
@@ -7048,6 +7041,7 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg)
  the setter.  Then go through DEBUG_INSNs and if a DEBUG_EXPR
  has been created for the unused register, replace it with
  the DEBUG_EXPR, otherwise reset the DEBUG_INSN.  */
+  auto_vec later_debug_set_vars;
   for (insn = get_last_insn (); insn; insn = prev)
 {
   int live_insn = 0;
@@ -7110,6 +7104,21 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg)
}
  cse_cfg_altered |= delete_insn_and_edges (insn);
}
+  else
+   {
+ if (!DEBUG_INSN_P (insn) || DEBUG_MARKER_INSN_P (insn))
+   {
+ for (tree var : later_debug_set_vars)
+   TREE_VISITED (var) = 0;
+ later_debug_set_vars.truncate (0);
+   }
+ else if (DEBUG_BIND_INSN_P (insn)
+  && !TREE_VISITED (INSN_VAR_LOCATION_DECL (insn)))
+   {
+ later_debug_set_vars.safe_push (INSN_VAR_LOCATION_DECL (insn));
+ TREE_VISITED (INSN_VAR_LOCATION_DECL (insn)) = 1;
+   }
+   }
 }
 
   if (MAY_HAVE_DEBUG_BIND_INSNS)
-- 
2.35.3


[committed] MAINTAINERS: Add myself as OpenMP and libgomp maintainer

2023-03-22 Thread Tobias Burnus

Committed as r13-6798

Thanks for the trust – and additional workload ;-)

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
commit eb800d4f2f2b6790d337146013ac30bff8c56592
Author: Tobias Burnus 
Date:   Wed Mar 22 10:41:00 2023 +0100

MAINTAINERS: Add myself as OpenMP and libgomp maintainer

ChangeLog:
* MAINTAINERS: Add myself as OpenMP and libgomp maintainer.

diff --git a/MAINTAINERS b/MAINTAINERS
index 3c533cb651d..c8045d49861 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -179,6 +179,7 @@ fp-bit			Ian Lance Taylor	
 libgcc			Ian Lance Taylor	
 libgo			Ian Lance Taylor	
 libgomp			Jakub Jelinek		
+libgomp			Tobias Burnus		
 libgomp (OpenACC)	Thomas Schwinge		
 libiberty		Ian Lance Taylor	
 libitm			Torvald Riegel		
@@ -253,6 +254,7 @@ loop optimizer		Bin Cheng		
 OpenACC			Thomas Schwinge		
 OpenACC			Tobias Burnus		
 OpenMP			Jakub Jelinek		
+OpenMP			Tobias Burnus		
 testsuite		Rainer Orth		
 testsuite		Mike Stump		
 register allocation	Vladimir Makarov	


Re: [PATCH] range-op-float: Fix up -ffinite-math-only range extension and don't extend into infinities [PR109008]

2023-03-22 Thread Jakub Jelinek via Gcc-patches
On Wed, Mar 22, 2023 at 07:32:44AM +0100, Aldy Hernandez wrote:
> On 3/21/23 14:56, Jakub Jelinek wrote:
> > On Tue, Mar 21, 2023 at 02:49:49PM +0100, Aldy Hernandez wrote:
> > > So, this?
> > > 
> > > frange::set (tree type,
> > >   const REAL_VALUE_TYPE ,
> > >   const REAL_VALUE_TYPE ,
> > >   const nan_state &,
> > >   value_range_kind kind = VR_RANGE)
> > > 
> > > If so, I'll start poking at it.
> > 
> > Yes.
> > 
> > Jakub
> > 
> 
> Tested on x86-64 Linux.
> 
> OK?

Yes, thanks.

Jakub



Re: [PATCH][stage1] Remove conditionals around free()

2023-03-22 Thread Eric Gallager via Gcc-patches
On 3/4/23, Janne Blomqvist via Gcc-patches  wrote:
> On Wed, Mar 1, 2023 at 11:31 PM Bernhard Reutner-Fischer via Fortran
>  wrote:
>>
>> Hi!
>>
>> Mere cosmetics.
>>
>> - if (foo != NULL)
>> free (foo);
>>
>> With the caveat that coccinelle ruins replacement whitespace or i'm
>> uneducated enough to be unable to _not_ run the diff through
>>  sed -e 's/^+\([[:space:]]*\)free(/+\1free (/'
>> at least. If anybody knows how to improve replacement whitespace,
>> i'd be interrested but didn't look nor ask. ISTM that leading
>> whitespace is somewhat ruined, too, so beware (8 spaces versus tab as
>> far as i have spot-checked).
>>
>> Would touch
>>  gcc/ada/rtinit.c |3 +--
>>  intl/bindtextdom.c   |3 +--
>>  intl/loadmsgcat.c|6 ++
>>  intl/localcharset.c  |3 +--
>>  libbacktrace/xztest.c|9 +++--
>>  libbacktrace/zstdtest.c  |9 +++--
>>  libbacktrace/ztest.c |9 +++--
>>  libgfortran/caf/single.c |6 ++
>>  libgfortran/io/async.c   |6 ++
>>  libgfortran/io/format.c  |3 +--
>>  libgfortran/io/transfer.c|6 ++
>>  libgfortran/io/unix.c|3 +--
>>  libgo/runtime/go-setenv.c|6 ++
>>  libgo/runtime/go-unsetenv.c  |3 +--
>>  libgomp/target.c |3 +--
>>  libiberty/concat.c   |3 +--
>>  zlib/contrib/minizip/unzip.c |2 +-
>>  zlib/contrib/minizip/zip.c   |2 +-
>>  zlib/examples/enough.c   |6 ++
>>  zlib/examples/gun.c  |2 +-
>>  zlib/examples/gzjoin.c   |3 +--
>>  zlib/examples/gzlog.c|6 ++
>>
>> coccinelle script and invocation inline.
>> Would need to be split for the respective maintainers and run through
>> mklog with subject changelog and should of course be compiled and
>> tested before that.
>>
>> Remarks:
>> 1) We should do this in if-conversion (?) on our own.
>>I suppose. Independently of -fdelete-null-pointer-checks
>> 2) Maybe not silently, but raise language awareness nowadays.
>>By now it's been a long time since this was first mandated.
>> 3) fallout from looking at something completely different
>> 4) i most likely will not remember to split it apart and send proper
>>patches, tested patches, in stage 1 to maintainers proper, so if
>>anyone feels like pursuing this, be my guest. I thought i'd just
>>mention it.
>>
>> cheers,
>
> Back in 2011 Jim Meyering applied a patch doing this, see
> https://gcc.gnu.org/legacy-ml/gcc-patches/2011-03/msg00403.html , and
> the gcc/README.Portability snippet added then which is still there.
>
> Per analysis done then, it seems SunOS 4 was the last system where
> free() of a NULL pointer didn't behave per the spec.
>
> Also in Jim's patch intl/ and zlib/ directories were not touched as
> those are imported from other upstreams.
>

Speaking of which, this reminded me that I opened bug 80528 to catch
code like this as a compiler warning:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80528

> --
> Janne Blomqvist
>


Re: [PATCH] Remove TARGET_GEN_MEMSET_SCRATCH_RTX since it's not used anymore.

2023-03-22 Thread Uros Bizjak via Gcc-patches
On Wed, Mar 22, 2023 at 3:59 AM liuhongt  wrote:
>
> The target hook is only used by i386, and the current definition is
> same as default gen_reg_rtx. So there's no need for this target hook.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> Ok for trunk(or GCC14)?
>
> gcc/ChangeLog:
>
> * builtins.cc (builtin_memset_read_str): Replace
> targetm.gen_memset_scratch_rtx with gen_reg_rtx.
> (builtin_memset_gen_str): Ditto.
> * config/i386/i386-expand.cc
> (ix86_convert_const_wide_int_to_broadcast): Replace
> ix86_gen_scratch_sse_rtx with gen_reg_rtx.
> (ix86_expand_vector_move): Ditto.
> * config/i386/i386-protos.h (ix86_gen_scratch_sse_rtx):
> Removed.
> * config/i386/i386.cc (ix86_gen_scratch_sse_rtx): Removed.
> (TARGET_GEN_MEMSET_SCRATCH_RTX): Removed.
> * doc/tm.texi: Remove TARGET_GEN_MEMSET_SCRATCH_RTX.
> * doc/tm.texi.in: Ditto.
> * target.def: Ditto.

Looks trivial enough for gcc13, so OK for x86 part.

Needs also OK from a middle-end reviewer.

Thanks,
Uros.

> ---
>  gcc/builtins.cc|  4 ++--
>  gcc/config/i386/i386-expand.cc |  6 +++---
>  gcc/config/i386/i386-protos.h  |  2 --
>  gcc/config/i386/i386.cc| 12 
>  gcc/doc/tm.texi|  7 ---
>  gcc/doc/tm.texi.in |  2 --
>  gcc/target.def |  9 -
>  7 files changed, 5 insertions(+), 37 deletions(-)
>
> diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> index 90246e214d6..8026e2001b7 100644
> --- a/gcc/builtins.cc
> +++ b/gcc/builtins.cc
> @@ -4212,7 +4212,7 @@ builtin_memset_read_str (void *data, void *prev,
> return const_vec;
>
>/* Use the move expander with CONST_VECTOR.  */
> -  target = targetm.gen_memset_scratch_rtx (mode);
> +  target = gen_reg_rtx (mode);
>emit_move_insn (target, const_vec);
>return target;
>  }
> @@ -4256,7 +4256,7 @@ builtin_memset_gen_str (void *data, void *prev,
>  the memset expander.  */
>insn_code icode = optab_handler (vec_duplicate_optab, mode);
>
> -  target = targetm.gen_memset_scratch_rtx (mode);
> +  target = gen_reg_rtx (mode);
>class expand_operand ops[2];
>create_output_operand ([0], target, mode);
>create_input_operand ([1], (rtx) data, QImode);
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index c1300dc4e26..1e3ce4b7c3f 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -338,7 +338,7 @@ ix86_convert_const_wide_int_to_broadcast (machine_mode 
> mode, rtx op)
>machine_mode vector_mode;
>if (!mode_for_vector (broadcast_mode, nunits).exists (_mode))
>  gcc_unreachable ();
> -  rtx target = ix86_gen_scratch_sse_rtx (vector_mode);
> +  rtx target = gen_reg_rtx (vector_mode);
>bool ok = ix86_expand_vector_init_duplicate (false, vector_mode,
>target,
>GEN_INT (val_broadcast));
> @@ -686,7 +686,7 @@ ix86_expand_vector_move (machine_mode mode, rtx 
> operands[])
>if (!register_operand (op0, mode)
>   && !register_operand (op1, mode))
> {
> - rtx scratch = ix86_gen_scratch_sse_rtx (mode);
> + rtx scratch = gen_reg_rtx (mode);
>   emit_move_insn (scratch, op1);
>   op1 = scratch;
> }
> @@ -728,7 +728,7 @@ ix86_expand_vector_move (machine_mode mode, rtx 
> operands[])
>&& !register_operand (op0, mode)
>&& !register_operand (op1, mode))
>  {
> -  rtx tmp = ix86_gen_scratch_sse_rtx (GET_MODE (op0));
> +  rtx tmp = gen_reg_rtx (GET_MODE (op0));
>emit_move_insn (tmp, op1);
>emit_move_insn (op0, tmp);
>return;
> diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> index bfb2198265a..71ae95ffef7 100644
> --- a/gcc/config/i386/i386-protos.h
> +++ b/gcc/config/i386/i386-protos.h
> @@ -50,8 +50,6 @@ extern void ix86_reset_previous_fndecl (void);
>
>  extern bool ix86_using_red_zone (void);
>
> -extern rtx ix86_gen_scratch_sse_rtx (machine_mode);
> -
>  extern unsigned int ix86_regmode_natural_size (machine_mode);
>  extern bool ix86_check_builtin_isa_match (unsigned int fcode);
>  #ifdef RTX_CODE
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 5d0e4739a84..6a8734c2346 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -24197,15 +24197,6 @@ ix86_optab_supported_p (int op, machine_mode mode1, 
> machine_mode,
>  }
>  }
>
> -/* Implement the TARGET_GEN_MEMSET_SCRATCH_RTX hook.  Return a scratch
> -   register in MODE for vector load and store.  */
> -
> -rtx
> -ix86_gen_scratch_sse_rtx (machine_mode mode)
> -{
> -  return gen_reg_rtx (mode);
> -}
> -
>  /* Address space support.
>
> This is not "far pointers" in the 16-bit sense, but an easy way
> @@ 

Re: [PATCH] range-op-float: Fix up -ffinite-math-only range extension and don't extend into infinities [PR109008]

2023-03-22 Thread Aldy Hernandez via Gcc-patches



On 3/21/23 14:56, Jakub Jelinek wrote:

On Tue, Mar 21, 2023 at 02:49:49PM +0100, Aldy Hernandez wrote:

So, this?

frange::set (tree type,
const REAL_VALUE_TYPE ,
const REAL_VALUE_TYPE ,
const nan_state &,
value_range_kind kind = VR_RANGE)

If so, I'll start poking at it.


Yes.

Jakub



Tested on x86-64 Linux.

OK?
AldyFrom 64b9fabc0f31c661bb72029440227fe319566654 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez 
Date: Wed, 8 Mar 2023 10:58:01 +0100
Subject: [PATCH] frange: Implement nan_state class [PR109008]

This patch implements a nan_state class, that allows us to query or
pass around the NANness of an frange.  We can store +NAN, -NAN, +-NAN,
or not-a-NAN with it.

I tried to touch as little as possible, leaving other cleanups to the
next release.  For example, we should replace the m_*_nan fields in
frange with nan_state, and provide relevant accessors to nan_state
(isnan, etc).

gcc/ChangeLog:

	* value-range.cc (frange::set): Add nan_state argument.
	* value-range.h (class nan_state): New.
	(frange::get_nan_state): New.
---
 gcc/value-range.cc | 18 +++---
 gcc/value-range.h  | 62 ++
 2 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index a535337c47a..f71554b7d7c 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -284,7 +284,7 @@ frange::flush_denormals_to_zero ()
 void
 frange::set (tree type,
 	 const REAL_VALUE_TYPE , const REAL_VALUE_TYPE ,
-	 value_range_kind kind)
+	 const nan_state , value_range_kind kind)
 {
   switch (kind)
 {
@@ -316,8 +316,8 @@ frange::set (tree type,
   m_max = max;
   if (HONOR_NANS (m_type))
 {
-  m_pos_nan = true;
-  m_neg_nan = true;
+  m_pos_nan = nan.pos_p ();
+  m_neg_nan = nan.neg_p ();
 }
   else
 {
@@ -367,6 +367,18 @@ frange::set (tree type,
 verify_range ();
 }
 
+// Setter for an frange defaulting the NAN possibility to +-NAN when
+// HONOR_NANS.
+
+void
+frange::set (tree type,
+	 const REAL_VALUE_TYPE , const REAL_VALUE_TYPE ,
+	 value_range_kind kind)
+{
+  nan_state nan;
+  set (type, min, max, nan, kind);
+}
+
 void
 frange::set (tree min, tree max, value_range_kind kind)
 {
diff --git a/gcc/value-range.h b/gcc/value-range.h
index f4ac73b499f..ec50346826c 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -268,6 +268,56 @@ public:
   virtual void accept (const vrange_visitor ) const override;
 };
 
+// The NAN state as an opaque object.  The default constructor is +-NAN.
+
+class nan_state
+{
+public:
+  nan_state ();
+  nan_state (bool pos_nan, bool neg_nan);
+  bool neg_p () const;
+  bool pos_p () const;
+private:
+  bool m_pos_nan;
+  bool m_neg_nan;
+};
+
+// Default constructor initializing the object to +-NAN.
+
+inline
+nan_state::nan_state ()
+{
+  m_pos_nan = true;
+  m_neg_nan = true;
+}
+
+// Constructor initializing the object to +NAN if POS_NAN is set, -NAN
+// if NEG_NAN is set, or +-NAN if both are set.  Otherwise POS_NAN and
+// NEG_NAN are clear, and the object cannot be a NAN.
+
+inline
+nan_state::nan_state (bool pos_nan, bool neg_nan)
+{
+  m_pos_nan = pos_nan;
+  m_neg_nan = neg_nan;
+}
+
+// Return if +NAN is possible.
+
+inline bool
+nan_state::pos_p () const
+{
+  return m_pos_nan;
+}
+
+// Return if -NAN is possible.
+
+inline bool
+nan_state::neg_p () const
+{
+  return m_neg_nan;
+}
+
 // A floating point range.
 //
 // The representation is a type with a couple of endpoints, unioned
@@ -295,6 +345,8 @@ public:
   virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
 	value_range_kind = VR_RANGE);
+  void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
+	const nan_state &, value_range_kind = VR_RANGE);
   void set_nan (tree type);
   void set_nan (tree type, bool sign);
   virtual void set_varying (tree type) override;
@@ -315,9 +367,11 @@ public:
   bool operator!= (const frange ) const { return !(*this == r); }
   const REAL_VALUE_TYPE _bound () const;
   const REAL_VALUE_TYPE _bound () const;
+  nan_state get_nan_state () const;
   void update_nan ();
   void update_nan (bool sign);
   void update_nan (tree) = delete; // Disallow silent conversion to bool.
+  void update_nan (const nan_state &);
   void clear_nan ();
 
   // fpclassify like API
@@ -358,6 +412,14 @@ frange::upper_bound () const
   return m_max;
 }
 
+// Return the NAN state.
+
+inline nan_state
+frange::get_nan_state () const
+{
+  return nan_state (m_pos_nan, m_neg_nan);
+}
+
 // is_a<> and as_a<> implementation for vrange.
 
 // Anything we haven't specialized is a hard fail.
-- 
2.39.2