[PATCH v1] RISC-V: Add test for FP llceil auto vectorization

2023-10-13 Thread pan2 . li
From: Pan Li 

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

long long llceil (double);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-llceil-0.c: New test.

Signed-off-by: Pan Li 
---
 .../riscv/rvv/autovec/unop/math-llceil-0.c| 20 ++
 .../rvv/autovec/unop/math-llceil-run-0.c  | 64 +++
 .../riscv/rvv/autovec/vls/math-llceil-0.c | 30 +
 3 files changed, 114 insertions(+)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-llceil-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
new file mode 100644
index 000..3480c3ea91d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include 
+#include "test-math.h"
+
+/*
+** test_double_int64_t___builtin_llceil:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+3
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llceil)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
new file mode 100644
index 000..5ccbe64ffb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_v && rv64 } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include 
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+double in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llceil)
+TEST_ASSERT (int64_t)
+
+TEST_INIT_CVT (double, 1.2, int64_t, __builtin_llceil (1.2), 1)
+TEST_INIT_CVT (double, -1.2, int64_t, __builtin_llceil (-1.2), 2)
+TEST_INIT_CVT (double, 0.5, int64_t, __builtin_llceil (0.5), 3)
+TEST_INIT_CVT (double, -0.5, int64_t, __builtin_llceil (-0.5), 4)
+TEST_INIT_CVT (double, 0.1, int64_t, __builtin_llceil (0.1), 5)
+TEST_INIT_CVT (double, -0.1, int64_t, __builtin_llceil (-0.1), 6)
+TEST_INIT_CVT (double, 3.0, int64_t, __builtin_llceil (3.0), 7)
+TEST_INIT_CVT (double, -3.0, int64_t, __builtin_llceil (-3.0), 8)
+TEST_INIT_CVT (double, 4503599627370495.5, int64_t, __builtin_llceil 
(4503599627370495.5), 9)
+TEST_INIT_CVT (double, 4503599627370497.0, int64_t, __builtin_llceil 
(4503599627370497.0), 10)
+TEST_INIT_CVT (double, -4503599627370495.5, int64_t, __builtin_llceil 
(-4503599627370495.5), 11)
+TEST_INIT_CVT (double, -4503599627370496.0, int64_t, __builtin_llceil 
(-4503599627370496.0), 12)
+TEST_INIT_CVT (double, 0.0, int64_t, __builtin_llceil (-0.0), 13)
+TEST_INIT_CVT (double, -0.0, int64_t, __builtin_llceil (-0.0), 14)
+TEST_INIT_CVT (double, 9223372036854774784.0, int64_t, __builtin_llceil 
(9223372036854774784.0), 15)
+TEST_INIT_CVT (double, 9223372036854775808.0, int64_t, 0x7fff, 16)
+TEST_INIT_CVT (double, -9223372036854775808.0, int64_t, __builtin_llceil 
(-9223372036854775808.0), 17)
+TEST_INIT_CVT (double, -9223372036854777856.0, int64_t, 0x8000, 18)
+TEST_INIT_CVT (double, __builtin_inf (), int64_t, __builtin_llceil 
(__builtin_inf ()), 19)
+TEST_INIT_CVT (double, -__builtin_inf (), int64_t, __builtin_llceil 
(-__builtin_inf ()), 20)
+TEST_INIT_CVT (double, __builtin_nan (""), int64_t, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (double, int64_t, 1, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 2, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 3, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 4, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 5, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 6, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 7, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 8, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 9, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+

Re: [PATCH v1] RISC-V: Add test for FP llceil auto vectorization

2023-10-13 Thread juzhe.zh...@rivai.ai
OK



juzhe.zh...@rivai.ai
 
From: pan2.li
Date: 2023-10-13 15:20
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP llceil auto vectorization
From: Pan Li 
 
The below FP API are supported already by sharing the same standard
name, as well as the machine mode.
 
long long llceil (double);
 
This patch would like to add the test cases for ensuring the
correctness.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-llceil-0.c: New test.
 
Signed-off-by: Pan Li 
---
.../riscv/rvv/autovec/unop/math-llceil-0.c| 20 ++
.../rvv/autovec/unop/math-llceil-run-0.c  | 64 +++
.../riscv/rvv/autovec/vls/math-llceil-0.c | 30 +
3 files changed, 114 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-llceil-0.c
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
new file mode 100644
index 000..3480c3ea91d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include 
+#include "test-math.h"
+
+/*
+** test_double_int64_t___builtin_llceil:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+3
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llceil)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
new file mode 100644
index 000..5ccbe64ffb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_v && rv64 } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include 
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+double in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llceil)
+TEST_ASSERT (int64_t)
+
+TEST_INIT_CVT (double, 1.2, int64_t, __builtin_llceil (1.2), 1)
+TEST_INIT_CVT (double, -1.2, int64_t, __builtin_llceil (-1.2), 2)
+TEST_INIT_CVT (double, 0.5, int64_t, __builtin_llceil (0.5), 3)
+TEST_INIT_CVT (double, -0.5, int64_t, __builtin_llceil (-0.5), 4)
+TEST_INIT_CVT (double, 0.1, int64_t, __builtin_llceil (0.1), 5)
+TEST_INIT_CVT (double, -0.1, int64_t, __builtin_llceil (-0.1), 6)
+TEST_INIT_CVT (double, 3.0, int64_t, __builtin_llceil (3.0), 7)
+TEST_INIT_CVT (double, -3.0, int64_t, __builtin_llceil (-3.0), 8)
+TEST_INIT_CVT (double, 4503599627370495.5, int64_t, __builtin_llceil 
(4503599627370495.5), 9)
+TEST_INIT_CVT (double, 4503599627370497.0, int64_t, __builtin_llceil 
(4503599627370497.0), 10)
+TEST_INIT_CVT (double, -4503599627370495.5, int64_t, __builtin_llceil 
(-4503599627370495.5), 11)
+TEST_INIT_CVT (double, -4503599627370496.0, int64_t, __builtin_llceil 
(-4503599627370496.0), 12)
+TEST_INIT_CVT (double, 0.0, int64_t, __builtin_llceil (-0.0), 13)
+TEST_INIT_CVT (double, -0.0, int64_t, __builtin_llceil (-0.0), 14)
+TEST_INIT_CVT (double, 9223372036854774784.0, int64_t, __builtin_llceil 
(9223372036854774784.0), 15)
+TEST_INIT_CVT (double, 9223372036854775808.0, int64_t, 0x7fff, 16)
+TEST_INIT_CVT (double, -9223372036854775808.0, int64_t, __builtin_llceil 
(-9223372036854775808.0), 17)
+TEST_INIT_CVT (double, -9223372036854777856.0, int64_t, 0x8000, 18)
+TEST_INIT_CVT (double, __builtin_inf (), int64_t, __builtin_llceil 
(__builtin_inf ()), 19)
+TEST_INIT_CVT (double, -__builtin_inf (), int64_t, __builtin_llceil 
(-__builtin_inf ()), 20)
+TEST_INIT_CVT (double, __builtin_nan (""), int64_t, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (double, int64_t, 1, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 2, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 3, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 4, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 5, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 6, __builtin_llceil, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 7, __builtin_llceil, in, out, ref, 

RE: [PATCH v1] RISC-V: Add test for FP llceil auto vectorization

2023-10-13 Thread Li, Pan2
Committed, thanks Juzhe.

Pan

From: juzhe.zh...@rivai.ai 
Sent: Friday, October 13, 2023 3:33 PM
To: Li, Pan2 ; gcc-patches 
Cc: Li, Pan2 ; Wang, Yanzhang ; 
kito.cheng 
Subject: Re: [PATCH v1] RISC-V: Add test for FP llceil auto vectorization

OK


juzhe.zh...@rivai.ai

From: pan2.li
Date: 2023-10-13 15:20
To: gcc-patches
CC: juzhe.zhong; 
pan2.li; 
yanzhang.wang; 
kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP llceil auto vectorization
From: Pan Li mailto:pan2...@intel.com>>

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

long long llceil (double);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-llceil-0.c: New test.

Signed-off-by: Pan Li mailto:pan2...@intel.com>>
---
.../riscv/rvv/autovec/unop/math-llceil-0.c| 20 ++
.../rvv/autovec/unop/math-llceil-run-0.c  | 64 +++
.../riscv/rvv/autovec/vls/math-llceil-0.c | 30 +
3 files changed, 114 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-llceil-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
new file mode 100644
index 000..3480c3ea91d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-0.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include 
+#include "test-math.h"
+
+/*
+** test_double_int64_t___builtin_llceil:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+3
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llceil)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
new file mode 100644
index 000..5ccbe64ffb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llceil-run-0.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_v && rv64 } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include 
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+double in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llceil)
+TEST_ASSERT (int64_t)
+
+TEST_INIT_CVT (double, 1.2, int64_t, __builtin_llceil (1.2), 1)
+TEST_INIT_CVT (double, -1.2, int64_t, __builtin_llceil (-1.2), 2)
+TEST_INIT_CVT (double, 0.5, int64_t, __builtin_llceil (0.5), 3)
+TEST_INIT_CVT (double, -0.5, int64_t, __builtin_llceil (-0.5), 4)
+TEST_INIT_CVT (double, 0.1, int64_t, __builtin_llceil (0.1), 5)
+TEST_INIT_CVT (double, -0.1, int64_t, __builtin_llceil (-0.1), 6)
+TEST_INIT_CVT (double, 3.0, int64_t, __builtin_llceil (3.0), 7)
+TEST_INIT_CVT (double, -3.0, int64_t, __builtin_llceil (-3.0), 8)
+TEST_INIT_CVT (double, 4503599627370495.5, int64_t, __builtin_llceil 
(4503599627370495.5), 9)
+TEST_INIT_CVT (double, 4503599627370497.0, int64_t, __builtin_llceil 
(4503599627370497.0), 10)
+TEST_INIT_CVT (double, -4503599627370495.5, int64_t, __builtin_llceil 
(-4503599627370495.5), 11)
+TEST_INIT_CVT (double, -4503599627370496.0, int64_t, __builtin_llceil 
(-4503599627370496.0), 12)
+TEST_INIT_CVT (double, 0.0, int64_t, __builtin_llceil (-0.0), 13)
+TEST_INIT_CVT (double, -0.0, int64_t, __builtin_llceil (-0.0), 14)
+TEST_INIT_CVT (double, 9223372036854774784.0, int64_t, __builtin_llceil 
(9223372036854774784.0), 15)
+TEST_INIT_CVT (double, 9223372036854775808.0, int64_t, 0x7fff, 16)
+TEST_INIT_CVT (double, -9223372036854775808.0, int64_t, __builtin_llceil 
(-9223372036854775808.0), 17)
+TEST_INIT_CVT (double, -9223372036854777856.0, int64_t, 0x8000, 18)
+TEST_INIT_CVT (double, __builtin_inf (), int64_t, __builtin_llceil 
(__builtin_inf ()), 19)
+TEST_INIT_CVT (double, -__builtin_inf (), int64_t, __builtin_llceil 
(-__builtin_inf ()), 20)
+TEST_INIT_CVT (double, __builtin_nan (""), int64_t, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (double, int64_t, 1, __bu

[PATCH v1] RISC-V: Add test for FP iceil auto vectorization

2023-10-13 Thread pan2 . li
From: Pan Li 

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

int iceil (float);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-iceil-0.c: New test.

Signed-off-by: Pan Li 
---
 .../riscv/rvv/autovec/unop/math-iceil-0.c | 19 ++
 .../riscv/rvv/autovec/unop/math-iceil-run-0.c | 63 +++
 .../riscv/rvv/autovec/vls/math-iceil-0.c  | 30 +
 3 files changed, 112 insertions(+)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-iceil-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
new file mode 100644
index 000..2d4a1d163d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "test-math.h"
+
+/*
+** test_float_int___builtin_iceilf:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+3
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (float, int, __builtin_iceilf)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
new file mode 100644
index 000..714173a7f8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int out[ARRAY_SIZE];
+int ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int, __builtin_iceilf)
+TEST_ASSERT (int)
+
+TEST_INIT_CVT (float, 1.2, int, __builtin_iceilf (1.2), 1)
+TEST_INIT_CVT (float, -1.2, int, __builtin_iceilf (-1.2), 2)
+TEST_INIT_CVT (float, 0.5, int, __builtin_iceilf (0.5), 3)
+TEST_INIT_CVT (float, -0.5, int, __builtin_iceilf (-0.5), 4)
+TEST_INIT_CVT (float, 0.1, int, __builtin_iceilf (0.1), 5)
+TEST_INIT_CVT (float, -0.1, int, __builtin_iceilf (-0.1), 6)
+TEST_INIT_CVT (float, 3.0, int, __builtin_iceilf (3.0), 7)
+TEST_INIT_CVT (float, -3.0, int, __builtin_iceilf (-3.0), 8)
+TEST_INIT_CVT (float, 8388607.5, int, __builtin_iceilf (8388607.5), 9)
+TEST_INIT_CVT (float, 8388609.0, int, __builtin_iceilf (8388609.0), 10)
+TEST_INIT_CVT (float, -8388607.5, int, __builtin_iceilf (-8388607.5), 11)
+TEST_INIT_CVT (float, -8388609.0, int, __builtin_iceilf (-8388609.0), 12)
+TEST_INIT_CVT (float, 0.0, int, __builtin_iceilf (-0.0), 13)
+TEST_INIT_CVT (float, -0.0, int, __builtin_iceilf (-0.0), 14)
+TEST_INIT_CVT (float, 2147483520.0, int, __builtin_iceilf (2147483520.0), 15)
+TEST_INIT_CVT (float, 2147483648.0, int, 0x7fff, 16)
+TEST_INIT_CVT (float, -2147483648.0, int, __builtin_iceilf (-2147483648.0), 17)
+TEST_INIT_CVT (float, -2147483904.0, int, 0x8000, 18)
+TEST_INIT_CVT (float, __builtin_inf (), int, __builtin_iceilf (__builtin_inff 
()), 19)
+TEST_INIT_CVT (float, -__builtin_inf (), int, __builtin_iceilf 
(-__builtin_inff ()), 20)
+TEST_INIT_CVT (float, __builtin_nanf (""), int, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (float, int, 1, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 2, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 3, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 4, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 5, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 6, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 7, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 8, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 9, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 10, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 11, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 12, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 13, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 14, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+ 

Re: [PATCH v1] RISC-V: Add test for FP iceil auto vectorization

2023-10-13 Thread juzhe.zh...@rivai.ai
Ok



juzhe.zh...@rivai.ai
 
From: pan2.li
Date: 2023-10-13 16:06
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP iceil auto vectorization
From: Pan Li 
 
The below FP API are supported already by sharing the same standard
name, as well as the machine mode.
 
int iceil (float);
 
This patch would like to add the test cases for ensuring the
correctness.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-iceil-0.c: New test.
 
Signed-off-by: Pan Li 
---
.../riscv/rvv/autovec/unop/math-iceil-0.c | 19 ++
.../riscv/rvv/autovec/unop/math-iceil-run-0.c | 63 +++
.../riscv/rvv/autovec/vls/math-iceil-0.c  | 30 +
3 files changed, 112 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-iceil-0.c
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
new file mode 100644
index 000..2d4a1d163d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "test-math.h"
+
+/*
+** test_float_int___builtin_iceilf:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+3
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (float, int, __builtin_iceilf)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
new file mode 100644
index 000..714173a7f8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int out[ARRAY_SIZE];
+int ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int, __builtin_iceilf)
+TEST_ASSERT (int)
+
+TEST_INIT_CVT (float, 1.2, int, __builtin_iceilf (1.2), 1)
+TEST_INIT_CVT (float, -1.2, int, __builtin_iceilf (-1.2), 2)
+TEST_INIT_CVT (float, 0.5, int, __builtin_iceilf (0.5), 3)
+TEST_INIT_CVT (float, -0.5, int, __builtin_iceilf (-0.5), 4)
+TEST_INIT_CVT (float, 0.1, int, __builtin_iceilf (0.1), 5)
+TEST_INIT_CVT (float, -0.1, int, __builtin_iceilf (-0.1), 6)
+TEST_INIT_CVT (float, 3.0, int, __builtin_iceilf (3.0), 7)
+TEST_INIT_CVT (float, -3.0, int, __builtin_iceilf (-3.0), 8)
+TEST_INIT_CVT (float, 8388607.5, int, __builtin_iceilf (8388607.5), 9)
+TEST_INIT_CVT (float, 8388609.0, int, __builtin_iceilf (8388609.0), 10)
+TEST_INIT_CVT (float, -8388607.5, int, __builtin_iceilf (-8388607.5), 11)
+TEST_INIT_CVT (float, -8388609.0, int, __builtin_iceilf (-8388609.0), 12)
+TEST_INIT_CVT (float, 0.0, int, __builtin_iceilf (-0.0), 13)
+TEST_INIT_CVT (float, -0.0, int, __builtin_iceilf (-0.0), 14)
+TEST_INIT_CVT (float, 2147483520.0, int, __builtin_iceilf (2147483520.0), 15)
+TEST_INIT_CVT (float, 2147483648.0, int, 0x7fff, 16)
+TEST_INIT_CVT (float, -2147483648.0, int, __builtin_iceilf (-2147483648.0), 17)
+TEST_INIT_CVT (float, -2147483904.0, int, 0x8000, 18)
+TEST_INIT_CVT (float, __builtin_inf (), int, __builtin_iceilf (__builtin_inff 
()), 19)
+TEST_INIT_CVT (float, -__builtin_inf (), int, __builtin_iceilf 
(-__builtin_inff ()), 20)
+TEST_INIT_CVT (float, __builtin_nanf (""), int, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (float, int, 1, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 2, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 3, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 4, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 5, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 6, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 7, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 8, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 9, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 10, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 11, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 12, __builtin_iceilf, in, out

RE: [PATCH v1] RISC-V: Add test for FP iceil auto vectorization

2023-10-13 Thread Li, Pan2
Committed, thanks Juzhe.

Pan

From: juzhe.zh...@rivai.ai 
Sent: Friday, October 13, 2023 4:08 PM
To: Li, Pan2 ; gcc-patches 
Cc: Li, Pan2 ; Wang, Yanzhang ; 
kito.cheng 
Subject: Re: [PATCH v1] RISC-V: Add test for FP iceil auto vectorization

Ok


juzhe.zh...@rivai.ai

From: pan2.li
Date: 2023-10-13 16:06
To: gcc-patches
CC: juzhe.zhong; 
pan2.li; 
yanzhang.wang; 
kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP iceil auto vectorization
From: Pan Li mailto:pan2...@intel.com>>

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

int iceil (float);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-iceil-0.c: New test.

Signed-off-by: Pan Li mailto:pan2...@intel.com>>
---
.../riscv/rvv/autovec/unop/math-iceil-0.c | 19 ++
.../riscv/rvv/autovec/unop/math-iceil-run-0.c | 63 +++
.../riscv/rvv/autovec/vls/math-iceil-0.c  | 30 +
3 files changed, 112 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-iceil-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
new file mode 100644
index 000..2d4a1d163d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-0.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "test-math.h"
+
+/*
+** test_float_int___builtin_iceilf:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+3
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (float, int, __builtin_iceilf)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
new file mode 100644
index 000..714173a7f8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-iceil-run-0.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int out[ARRAY_SIZE];
+int ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int, __builtin_iceilf)
+TEST_ASSERT (int)
+
+TEST_INIT_CVT (float, 1.2, int, __builtin_iceilf (1.2), 1)
+TEST_INIT_CVT (float, -1.2, int, __builtin_iceilf (-1.2), 2)
+TEST_INIT_CVT (float, 0.5, int, __builtin_iceilf (0.5), 3)
+TEST_INIT_CVT (float, -0.5, int, __builtin_iceilf (-0.5), 4)
+TEST_INIT_CVT (float, 0.1, int, __builtin_iceilf (0.1), 5)
+TEST_INIT_CVT (float, -0.1, int, __builtin_iceilf (-0.1), 6)
+TEST_INIT_CVT (float, 3.0, int, __builtin_iceilf (3.0), 7)
+TEST_INIT_CVT (float, -3.0, int, __builtin_iceilf (-3.0), 8)
+TEST_INIT_CVT (float, 8388607.5, int, __builtin_iceilf (8388607.5), 9)
+TEST_INIT_CVT (float, 8388609.0, int, __builtin_iceilf (8388609.0), 10)
+TEST_INIT_CVT (float, -8388607.5, int, __builtin_iceilf (-8388607.5), 11)
+TEST_INIT_CVT (float, -8388609.0, int, __builtin_iceilf (-8388609.0), 12)
+TEST_INIT_CVT (float, 0.0, int, __builtin_iceilf (-0.0), 13)
+TEST_INIT_CVT (float, -0.0, int, __builtin_iceilf (-0.0), 14)
+TEST_INIT_CVT (float, 2147483520.0, int, __builtin_iceilf (2147483520.0), 15)
+TEST_INIT_CVT (float, 2147483648.0, int, 0x7fff, 16)
+TEST_INIT_CVT (float, -2147483648.0, int, __builtin_iceilf (-2147483648.0), 17)
+TEST_INIT_CVT (float, -2147483904.0, int, 0x8000, 18)
+TEST_INIT_CVT (float, __builtin_inf (), int, __builtin_iceilf (__builtin_inff 
()), 19)
+TEST_INIT_CVT (float, -__builtin_inf (), int, __builtin_iceilf 
(-__builtin_inff ()), 20)
+TEST_INIT_CVT (float, __builtin_nanf (""), int, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (float, int, 1, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 2, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 3, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 4, __builtin_iceilf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 5, __builtin_iceilf, in, out, ref, ARRAY_SIZ

[PATCH v1] RISC-V: Add test for FP ifloor auto vectorization

2023-10-13 Thread pan2 . li
From: Pan Li 

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

int ifloor (float);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-ifloor-0.c: New test.

Signed-off-by: Pan Li 
---
 .../riscv/rvv/autovec/unop/math-ifloor-0.c| 19 ++
 .../rvv/autovec/unop/math-ifloor-run-0.c  | 63 +++
 .../riscv/rvv/autovec/vls/math-ifloor-0.c | 30 +
 3 files changed, 112 insertions(+)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-ifloor-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
new file mode 100644
index 000..b9ec415d690
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "test-math.h"
+
+/*
+** test_float_int___builtin_ifloorf:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+2
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (float, int, __builtin_ifloorf)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
new file mode 100644
index 000..8ef4da0ea88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int out[ARRAY_SIZE];
+int ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int, __builtin_ifloorf)
+TEST_ASSERT (int)
+
+TEST_INIT_CVT (float, 1.2, int, __builtin_ifloorf (1.2), 1)
+TEST_INIT_CVT (float, -1.2, int, __builtin_ifloorf (-1.2), 2)
+TEST_INIT_CVT (float, 0.5, int, __builtin_ifloorf (0.5), 3)
+TEST_INIT_CVT (float, -0.5, int, __builtin_ifloorf (-0.5), 4)
+TEST_INIT_CVT (float, 0.1, int, __builtin_ifloorf (0.1), 5)
+TEST_INIT_CVT (float, -0.1, int, __builtin_ifloorf (-0.1), 6)
+TEST_INIT_CVT (float, 3.0, int, __builtin_ifloorf (3.0), 7)
+TEST_INIT_CVT (float, -3.0, int, __builtin_ifloorf (-3.0), 8)
+TEST_INIT_CVT (float, 8388607.5, int, __builtin_ifloorf (8388607.5), 9)
+TEST_INIT_CVT (float, 8388609.0, int, __builtin_ifloorf (8388609.0), 10)
+TEST_INIT_CVT (float, -8388607.5, int, __builtin_ifloorf (-8388607.5), 11)
+TEST_INIT_CVT (float, -8388609.0, int, __builtin_ifloorf (-8388609.0), 12)
+TEST_INIT_CVT (float, 0.0, int, __builtin_ifloorf (-0.0), 13)
+TEST_INIT_CVT (float, -0.0, int, __builtin_ifloorf (-0.0), 14)
+TEST_INIT_CVT (float, 2147483520.0, int, __builtin_ifloorf (2147483520.0), 15)
+TEST_INIT_CVT (float, 2147483648.0, int, 0x7fff, 16)
+TEST_INIT_CVT (float, -2147483648.0, int, __builtin_ifloorf (-2147483648.0), 
17)
+TEST_INIT_CVT (float, -2147483904.0, int, 0x8000, 18)
+TEST_INIT_CVT (float, __builtin_inf (), int, __builtin_ifloorf (__builtin_inff 
()), 19)
+TEST_INIT_CVT (float, -__builtin_inf (), int, __builtin_ifloorf 
(-__builtin_inff ()), 20)
+TEST_INIT_CVT (float, __builtin_nanf (""), int, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (float, int, 1, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 2, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 3, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 4, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 5, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 6, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 7, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 8, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 9, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 10, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 11, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 12, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 13, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 14

Re: [PATCH v1] RISC-V: Add test for FP ifloor auto vectorization

2023-10-13 Thread juzhe.zh...@rivai.ai
OK



juzhe.zh...@rivai.ai
 
From: pan2.li
Date: 2023-10-13 16:23
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP ifloor auto vectorization
From: Pan Li 
 
The below FP API are supported already by sharing the same standard
name, as well as the machine mode.
 
int ifloor (float);
 
This patch would like to add the test cases for ensuring the
correctness.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-ifloor-0.c: New test.
 
Signed-off-by: Pan Li 
---
.../riscv/rvv/autovec/unop/math-ifloor-0.c| 19 ++
.../rvv/autovec/unop/math-ifloor-run-0.c  | 63 +++
.../riscv/rvv/autovec/vls/math-ifloor-0.c | 30 +
3 files changed, 112 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-ifloor-0.c
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
new file mode 100644
index 000..b9ec415d690
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "test-math.h"
+
+/*
+** test_float_int___builtin_ifloorf:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+2
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (float, int, __builtin_ifloorf)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
new file mode 100644
index 000..8ef4da0ea88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int out[ARRAY_SIZE];
+int ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int, __builtin_ifloorf)
+TEST_ASSERT (int)
+
+TEST_INIT_CVT (float, 1.2, int, __builtin_ifloorf (1.2), 1)
+TEST_INIT_CVT (float, -1.2, int, __builtin_ifloorf (-1.2), 2)
+TEST_INIT_CVT (float, 0.5, int, __builtin_ifloorf (0.5), 3)
+TEST_INIT_CVT (float, -0.5, int, __builtin_ifloorf (-0.5), 4)
+TEST_INIT_CVT (float, 0.1, int, __builtin_ifloorf (0.1), 5)
+TEST_INIT_CVT (float, -0.1, int, __builtin_ifloorf (-0.1), 6)
+TEST_INIT_CVT (float, 3.0, int, __builtin_ifloorf (3.0), 7)
+TEST_INIT_CVT (float, -3.0, int, __builtin_ifloorf (-3.0), 8)
+TEST_INIT_CVT (float, 8388607.5, int, __builtin_ifloorf (8388607.5), 9)
+TEST_INIT_CVT (float, 8388609.0, int, __builtin_ifloorf (8388609.0), 10)
+TEST_INIT_CVT (float, -8388607.5, int, __builtin_ifloorf (-8388607.5), 11)
+TEST_INIT_CVT (float, -8388609.0, int, __builtin_ifloorf (-8388609.0), 12)
+TEST_INIT_CVT (float, 0.0, int, __builtin_ifloorf (-0.0), 13)
+TEST_INIT_CVT (float, -0.0, int, __builtin_ifloorf (-0.0), 14)
+TEST_INIT_CVT (float, 2147483520.0, int, __builtin_ifloorf (2147483520.0), 15)
+TEST_INIT_CVT (float, 2147483648.0, int, 0x7fff, 16)
+TEST_INIT_CVT (float, -2147483648.0, int, __builtin_ifloorf (-2147483648.0), 
17)
+TEST_INIT_CVT (float, -2147483904.0, int, 0x8000, 18)
+TEST_INIT_CVT (float, __builtin_inf (), int, __builtin_ifloorf (__builtin_inff 
()), 19)
+TEST_INIT_CVT (float, -__builtin_inf (), int, __builtin_ifloorf 
(-__builtin_inff ()), 20)
+TEST_INIT_CVT (float, __builtin_nanf (""), int, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (float, int, 1, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 2, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 3, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 4, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 5, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 6, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 7, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 8, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 9, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 10, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 11, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TE

PATCH-1v3, expand] Enable vector mode for compare_by_pieces [PR111449]

2023-10-13 Thread HAO CHEN GUI
Hi,
  Vector mode instructions are efficient for compare on some targets.
This patch enables vector mode for compare_by_pieces. Currently,
vector mode is enabled for compare, set and clear. Helper function
"qi_vector_p" decides if vector mode is enabled for certain by pieces
operation. optabs_checking checks if optabs are available for the
mode and certain by pieces operations. Both of them are called in
fixed_size_mode finding functions. A member is added to class
op_by_pieces_d in order to record the type of by pieces operations.

  The test case is in the second patch which is rs6000 specific.

  Compared to last version, the main change is to create two helper
functions and call them in mode finding function.

  Bootstrapped and tested on x86 and powerpc64-linux BE and LE with no
regressions.

Thanks
Gui Haochen

ChangeLog
Expand: Enable vector mode for pieces compares

Vector mode compare instructions are efficient for equality compare on
rs6000. This patch refactors the codes of pieces operation to enable
vector mode for compare.

gcc/
PR target/111449
* expr.cc (qi_vector_p): New function to indicate if vector mode
is enabled for certain by pieces operations.
(optabs_checking): New function to check if optabs are available
for certain by pieces operations.
(widest_fixed_size_mode_for_size): Replace the second argument
with the type of by pieces operations.  Call qi_vector_p to check
if vector mode is enable.  Call optabs_checking to check if optabs
are available for the candidate vector mode.
(by_pieces_ninsns): Pass the type of by pieces operation to
widest_fixed_size_mode_for_size.
(class op_by_pieces_d): Add a protected member m_op to record the
type of by pieces operations.  Declare member function
fixed_size_mode widest_fixed_size_mode_for_size.
(op_by_pieces_d::op_by_pieces_d): Change last argument to the type
of by pieces operations, initialize m_op with it.  Call non-member
function widest_fixed_size_mode_for_size.
(op_by_pieces_d::get_usable_mode): Call member function
widest_fixed_size_mode_for_size.
(op_by_pieces_d::smallest_fixed_size_mode_for_size): Call
qi_vector_p to check if vector mode is enable.  Call
optabs_checking to check if optabs are available for the candidate
vector mode.
(op_by_pieces_d::run): Call member function
widest_fixed_size_mode_for_size.
(op_by_pieces_d::widest_fixed_size_mode_for_size): Implement.
(move_by_pieces_d::move_by_pieces_d): Set m_op to MOVE_BY_PIECES.
(store_by_pieces_d::store_by_pieces_d): Set m_op with the op.
(can_store_by_pieces): Pass the type of by pieces operations to
widest_fixed_size_mode_for_size.
(clear_by_pieces): Initialize class store_by_pieces_d with
CLEAR_BY_PIECES.
(compare_by_pieces_d::compare_by_pieces_d): Set m_op to
COMPARE_BY_PIECES.

patch.diff
diff --git a/gcc/expr.cc b/gcc/expr.cc
index d87346dc07f..8ec3f5465a9 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -988,18 +988,43 @@ alignment_for_piecewise_move (unsigned int max_pieces, 
unsigned int align)
   return align;
 }

-/* Return the widest QI vector, if QI_MODE is true, or integer mode
-   that is narrower than SIZE bytes.  */
+/* Return true if vector mode is enabled for the op.  */
+static bool
+qi_vector_p (by_pieces_operation op)
+{
+  return (op == COMPARE_BY_PIECES
+ || op == SET_BY_PIECES
+ || op == CLEAR_BY_PIECES);
+}
+
+/* Return true if optabs are available for the mode and by pieces
+   operations.  */
+static bool
+optabs_checking (fixed_size_mode mode, by_pieces_operation op)
+{
+  if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
+  && optab_handler (vec_duplicate_optab, mode) != CODE_FOR_nothing)
+return true;
+  else if (op == COMPARE_BY_PIECES
+  && optab_handler (mov_optab, mode) != CODE_FOR_nothing
+  && can_compare_p (EQ, mode, ccp_jump))
+return true;
+
+  return false;
+}
+
+/* Return the widest QI vector, if vector mode is enabled for the op,
+   or integer mode that is narrower than SIZE bytes.  */

 static fixed_size_mode
-widest_fixed_size_mode_for_size (unsigned int size, bool qi_vector)
+widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
 {
   fixed_size_mode result = NARROWEST_INT_MODE;

   gcc_checking_assert (size > 1);

   /* Use QI vector only if size is wider than a WORD.  */
-  if (qi_vector && size > UNITS_PER_WORD)
+  if (qi_vector_p (op) && size > UNITS_PER_WORD)
 {
   machine_mode mode;
   fixed_size_mode candidate;
@@ -1009,8 +1034,7 @@ widest_fixed_size_mode_for_size (unsigned int size, bool 
qi_vector)
  {
if (GET_MODE_SIZE (candidate) >= size)
  break;
-   if (optab_handler (vec_duplicate_optab, candidate)
-   != CODE_FOR_nothing)
+  

RE: [PATCH v1] RISC-V: Add test for FP ifloor auto vectorization

2023-10-13 Thread Li, Pan2
Committed, thanks Juzhe.

Pan

From: juzhe.zh...@rivai.ai 
Sent: Friday, October 13, 2023 4:42 PM
To: Li, Pan2 ; gcc-patches 
Cc: Li, Pan2 ; Wang, Yanzhang ; 
kito.cheng 
Subject: Re: [PATCH v1] RISC-V: Add test for FP ifloor auto vectorization

OK


juzhe.zh...@rivai.ai

From: pan2.li
Date: 2023-10-13 16:23
To: gcc-patches
CC: juzhe.zhong; 
pan2.li; 
yanzhang.wang; 
kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP ifloor auto vectorization
From: Pan Li mailto:pan2...@intel.com>>

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

int ifloor (float);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-ifloor-0.c: New test.

Signed-off-by: Pan Li mailto:pan2...@intel.com>>
---
.../riscv/rvv/autovec/unop/math-ifloor-0.c| 19 ++
.../rvv/autovec/unop/math-ifloor-run-0.c  | 63 +++
.../riscv/rvv/autovec/vls/math-ifloor-0.c | 30 +
3 files changed, 112 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-ifloor-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
new file mode 100644
index 000..b9ec415d690
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-0.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "test-math.h"
+
+/*
+** test_float_int___builtin_ifloorf:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+2
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (float, int, __builtin_ifloorf)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
new file mode 100644
index 000..8ef4da0ea88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ifloor-run-0.c
@@ -0,0 +1,63 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+float in[ARRAY_SIZE];
+int out[ARRAY_SIZE];
+int ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (float, int, __builtin_ifloorf)
+TEST_ASSERT (int)
+
+TEST_INIT_CVT (float, 1.2, int, __builtin_ifloorf (1.2), 1)
+TEST_INIT_CVT (float, -1.2, int, __builtin_ifloorf (-1.2), 2)
+TEST_INIT_CVT (float, 0.5, int, __builtin_ifloorf (0.5), 3)
+TEST_INIT_CVT (float, -0.5, int, __builtin_ifloorf (-0.5), 4)
+TEST_INIT_CVT (float, 0.1, int, __builtin_ifloorf (0.1), 5)
+TEST_INIT_CVT (float, -0.1, int, __builtin_ifloorf (-0.1), 6)
+TEST_INIT_CVT (float, 3.0, int, __builtin_ifloorf (3.0), 7)
+TEST_INIT_CVT (float, -3.0, int, __builtin_ifloorf (-3.0), 8)
+TEST_INIT_CVT (float, 8388607.5, int, __builtin_ifloorf (8388607.5), 9)
+TEST_INIT_CVT (float, 8388609.0, int, __builtin_ifloorf (8388609.0), 10)
+TEST_INIT_CVT (float, -8388607.5, int, __builtin_ifloorf (-8388607.5), 11)
+TEST_INIT_CVT (float, -8388609.0, int, __builtin_ifloorf (-8388609.0), 12)
+TEST_INIT_CVT (float, 0.0, int, __builtin_ifloorf (-0.0), 13)
+TEST_INIT_CVT (float, -0.0, int, __builtin_ifloorf (-0.0), 14)
+TEST_INIT_CVT (float, 2147483520.0, int, __builtin_ifloorf (2147483520.0), 15)
+TEST_INIT_CVT (float, 2147483648.0, int, 0x7fff, 16)
+TEST_INIT_CVT (float, -2147483648.0, int, __builtin_ifloorf (-2147483648.0), 
17)
+TEST_INIT_CVT (float, -2147483904.0, int, 0x8000, 18)
+TEST_INIT_CVT (float, __builtin_inf (), int, __builtin_ifloorf (__builtin_inff 
()), 19)
+TEST_INIT_CVT (float, -__builtin_inf (), int, __builtin_ifloorf 
(-__builtin_inff ()), 20)
+TEST_INIT_CVT (float, __builtin_nanf (""), int, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (float, int, 1, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 2, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 3, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 4, __builtin_ifloorf, in, out, ref, ARRAY_SIZE);
+  RUN_TEST_CVT (float, int, 5

[PATCH v1] RISC-V: Add test for FP llfloor auto vectorization

2023-10-13 Thread pan2 . li
From: Pan Li 

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

long long llfloor (double);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-llfloor-0.c: New test.

Signed-off-by: Pan Li 
---
 .../riscv/rvv/autovec/unop/math-llfloor-0.c   | 20 ++
 .../rvv/autovec/unop/math-llfloor-run-0.c | 64 +++
 .../riscv/rvv/autovec/vls/math-llfloor-0.c| 30 +
 3 files changed, 114 insertions(+)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-llfloor-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
new file mode 100644
index 000..4b10f966015
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include 
+#include "test-math.h"
+
+/*
+** test_double_int64_t___builtin_llfloor:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+2
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llfloor)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
new file mode 100644
index 000..22829132e96
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_v && rv64 } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include 
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+double in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llfloor)
+TEST_ASSERT (int64_t)
+
+TEST_INIT_CVT (double, 1.2, int64_t, __builtin_llfloor (1.2), 1)
+TEST_INIT_CVT (double, -1.2, int64_t, __builtin_llfloor (-1.2), 2)
+TEST_INIT_CVT (double, 0.5, int64_t, __builtin_llfloor (0.5), 3)
+TEST_INIT_CVT (double, -0.5, int64_t, __builtin_llfloor (-0.5), 4)
+TEST_INIT_CVT (double, 0.1, int64_t, __builtin_llfloor (0.1), 5)
+TEST_INIT_CVT (double, -0.1, int64_t, __builtin_llfloor (-0.1), 6)
+TEST_INIT_CVT (double, 3.0, int64_t, __builtin_llfloor (3.0), 7)
+TEST_INIT_CVT (double, -3.0, int64_t, __builtin_llfloor (-3.0), 8)
+TEST_INIT_CVT (double, 4503599627370495.5, int64_t, __builtin_llfloor 
(4503599627370495.5), 9)
+TEST_INIT_CVT (double, 4503599627370497.0, int64_t, __builtin_llfloor 
(4503599627370497.0), 10)
+TEST_INIT_CVT (double, -4503599627370495.5, int64_t, __builtin_llfloor 
(-4503599627370495.5), 11)
+TEST_INIT_CVT (double, -4503599627370496.0, int64_t, __builtin_llfloor 
(-4503599627370496.0), 12)
+TEST_INIT_CVT (double, 0.0, int64_t, __builtin_llfloor (-0.0), 13)
+TEST_INIT_CVT (double, -0.0, int64_t, __builtin_llfloor (-0.0), 14)
+TEST_INIT_CVT (double, 9223372036854774784.0, int64_t, __builtin_llfloor 
(9223372036854774784.0), 15)
+TEST_INIT_CVT (double, 9223372036854775808.0, int64_t, 0x7fff, 16)
+TEST_INIT_CVT (double, -9223372036854775808.0, int64_t, __builtin_llfloor 
(-9223372036854775808.0), 17)
+TEST_INIT_CVT (double, -9223372036854777856.0, int64_t, 0x8000, 18)
+TEST_INIT_CVT (double, __builtin_inf (), int64_t, __builtin_llfloor 
(__builtin_inf ()), 19)
+TEST_INIT_CVT (double, -__builtin_inf (), int64_t, __builtin_llfloor 
(-__builtin_inf ()), 20)
+TEST_INIT_CVT (double, __builtin_nan (""), int64_t, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (double, int64_t, 1, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 2, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 3, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 4, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 5, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 6, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 7, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 8, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 9, __bui

[PATCH] Add support for SLP vectorization of OpenMP SIMD clone calls

2023-10-13 Thread Richard Biener
This adds support for SLP vectorization of OpenMP SIMD clone calls.
There's a complication when vectorizing calls involving virtual
operands since this is now for the first time not only leafs (loads
or stores).  With SLP this runs into the issue that placement of
the vectorized stmts is not necessarily at one of the original
scalar stmts which leads to the magic updating virtual operands
in vect_finish_stmt_generation not working.  So we run into the
assert that updating virtual operands isn't necessary.  I've
papered over this similar to how we do for mismatched const/pure
attribution by setting vinfo->any_known_not_updated_vssa.

I've added two basic testcases with multi-lane SLP and verified
that with single-lane SLP enabled the rest of the existing testcases
pass.

Bootstrapped and tested on x86_64-unknown-linux-gnu, will push later 
today.

Richard.

* tree-vect-slp.cc (mask_call_maps): New.
(vect_get_operand_map): Handle IFN_MASK_CALL.
(vect_build_slp_tree_1): Likewise.
* tree-vect-stmts.cc (vectorizable_simd_clone_call): Handle
SLP.

* gcc.dg/vect/slp-simd-clone-1.c: New testcase.
* gcc.dg/vect/slp-simd-clone-2.c: Likewise.
---
 gcc/testsuite/gcc.dg/vect/slp-simd-clone-1.c |  46 +
 gcc/testsuite/gcc.dg/vect/slp-simd-clone-2.c |  57 +++
 gcc/tree-vect-slp.cc |  20 +++-
 gcc/tree-vect-stmts.cc   | 102 ++-
 4 files changed, 196 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/slp-simd-clone-1.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/slp-simd-clone-2.c

diff --git a/gcc/testsuite/gcc.dg/vect/slp-simd-clone-1.c 
b/gcc/testsuite/gcc.dg/vect/slp-simd-clone-1.c
new file mode 100644
index 000..6ccbb39b567
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/slp-simd-clone-1.c
@@ -0,0 +1,46 @@
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+#include "tree-vect.h"
+
+int x[1024];
+
+#pragma omp declare simd simdlen(4) notinbranch
+__attribute__((noinline)) int
+foo (int a, int b)
+{
+  return a + b;
+}
+
+void __attribute__((noipa))
+bar (void)
+{
+#pragma omp simd
+  for (int i = 0; i < 512; i++)
+{
+  x[2*i+0] = foo (x[2*i+0], x[2*i+0]);
+  x[2*i+1] = foo (x[2*i+1], x[2*i+1]);
+}
+}
+
+int
+main ()
+{
+  int i;
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < 1024; i++)
+x[i] = i;
+
+  bar ();
+
+#pragma GCC novector
+  for (i = 0; i < 1024; i++)
+if (x[i] != i + i)
+  abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-simd-clone-2.c 
b/gcc/testsuite/gcc.dg/vect/slp-simd-clone-2.c
new file mode 100644
index 000..98387c92486
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/slp-simd-clone-2.c
@@ -0,0 +1,57 @@
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx2" { target avx2_runtime } } */
+
+#include "tree-vect.h"
+
+int x[1024];
+
+#pragma omp declare simd simdlen(4) inbranch
+__attribute__((noinline)) int
+foo (int a, int b)
+{
+  return a + b;
+}
+
+void __attribute__((noipa))
+bar (void)
+{
+#pragma omp simd
+  for (int i = 0; i < 512; i++)
+{
+  if (x[2*i+0] < 10)
+   x[2*i+0] = foo (x[2*i+0], x[2*i+0]);
+  if (x[2*i+1] < 20)
+   x[2*i+1] = foo (x[2*i+1], x[2*i+1]);
+}
+}
+
+int
+main ()
+{
+  int i;
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < 1024; i++)
+x[i] = i;
+
+  bar ();
+
+#pragma GCC novector
+  for (i = 0; i < 1024; i++)
+{
+  if (((i & 1) && i < 20)
+ || (!(i & 1) && i < 10))
+   {
+ if (x[i] != i + i)
+   abort ();
+   }
+  else if (x[i] != i)
+   abort ();
+}
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { target 
avx2_runtime } } } */
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 4ff8cbaec04..436efdd4807 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -505,6 +505,14 @@ static const int arg2_map[] = { 1, 2 };
 static const int arg1_arg4_map[] = { 2, 1, 4 };
 static const int arg3_arg2_map[] = { 2, 3, 2 };
 static const int op1_op0_map[] = { 2, 1, 0 };
+static const int mask_call_maps[6][7] = {
+  { 1, 1, },
+  { 2, 1, 2, },
+  { 3, 1, 2, 3, },
+  { 4, 1, 2, 3, 4, },
+  { 5, 1, 2, 3, 4, 5, },
+  { 6, 1, 2, 3, 4, 5, 6 },
+};
 
 /* For most SLP statements, there is a one-to-one mapping between
gimple arguments and child nodes.  If that is not true for STMT,
@@ -547,6 +555,15 @@ vect_get_operand_map (const gimple *stmt, unsigned char 
swap = 0)
  case IFN_MASK_STORE:
return arg3_arg2_map;
 
+ case IFN_MASK_CALL:
+   {
+ unsigned nargs = gimple_call_num_args (call);
+ if (nargs >= 2 && nargs <= 7)
+ 

Re: [PATCH 10/11] aarch64: Fix branch-protection error message tests

2023-10-13 Thread Richard Earnshaw (lists)
On 05/09/2023 16:00, Richard Sandiford via Gcc-patches wrote:
> Szabolcs Nagy  writes:
>> Update tests for the new branch-protection parser errors.
>>
>> gcc/testsuite/ChangeLog:
>>
>>  * gcc.target/aarch64/branch-protection-attr.c: Update.
>>  * gcc.target/aarch64/branch-protection-option.c: Update.
> 
> OK, thanks.  (And I agree these are better messages. :))
> 
> I think that's the last of the AArch64-specific ones.  The others
> will need to be reviewed by Kyrill or Richard.
> 
> Richard
> 
>> ---
>>  gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c   | 6 +++---
>>  gcc/testsuite/gcc.target/aarch64/branch-protection-option.c | 2 +-
>>  2 files changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c 
>> b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
>> index 272000c2747..dae2a758a56 100644
>> --- a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
>> +++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
>> @@ -4,19 +4,19 @@ void __attribute__ ((target("branch-protection=leaf")))
>>  foo1 ()
>>  {
>>  }
>> -/* { dg-error {invalid protection type 'leaf' in 
>> 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 5 
>> } */
>> +/* { dg-error {invalid argument 'leaf' for 
>> 'target\("branch-protection="\)'} "" { target *-*-* } 5 } */
>>  /* { dg-error {pragma or attribute 'target\("branch-protection=leaf"\)' is 
>> not valid} "" { target *-*-* } 5 } */

'leaf' is really a modifier for the other branch protection strategies; perhaps 
it would be better to describe it as that.

But this brings up another issue/question.  If the compiler has been configured 
with, say, '--enable-branch-protection=standard' or some other variety, is 
there (or do we want) a way to extend that to leaf functions without changing 
the underlying strategy?

>>  
>>  void __attribute__ ((target("branch-protection=none+pac-ret")))
>>  foo2 ()
>>  {
>>  }
>> -/* { dg-error "unexpected 'pac-ret' after 'none'" "" { target *-*-* } 12 } 
>> */
>> +/* { dg-error {argument 'none' can only appear alone in 
>> 'target\("branch-protection="\)'} "" { target *-*-* } 12 } */

Or maybe better still: "branch protection strategies 'none' and 'pac-ret' are 
incompatible".

>>  /* { dg-error {pragma or attribute 
>> 'target\("branch-protection=none\+pac-ret"\)' is not valid} "" { target 
>> *-*-* } 12 } */
>>  
>>  void __attribute__ ((target("branch-protection=")))
>>  foo3 ()
>>  {
>>  }
>> -/* { dg-error {missing argument to 'target\("branch-protection="\)' pragma 
>> or attribute} "" { target *-*-* } 19 } */
>> +/* { dg-error {invalid argument '' for 'target\("branch-protection="\)'} "" 
>> { target *-*-* } 19 } */
>>  /* { dg-error {pragma or attribute 'target\("branch-protection="\)' is not 
>> valid} "" { target *-*-* } 19 } */
>> diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c 
>> b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
>> index 1b3bf4ee2b8..e2f847a31c4 100644
>> --- a/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
>> +++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
>> @@ -1,4 +1,4 @@
>>  /* { dg-do "compile" } */
>>  /* { dg-options "-mbranch-protection=leaf -mbranch-protection=none+pac-ret" 
>> } */
>>  
>> -/* { dg-error "unexpected 'pac-ret' after 'none'"  "" { target *-*-* } 0 } 
>> */
>> +/* { dg-error "argument 'none' can only appear alone in 
>> '-mbranch-protection='" "" { target *-*-* } 0 } */

But this is all a matter of taste.

However, this patch should be merged with the patch that changes the error 
messages.  Or has that already gone in?

R


Re: [PATCH v1] RISC-V: Add test for FP llfloor auto vectorization

2023-10-13 Thread juzhe.zh...@rivai.ai
OK



juzhe.zh...@rivai.ai
 
From: pan2.li
Date: 2023-10-13 17:49
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP llfloor auto vectorization
From: Pan Li 
 
The below FP API are supported already by sharing the same standard
name, as well as the machine mode.
 
long long llfloor (double);
 
This patch would like to add the test cases for ensuring the
correctness.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-llfloor-0.c: New test.
 
Signed-off-by: Pan Li 
---
.../riscv/rvv/autovec/unop/math-llfloor-0.c   | 20 ++
.../rvv/autovec/unop/math-llfloor-run-0.c | 64 +++
.../riscv/rvv/autovec/vls/math-llfloor-0.c| 30 +
3 files changed, 114 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-llfloor-0.c
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
new file mode 100644
index 000..4b10f966015
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include 
+#include "test-math.h"
+
+/*
+** test_double_int64_t___builtin_llfloor:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+2
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llfloor)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
new file mode 100644
index 000..22829132e96
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_v && rv64 } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include 
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+double in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llfloor)
+TEST_ASSERT (int64_t)
+
+TEST_INIT_CVT (double, 1.2, int64_t, __builtin_llfloor (1.2), 1)
+TEST_INIT_CVT (double, -1.2, int64_t, __builtin_llfloor (-1.2), 2)
+TEST_INIT_CVT (double, 0.5, int64_t, __builtin_llfloor (0.5), 3)
+TEST_INIT_CVT (double, -0.5, int64_t, __builtin_llfloor (-0.5), 4)
+TEST_INIT_CVT (double, 0.1, int64_t, __builtin_llfloor (0.1), 5)
+TEST_INIT_CVT (double, -0.1, int64_t, __builtin_llfloor (-0.1), 6)
+TEST_INIT_CVT (double, 3.0, int64_t, __builtin_llfloor (3.0), 7)
+TEST_INIT_CVT (double, -3.0, int64_t, __builtin_llfloor (-3.0), 8)
+TEST_INIT_CVT (double, 4503599627370495.5, int64_t, __builtin_llfloor 
(4503599627370495.5), 9)
+TEST_INIT_CVT (double, 4503599627370497.0, int64_t, __builtin_llfloor 
(4503599627370497.0), 10)
+TEST_INIT_CVT (double, -4503599627370495.5, int64_t, __builtin_llfloor 
(-4503599627370495.5), 11)
+TEST_INIT_CVT (double, -4503599627370496.0, int64_t, __builtin_llfloor 
(-4503599627370496.0), 12)
+TEST_INIT_CVT (double, 0.0, int64_t, __builtin_llfloor (-0.0), 13)
+TEST_INIT_CVT (double, -0.0, int64_t, __builtin_llfloor (-0.0), 14)
+TEST_INIT_CVT (double, 9223372036854774784.0, int64_t, __builtin_llfloor 
(9223372036854774784.0), 15)
+TEST_INIT_CVT (double, 9223372036854775808.0, int64_t, 0x7fff, 16)
+TEST_INIT_CVT (double, -9223372036854775808.0, int64_t, __builtin_llfloor 
(-9223372036854775808.0), 17)
+TEST_INIT_CVT (double, -9223372036854777856.0, int64_t, 0x8000, 18)
+TEST_INIT_CVT (double, __builtin_inf (), int64_t, __builtin_llfloor 
(__builtin_inf ()), 19)
+TEST_INIT_CVT (double, -__builtin_inf (), int64_t, __builtin_llfloor 
(-__builtin_inf ()), 20)
+TEST_INIT_CVT (double, __builtin_nan (""), int64_t, 0x7fff, 21)
+
+int
+main ()
+{
+  RUN_TEST_CVT (double, int64_t, 1, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 2, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 3, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 4, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 5, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int64_t, 6, __builtin_llfloor, in, out, ref, 
ARRAY_SIZE);
+  RUN_TEST_CVT (double, int6

Re: [Patch] Fortran: Support OpenMP's 'allocate' directive for stack vars

2023-10-13 Thread Jakub Jelinek
On Tue, Oct 10, 2023 at 06:46:35PM +0200, Tobias Burnus wrote:
>   * parse.cc (check_omp_allocate_stmt): Permit procedure pointers
>   here (rejected later) for less mislreading diagnostic.

s/misl/mis/

> libgomp/ChangeLog:
> 
>   * libgomp.texi:

Fill in something here.

> @@ -7220,8 +7227,7 @@ gfc_resolve_omp_allocate (gfc_namespace *ns, 
> gfc_omp_namelist *list)
>&n->where);
> continue;
>   }
> -  if (ns != n->sym->ns || n->sym->attr.use_assoc
> -   || n->sym->attr.host_assoc || n->sym->attr.imported)
> +  if (ns != n->sym->ns || n->sym->attr.use_assoc ||  
> n->sym->attr.imported)

s/  n/ n/

> --- a/gcc/gimplify.cc
> +++ b/gcc/gimplify.cc
> @@ -1400,23 +1400,53 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
> "region must specify an % clause", t);
> /* Skip for omp_default_mem_alloc (= 1),
>unless align is present. */
> -   else if (!errorcount
> -&& (align != NULL_TREE
> -|| alloc == NULL_TREE
> -|| !integer_onep (alloc)))
> +   else if (errorcount
> +|| (align == NULL_TREE
> +&& alloc != NULL_TREE
> +&& integer_onep (alloc)))
> + DECL_ATTRIBUTES (t) = remove_attribute ("omp allocate",
> + DECL_ATTRIBUTES (t));

Probably already preexisting, by I wonder how safe remove_attribute is.
Aren't attributes shared in some cases
(like __attribute__((attr1, attr2, attr3)) int a, b, c, d;)?
Not really sure if something unshares them afterwards.
If they are shared, adding new attributes is fine, that will make the new
additions not shared and the tail shared, but remove_attribute could remove
it from all of them at once.  Perhaps I'm wrong, haven't verified.

Otherwise LGTM (though, I didn't spot anything about allocatables in the
patch, am I just looking wrong or are they still unsupported)?

Jakub



[PATCH v1] RISC-V: Refine run test cases of math autovec

2023-10-13 Thread pan2 . li
From: Pan Li 

For the run test cases of math autovec, we need a reference value to
check if the return value is expected or not.

The previous patch leverage hardcode for the reference value but we
can leverage the scalar math function instead. For example ceil after
autovec.

ASSERT (CEIL (Vector {1.2,...}) == Vector {2.0, ...});

But we can leverage the scalar math function to avoid potential mistakes.

ASSERT (CEIL (Vector {1.2,...}) == Vector {ceil (1.2), ...});

This patch remove some fflags check as it covered by check-body already.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c:
Use scalar func as reference instead of hardcode.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-floor-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-floor-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-rint-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-rint-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-round-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-round-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-trunc-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-trunc-run-2.c: Ditto.

Signed-off-by: Pan Li 
---
 .../riscv/rvv/autovec/unop/math-ceil-run-1.c  | 18 +-
 .../riscv/rvv/autovec/unop/math-ceil-run-2.c  | 18 +-
 .../riscv/rvv/autovec/unop/math-floor-run-1.c | 18 +-
 .../riscv/rvv/autovec/unop/math-floor-run-2.c | 18 +-
 .../rvv/autovec/unop/math-nearbyint-run-1.c   | 33 ++-
 .../rvv/autovec/unop/math-nearbyint-run-2.c   | 33 ++-
 .../riscv/rvv/autovec/unop/math-rint-run-1.c  | 33 ++-
 .../riscv/rvv/autovec/unop/math-rint-run-2.c  | 33 ++-
 .../riscv/rvv/autovec/unop/math-round-run-1.c | 18 +-
 .../riscv/rvv/autovec/unop/math-round-run-2.c | 18 +-
 .../riscv/rvv/autovec/unop/math-trunc-run-1.c | 18 +-
 .../riscv/rvv/autovec/unop/math-trunc-run-2.c | 18 +-
 12 files changed, 140 insertions(+), 136 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c
index 88611e8268e..419a3def4df 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c
@@ -12,15 +12,15 @@ float ref[ARRAY_SIZE];
 TEST_UNARY_CALL (float, __builtin_ceilf)
 TEST_ASSERT (float)
 
-TEST_INIT (float, 1.2, 2.0, 1)
-TEST_INIT (float, -1.2, -1.0, 2)
-TEST_INIT (float, 3.0, 3.0, 3)
-TEST_INIT (float, 8388607.5, 8388608.0, 4)
-TEST_INIT (float, 8388609.0, 8388609.0, 5)
-TEST_INIT (float, 0.0, 0.0, 6)
-TEST_INIT (float, -0.0, -0.0, 7)
-TEST_INIT (float, -8388607.5, -8388607.0, 8)
-TEST_INIT (float, -8388608.0, -8388608.0, 9)
+TEST_INIT (float, 1.2, __builtin_ceilf (1.2), 1)
+TEST_INIT (float, -1.2, __builtin_ceilf (-1.2), 2)
+TEST_INIT (float, 3.0, __builtin_ceilf (3.0), 3)
+TEST_INIT (float, 8388607.5, __builtin_ceilf (8388607.5), 4)
+TEST_INIT (float, 8388609.0, __builtin_ceilf (8388609.0), 5)
+TEST_INIT (float, 0.0, __builtin_ceilf (0.0), 6)
+TEST_INIT (float, -0.0,__builtin_ceilf (-0.0), 7)
+TEST_INIT (float, -8388607.5, __builtin_ceilf (-8388607.5), 8)
+TEST_INIT (float, -8388608.0, __builtin_ceilf (-8388608.0), 9)
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c
index bb4c86c3d12..2b29c8e4414 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c
@@ -12,15 +12,15 @@ double ref[ARRAY_SIZE];
 TEST_UNARY_CALL (double, __builtin_ceil)
 TEST_ASSERT (double)
 
-TEST_INIT (double, 1.2, 2.0, 1)
-TEST_INIT (double, -1.2, -1.0, 2)
-TEST_INIT (double, 3.0, 3.0, 3)
-TEST_INIT (double, 4503599627370495.5, 4503599627370496.0, 4)
-TEST_INIT (double, 4503599627370497.0, 4503599627370497.0, 5)
-TEST_INIT (double, 0.0, 0.0, 6)
-TEST_INIT (double, -0.0, -0.0, 7)
-TEST_INIT (double, -4503599627370495.5, -4503599627370495.0, 8)
-TEST_INIT (double, -4503599627370496.0, -4503599627370496.0, 9)
+TEST_INIT (double, 1.2, __builtin_ceil (1.2), 1)
+TEST_INIT (double, -1.2, __builtin_ceil (-1.2), 2)
+TEST_INIT (double, 3.0, __builtin_ceil (3.0), 3)
+TEST_INIT (double, 4503599627370495.5, __builtin_ceil (4503599627370495.5), 4)
+TEST_INIT (double, 4503599627370497.0, __builtin_ceil (4503599627370497.0), 5)
+TEST_INIT (double, 0.0, __builtin_ceil (0.0), 6)
+TEST_INIT (double, -0.0, __builtin_ceil (-0.0), 7)
+TEST_INIT (double, -4503599627370495.5, __builtin_ceil (-450

RE: [PATCH v1] RISC-V: Add test for FP llfloor auto vectorization

2023-10-13 Thread Li, Pan2
Committed, thanks Juzhe.

Pan

From: juzhe.zh...@rivai.ai 
Sent: Friday, October 13, 2023 6:31 PM
To: Li, Pan2 ; gcc-patches 
Cc: Li, Pan2 ; Wang, Yanzhang ; 
kito.cheng 
Subject: Re: [PATCH v1] RISC-V: Add test for FP llfloor auto vectorization

OK


juzhe.zh...@rivai.ai

From: pan2.li
Date: 2023-10-13 17:49
To: gcc-patches
CC: juzhe.zhong; 
pan2.li; 
yanzhang.wang; 
kito.cheng
Subject: [PATCH v1] RISC-V: Add test for FP llfloor auto vectorization
From: Pan Li mailto:pan2...@intel.com>>

The below FP API are supported already by sharing the same standard
name, as well as the machine mode.

long long llfloor (double);

This patch would like to add the test cases for ensuring the
correctness.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-llfloor-0.c: New test.

Signed-off-by: Pan Li mailto:pan2...@intel.com>>
---
.../riscv/rvv/autovec/unop/math-llfloor-0.c   | 20 ++
.../rvv/autovec/unop/math-llfloor-run-0.c | 64 +++
.../riscv/rvv/autovec/vls/math-llfloor-0.c| 30 +
3 files changed, 114 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-llfloor-0.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
new file mode 100644
index 000..4b10f966015
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-0.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-fno-vect-cost-model -ffast-math -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include 
+#include "test-math.h"
+
+/*
+** test_double_int64_t___builtin_llfloor:
+**   frrm\s+[atx][0-9]+
+**   ...
+**   fsrmi\s+2
+**   ...
+**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*ma
+**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+
+**   ...
+**   fsrm\s+[atx][0-9]+
+**   ret
+*/
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llfloor)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
new file mode 100644
index 000..22829132e96
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-llfloor-run-0.c
@@ -0,0 +1,64 @@
+/* { dg-do run { target { riscv_v && rv64 } } } */
+/* { dg-additional-options "-std=c99 -O3 -ftree-vectorize -fno-vect-cost-model 
-ffast-math" } */
+
+#include 
+#include "test-math.h"
+
+#define ARRAY_SIZE 128
+
+double in[ARRAY_SIZE];
+int64_t out[ARRAY_SIZE];
+int64_t ref[ARRAY_SIZE];
+
+TEST_UNARY_CALL_CVT (double, int64_t, __builtin_llfloor)
+TEST_ASSERT (int64_t)
+
+TEST_INIT_CVT (double, 1.2, int64_t, __builtin_llfloor (1.2), 1)
+TEST_INIT_CVT (double, -1.2, int64_t, __builtin_llfloor (-1.2), 2)
+TEST_INIT_CVT (double, 0.5, int64_t, __builtin_llfloor (0.5), 3)
+TEST_INIT_CVT (double, -0.5, int64_t, __builtin_llfloor (-0.5), 4)
+TEST_INIT_CVT (double, 0.1, int64_t, __builtin_llfloor (0.1), 5)
+TEST_INIT_CVT (double, -0.1, int64_t, __builtin_llfloor (-0.1), 6)
+TEST_INIT_CVT (double, 3.0, int64_t, __builtin_llfloor (3.0), 7)
+TEST_INIT_CVT (double, -3.0, int64_t, __builtin_llfloor (-3.0), 8)
+TEST_INIT_CVT (double, 4503599627370495.5, int64_t, __builtin_llfloor 
(4503599627370495.5), 9)
+TEST_INIT_CVT (double, 4503599627370497.0, int64_t, __builtin_llfloor 
(4503599627370497.0), 10)
+TEST_INIT_CVT (double, -4503599627370495.5, int64_t, __builtin_llfloor 
(-4503599627370495.5), 11)
+TEST_INIT_CVT (double, -4503599627370496.0, int64_t, __builtin_llfloor 
(-4503599627370496.0), 12)
+TEST_INIT_CVT (double, 0.0, int64_t, __builtin_llfloor (-0.0), 13)
+TEST_INIT_CVT (double, -0.0, int64_t, __builtin_llfloor (-0.0), 14)
+TEST_INIT_CVT (double, 9223372036854774784.0, int64_t, __builtin_llfloor 
(9223372036854774784.0), 15)
+TEST_INIT_CVT (double, 9223372036854775808.0, int64_t, 0x7fff, 16)
+TEST_INIT_CVT (double, -9223372036854775808.0, int64_t, __builtin_llfloor 
(-9223372036854775808.0), 17)
+TEST_INIT_CVT (double, -9223372036854777856.0, int64_t, 0x8000, 18)
+TEST_INIT_CVT (double, __builtin_inf (), int64_t, __builtin_llfloor 
(__builtin_inf ()), 19)
+TEST_INIT_CVT (double, -__builtin_inf (), int64_t, __builtin_llfloor 
(-__builtin_inf ()), 20)
+TEST_INIT_CVT (double, __builtin_nan (""), int64_t, 0x7fff, 21)
+
+int
+main ()
+{
+  RU

Re: [PATCH v1] RISC-V: Refine run test cases of math autovec

2023-10-13 Thread 钟居哲
OK



juzhe.zh...@rivai.ai
 
From: pan2.li
Date: 2023-10-13 19:35
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Refine run test cases of math autovec
From: Pan Li 
 
For the run test cases of math autovec, we need a reference value to
check if the return value is expected or not.
 
The previous patch leverage hardcode for the reference value but we
can leverage the scalar math function instead. For example ceil after
autovec.
 
ASSERT (CEIL (Vector {1.2,...}) == Vector {2.0, ...});
 
But we can leverage the scalar math function to avoid potential mistakes.
 
ASSERT (CEIL (Vector {1.2,...}) == Vector {ceil (1.2), ...});
 
This patch remove some fflags check as it covered by check-body already.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c:
Use scalar func as reference instead of hardcode.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-floor-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-floor-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-rint-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-rint-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-round-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-round-run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-trunc-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-trunc-run-2.c: Ditto.
 
Signed-off-by: Pan Li 
---
.../riscv/rvv/autovec/unop/math-ceil-run-1.c  | 18 +-
.../riscv/rvv/autovec/unop/math-ceil-run-2.c  | 18 +-
.../riscv/rvv/autovec/unop/math-floor-run-1.c | 18 +-
.../riscv/rvv/autovec/unop/math-floor-run-2.c | 18 +-
.../rvv/autovec/unop/math-nearbyint-run-1.c   | 33 ++-
.../rvv/autovec/unop/math-nearbyint-run-2.c   | 33 ++-
.../riscv/rvv/autovec/unop/math-rint-run-1.c  | 33 ++-
.../riscv/rvv/autovec/unop/math-rint-run-2.c  | 33 ++-
.../riscv/rvv/autovec/unop/math-round-run-1.c | 18 +-
.../riscv/rvv/autovec/unop/math-round-run-2.c | 18 +-
.../riscv/rvv/autovec/unop/math-trunc-run-1.c | 18 +-
.../riscv/rvv/autovec/unop/math-trunc-run-2.c | 18 +-
12 files changed, 140 insertions(+), 136 deletions(-)
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c
index 88611e8268e..419a3def4df 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-1.c
@@ -12,15 +12,15 @@ float ref[ARRAY_SIZE];
TEST_UNARY_CALL (float, __builtin_ceilf)
TEST_ASSERT (float)
-TEST_INIT (float, 1.2, 2.0, 1)
-TEST_INIT (float, -1.2, -1.0, 2)
-TEST_INIT (float, 3.0, 3.0, 3)
-TEST_INIT (float, 8388607.5, 8388608.0, 4)
-TEST_INIT (float, 8388609.0, 8388609.0, 5)
-TEST_INIT (float, 0.0, 0.0, 6)
-TEST_INIT (float, -0.0, -0.0, 7)
-TEST_INIT (float, -8388607.5, -8388607.0, 8)
-TEST_INIT (float, -8388608.0, -8388608.0, 9)
+TEST_INIT (float, 1.2, __builtin_ceilf (1.2), 1)
+TEST_INIT (float, -1.2, __builtin_ceilf (-1.2), 2)
+TEST_INIT (float, 3.0, __builtin_ceilf (3.0), 3)
+TEST_INIT (float, 8388607.5, __builtin_ceilf (8388607.5), 4)
+TEST_INIT (float, 8388609.0, __builtin_ceilf (8388609.0), 5)
+TEST_INIT (float, 0.0, __builtin_ceilf (0.0), 6)
+TEST_INIT (float, -0.0,__builtin_ceilf (-0.0), 7)
+TEST_INIT (float, -8388607.5, __builtin_ceilf (-8388607.5), 8)
+TEST_INIT (float, -8388608.0, __builtin_ceilf (-8388608.0), 9)
int
main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c
index bb4c86c3d12..2b29c8e4414 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-run-2.c
@@ -12,15 +12,15 @@ double ref[ARRAY_SIZE];
TEST_UNARY_CALL (double, __builtin_ceil)
TEST_ASSERT (double)
-TEST_INIT (double, 1.2, 2.0, 1)
-TEST_INIT (double, -1.2, -1.0, 2)
-TEST_INIT (double, 3.0, 3.0, 3)
-TEST_INIT (double, 4503599627370495.5, 4503599627370496.0, 4)
-TEST_INIT (double, 4503599627370497.0, 4503599627370497.0, 5)
-TEST_INIT (double, 0.0, 0.0, 6)
-TEST_INIT (double, -0.0, -0.0, 7)
-TEST_INIT (double, -4503599627370495.5, -4503599627370495.0, 8)
-TEST_INIT (double, -4503599627370496.0, -4503599627370496.0, 9)
+TEST_INIT (double, 1.2, __builtin_ceil (1.2), 1)
+TEST_INIT (double, -1.2, __builtin_ceil (-1.2), 2)
+TEST_INIT (double, 3.0, __builtin_ceil (3.0), 3)
+TEST_INIT (double, 4503599627370495.5, __builtin_ceil (4503599627370495.5), 4)
+TEST_INIT (double, 4503599627370497.0, __builtin_ceil (4503599627370497.0), 5)
+TEST_INIT (double, 0.0, __builtin_ceil (0.0), 6)
+TEST_INIT (double, -0.0, __buil

Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-pr69907.c for RVV

2023-10-13 Thread Richard Biener
On Fri, 13 Oct 2023, Juzhe-Zhong wrote:

> Like ARM SVE and GCN, add RVV.

Adding RVV when SVE or GCN is already there looks obvious to me, these
kind of changes are pre-approved.  No need for all the noise.

Thanks,
Richard.

> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/vect/bb-slp-pr69907.c: Add RVV.
> 
> ---
>  gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c 
> b/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
> index b348526b62f..f63b42a271a 100644
> --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
> +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
> @@ -22,5 +22,5 @@ void foo(unsigned *p1, unsigned short *p2)
>  /* Disable for SVE because for long or variable-length vectors we don't
> get an unrolled epilogue loop.  Also disable for AArch64 Advanced SIMD,
> because there we can vectorize the epilogue using mixed vector sizes.
> -   Likewise for AMD GCN.  */
> -/* { dg-final { scan-tree-dump "BB vectorization with gaps at the end of a 
> load is not supported" "slp1" { target { { ! aarch64*-*-* } && { ! 
> amdgcn*-*-* } } } } } */
> +   Likewise for AMD GCN and RVV.  */
> +/* { dg-final { scan-tree-dump "BB vectorization with gaps at the end of a 
> load is not supported" "slp1" { target { { ! aarch64*-*-* } && { { ! 
> amdgcn*-*-* } && { ! riscv_v } } } } } } */
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-68.c for RVV

2023-10-13 Thread Richard Biener
On Fri, 13 Oct 2023, Juzhe-Zhong wrote:

> Like comment said, this test failed on 64 bytes vector.
> Both RVV and GCN has 64 bytes vector.
> 
> So it's more reasonable to use vect512.

OK

> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/vect/bb-slp-68.c: Use vect512.
> 
> ---
>  gcc/testsuite/gcc.dg/vect/bb-slp-68.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-68.c 
> b/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
> index e7573a14933..2dd3d8ee90c 100644
> --- a/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
> +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
> @@ -20,4 +20,4 @@ void foo ()
>  
>  /* We want to have the store group split into 4, 2, 4 when using 32byte 
> vectors.
> Unfortunately it does not work when 64-byte vectors are available.  */
> -/* { dg-final { scan-tree-dump-not "from scalars" "slp2" { xfail amdgcn-*-* 
> } } } */
> +/* { dg-final { scan-tree-dump-not "from scalars" "slp2" { xfail vect512 } } 
> } */
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


[PATCH] OMP SIMD inbranch call vectorization for AVX512 style masks

2023-10-13 Thread Richard Biener
The following teaches vectorizable_simd_clone_call to handle
integer mode masks.  The tricky bit is to second-guess the
number of lanes represented by a single mask argument - the following
uses simdlen and the number of mask arguments to calculate that,
assuming ABIs have them uniform.

Similar to the VOIDmode handling there's a restriction on not
supporting splitting/merging of incoming vector masks to
more/less SIMD call arguments.

Bootstrapped and tested on x86_64-unknown-linux-gnu, re-testing
after a minor change.  Will push later.

Richard.

PR tree-optimization/111795
* tree-vect-stmts.cc (vectorizable_simd_clone_call): Handle
integer mode mask arguments.

* gcc.target/i386/vect-simd-clone-avx512-1.c: New testcase.
* gcc.target/i386/vect-simd-clone-avx512-2.c: Likewise.
* gcc.target/i386/vect-simd-clone-avx512-3.c: Likewise.
---
 .../i386/vect-simd-clone-avx512-1.c   |  43 +
 .../i386/vect-simd-clone-avx512-2.c   |   6 +
 .../i386/vect-simd-clone-avx512-3.c   |   6 +
 gcc/tree-vect-stmts.cc| 150 ++
 4 files changed, 175 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-3.c

diff --git a/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-1.c 
b/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-1.c
new file mode 100644
index 000..e350996439e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-1.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512vl } */
+/* { dg-options "-O2 -fopenmp-simd -mavx512vl" } */
+
+#include "avx512vl-check.h"
+
+#ifndef SIMDLEN
+#define SIMDLEN 4
+#endif
+
+int x[1024];
+
+#pragma omp declare simd simdlen(SIMDLEN)
+__attribute__((noinline)) int
+foo (int a, int b)
+{
+  return a + b;
+}
+
+void __attribute__((noipa))
+bar (void)
+{
+#pragma omp simd
+  for (int i = 0; i < 1024; i++)
+if (x[i] < 20)
+  x[i] = foo (x[i], x[i]);
+}
+
+void avx512vl_test ()
+{
+  int i;
+#pragma GCC novector
+  for (i = 0; i < 1024; i++)
+x[i] = i;
+
+  bar ();
+
+#pragma GCC novector
+  for (i = 0; i < 1024; i++)
+if ((i < 20 && x[i] != i + i)
+   || (i >= 20 && x[i] != i))
+  abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-2.c 
b/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-2.c
new file mode 100644
index 000..d9968ae30f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-2.c
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512vl } */
+/* { dg-options "-O2 -fopenmp-simd -mavx512vl" } */
+
+#define SIMDLEN 8
+#include "vect-simd-clone-avx512-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-3.c 
b/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-3.c
new file mode 100644
index 000..c05f6c8ce91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-simd-clone-avx512-3.c
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512vl } */
+/* { dg-options "-O2 -fopenmp-simd -mavx512vl" } */
+
+#define SIMDLEN 16
+#include "vect-simd-clone-avx512-1.c"
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 0fb6fc3394a..abc8603f67c 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -4492,6 +4492,9 @@ vectorizable_simd_clone_call (vec_info *vinfo, 
stmt_vec_info stmt_info,
i = -1;
break;
  case SIMD_CLONE_ARG_TYPE_MASK:
+   if (SCALAR_INT_MODE_P (n->simdclone->mask_mode)
+   != SCALAR_INT_MODE_P (TYPE_MODE (arginfo[i].vectype)))
+ i = -1;
break;
  }
if (i == (size_t) -1)
@@ -4517,6 +4520,12 @@ vectorizable_simd_clone_call (vec_info *vinfo, 
stmt_vec_info stmt_info,
   if (bestn == NULL)
 return false;
 
+  unsigned int num_mask_args = 0;
+  if (SCALAR_INT_MODE_P (bestn->simdclone->mask_mode))
+for (i = 0; i < nargs; i++)
+  if (bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
+   num_mask_args++;
+
   for (i = 0; i < nargs; i++)
 {
   if ((arginfo[i].dt == vect_constant_def
@@ -4541,30 +4550,50 @@ vectorizable_simd_clone_call (vec_info *vinfo, 
stmt_vec_info stmt_info,
  return false;
}
 
-  if (bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK
- && bestn->simdclone->mask_mode == VOIDmode
- && (simd_clone_subparts (bestn->simdclone->args[i].vector_type)
- != simd_clone_subparts (arginfo[i].vectype)))
+  if (bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
{
- /* FORNOW we only have partial support for vector-type masks that
-can't hold all of simdlen. */
- 

RE: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-68.c for RVV

2023-10-13 Thread Li, Pan2
Committed, thanks Richard.

Pan

-Original Message-
From: Richard Biener  
Sent: Friday, October 13, 2023 8:00 PM
To: Juzhe-Zhong 
Cc: gcc-patches@gcc.gnu.org; jeffreya...@gmail.com
Subject: Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-68.c for RVV

On Fri, 13 Oct 2023, Juzhe-Zhong wrote:

> Like comment said, this test failed on 64 bytes vector.
> Both RVV and GCN has 64 bytes vector.
> 
> So it's more reasonable to use vect512.

OK

> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/vect/bb-slp-68.c: Use vect512.
> 
> ---
>  gcc/testsuite/gcc.dg/vect/bb-slp-68.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-68.c 
> b/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
> index e7573a14933..2dd3d8ee90c 100644
> --- a/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
> +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
> @@ -20,4 +20,4 @@ void foo ()
>  
>  /* We want to have the store group split into 4, 2, 4 when using 32byte 
> vectors.
> Unfortunately it does not work when 64-byte vectors are available.  */
> -/* { dg-final { scan-tree-dump-not "from scalars" "slp2" { xfail amdgcn-*-* 
> } } } */
> +/* { dg-final { scan-tree-dump-not "from scalars" "slp2" { xfail vect512 } } 
> } */
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


[COMMITTED] PR tree-optimization/111622 - Do not add partial equivalences with no uses.

2023-10-13 Thread Andrew MacLeod
Technically PR 111622 exposes a bug in GCC 13, but its been papered over 
on trunk by this:


commit 9ea74d235c7e7816b996a17c61288f02ef767985
Author: Richard Biener 
Date:   Thu Sep 14 09:31:23 2023 +0200

tree-optimization/111294 - better DCE after forwprop


This removes a lot of dead statements, but those statements were being 
added to the list of partial equivalences and causing some serious 
compile time issues.


Rangers cache loops through equivalences when its propagating on-entry 
values, so if the partial equivalence list is very large, it can consume 
a lot of time.  Typically, partial equivalence lists are small.   In 
this case, a lot of dead stmts were not removed, so there was no 
redundancy elimination and it was causing an issue.   This patch 
actually speeds things up a hair in the normal case too.


Bootstrapped on x86_64-pc-linux-gnu with no regressions.  pushed.

Andrew





[COMMITTED] [GCC13] PR tree-optimization/111622 - Do not add partial equivalences with no uses.

2023-10-13 Thread Andrew MacLeod
There are a lot of dead statements in this testcase which a casts. These 
were being added to the list of partial equivalences and causing some 
serious compile time issues.


Rangers cache loops through equivalences when its propagating on-entry 
values, so if the partial equivalence list is very large, it can consume 
a lot of time.  Typically, partial equivalence lists are small.   In 
this case, a lot of dead stmts were not removed, so there was no 
redundancy elimination and it was causing an issue.


Bootstrapped on x86_64-pc-linux-gnu with no regressions. Pushed.

Andrew
From 425964b77ab5b9631e914965a7397303215c77a1 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Thu, 12 Oct 2023 17:06:36 -0400
Subject: [PATCH] Do not add partial equivalences with no uses.

	PR tree-optimization/111622
	* value-relation.cc (equiv_oracle::add_partial_equiv): Do not
	register a partial equivalence if an operand has no uses.
---
 gcc/value-relation.cc | 9 +
 1 file changed, 9 insertions(+)

diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index fc792a4d5bc..0ed5f93d184 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -389,6 +389,9 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
   // In either case, if PE2 has an entry, we simply do nothing.
   if (pe2.members)
 	return;
+  // If there are no uses of op2, do not register.
+  if (has_zero_uses (op2))
+	return;
   // PE1 is the LHS and already has members, so everything in the set
   // should be a slice of PE2 rather than PE1.
   pe2.code = pe_min (r, pe1.code);
@@ -406,6 +409,9 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
 }
   if (pe2.members)
 {
+  // If there are no uses of op1, do not register.
+  if (has_zero_uses (op1))
+	return;
   pe1.ssa_base = pe2.ssa_base;
   // If pe2 is a 16 bit value, but only an 8 bit copy, we can't be any
   // more than an 8 bit equivalence here, so choose MIN value.
@@ -415,6 +421,9 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
 }
   else
 {
+  // If there are no uses of either operand, do not register.
+  if (has_zero_uses (op1) || has_zero_uses (op2))
+	return;
   // Neither name has an entry, simply create op1 as slice of op2.
   pe2.code = bits_to_pe (TYPE_PRECISION (TREE_TYPE (op2)));
   if (pe2.code == VREL_VARYING)
-- 
2.41.0



Re: [COMMITTED] PR tree-optimization/111622 - Do not add partial equivalences with no uses.

2023-10-13 Thread Andrew MacLeod

of course the patch would be handy...


On 10/13/23 09:23, Andrew MacLeod wrote:
Technically PR 111622 exposes a bug in GCC 13, but its been papered 
over on trunk by this:


commit 9ea74d235c7e7816b996a17c61288f02ef767985
Author: Richard Biener 
Date:   Thu Sep 14 09:31:23 2023 +0200
        tree-optimization/111294 - better DCE after forwprop

This removes a lot of dead statements, but those statements were being 
added to the list of partial equivalences and causing some serious 
compile time issues.


Rangers cache loops through equivalences when its propagating on-entry 
values, so if the partial equivalence list is very large, it can 
consume a lot of time.  Typically, partial equivalence lists are 
small.   In this case, a lot of dead stmts were not removed, so there 
was no redundancy elimination and it was causing an issue.   This 
patch actually speeds things up a hair in the normal case too.


Bootstrapped on x86_64-pc-linux-gnu with no regressions.  pushed.

Andrew


From 4eea3c1872a941089cafa105a11d8e40b1a55929 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Thu, 12 Oct 2023 17:06:36 -0400
Subject: [PATCH] Do not add partial equivalences with no uses.

	PR tree-optimization/111622
	* value-relation.cc (equiv_oracle::add_partial_equiv): Do not
	register a partial equivalence if an operand has no uses.
---
 gcc/value-relation.cc | 9 +
 1 file changed, 9 insertions(+)

diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index 0326fe7cde6..c0f513a0eb1 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -392,6 +392,9 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
   // In either case, if PE2 has an entry, we simply do nothing.
   if (pe2.members)
 	return;
+  // If there are no uses of op2, do not register.
+  if (has_zero_uses (op2))
+	return;
   // PE1 is the LHS and already has members, so everything in the set
   // should be a slice of PE2 rather than PE1.
   pe2.code = pe_min (r, pe1.code);
@@ -409,6 +412,9 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
 }
   if (pe2.members)
 {
+  // If there are no uses of op1, do not register.
+  if (has_zero_uses (op1))
+	return;
   pe1.ssa_base = pe2.ssa_base;
   // If pe2 is a 16 bit value, but only an 8 bit copy, we can't be any
   // more than an 8 bit equivalence here, so choose MIN value.
@@ -418,6 +424,9 @@ equiv_oracle::add_partial_equiv (relation_kind r, tree op1, tree op2)
 }
   else
 {
+  // If there are no uses of either operand, do not register.
+  if (has_zero_uses (op1) || has_zero_uses (op2))
+	return;
   // Neither name has an entry, simply create op1 as slice of op2.
   pe2.code = bits_to_pe (TYPE_PRECISION (TREE_TYPE (op2)));
   if (pe2.code == VREL_VARYING)
-- 
2.41.0



Re: [Patch] Fortran: Support OpenMP's 'allocate' directive for stack vars

2023-10-13 Thread Tobias Burnus

On 13.10.23 13:01, Jakub Jelinek wrote:

On Tue, Oct 10, 2023 at 06:46:35PM +0200, Tobias Burnus wrote:
+++ b/gcc/gimplify.cc

@@ -1400,23 +1400,53 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
+  else if (errorcount
+   || (align == NULL_TREE
+   && alloc != NULL_TREE
+   && integer_onep (alloc)))
+DECL_ATTRIBUTES (t) = remove_attribute ("omp allocate",
+DECL_ATTRIBUTES (t));

Probably already preexisting, by I wonder how safe remove_attribute is.
Aren't attributes shared in some cases
(like __attribute__((attr1, attr2, attr3)) int a, b, c, d;)?


I think there should be no problem – new attributes get added as:

DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
   t, DECL_ATTRIBUTES (var));

Thus, attr = DECL_ATTRIBUTES (var) is not shared, even if
TREE_CHAIN (attr) might be shared.

Thus, as long as new attributes get added at the head of the chain,
there should be no issue. And "omp allocate" is added once per decl
and is therefore not shared - removing might create again a shared
tree, but any following 'tree_cons' will again unshare it.

I think in your case, there would be indeed a problem when doing:
  'tree attr = remove_attr (...("attr2") ...)'
as this would remove "attr2" for 4 decls.

* * *

However, as 'omp allocate' is not used later on, I also do not need
to remove it.

=> Updated patch attached + interdiff for gimplify.cc attached.

Changes:
* Condition now the same as previously
* Keep 'omp allocate' also for DECL_VALUE_EXPR variable
* Add assert that we either have Fortran's expression the GOMP_FREE
  location - or a DECL_VALUE_EXPR.
* Make use of the assertion by keeping the HAS_DECL_VALUE expr below;
  this avoids adding an align/allocator == default check.
  => same code as old code, except for creating + using 'v' variable
  and adding a clobber.

* * *


Otherwise LGTM (though, I didn't spot anything about allocatables in the
patch, am I just looking wrong or are they still unsupported)?


It's unsupported – albeit Chung-Lin has some patch for it. The code path
is completely different. It already starts by 'omp allocators' (+
legacy: 'omp allocate') being not declarative but executable and
associated with a Fortran 'allocate'  statement and ...

Sorry for being slow - but I keep getting distracted by other tasks ...

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
diff -u b/gcc/gimplify.cc b/gcc/gimplify.cc
--- b/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -1400,13 +1400,10 @@
 			  "region must specify an % clause", t);
 	  /* Skip for omp_default_mem_alloc (= 1),
 		 unless align is present. */
-	  else if (errorcount
-		   || (align == NULL_TREE
-			   && alloc != NULL_TREE
-			   && integer_onep (alloc)))
-		DECL_ATTRIBUTES (t) = remove_attribute ("omp allocate",
-			DECL_ATTRIBUTES (t));
-	  else
+	  else if (!errorcount
+		   && (align != NULL_TREE
+			   || alloc == NULL_TREE
+			   || !integer_onep (alloc)))
 		{
 		  /* Fortran might already use a pointer type internally;
 		 use that pointer except for type(C_ptr) and type(C_funptr);
@@ -1426,10 +1423,10 @@
 		  tmp = build_pointer_type (type);
 		  v = create_tmp_var (tmp, get_name (t));
 		  DECL_IGNORED_P (v) = 0;
-		  tmp = remove_attribute ("omp allocate", DECL_ATTRIBUTES (t));
 		  DECL_ATTRIBUTES (v)
 			= tree_cons (get_identifier ("omp allocate var"),
- build_tree_list (NULL_TREE, t), tmp);
+ build_tree_list (NULL_TREE, t),
+ DECL_ATTRIBUTES (t));
 		  tmp = build_fold_indirect_ref (v);
 		  TREE_THIS_NOTRAP (tmp) = 1;
 		  SET_DECL_VALUE_EXPR (t, tmp);
@@ -1461,6 +1458,11 @@
 		  tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
 	 fold_convert (TREE_TYPE (v), tmp));
 		  gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE);
+		  /* Ensure that either TREE_CHAIN (TREE_VALUE (attr) is set
+		 and GOMP_FREE added here or that DECL_HAS_VALUE_EXPR_P (t)
+		 is set, using in a condition much further below.  */
+		  gcc_assert (DECL_HAS_VALUE_EXPR_P (t)
+			  || TREE_CHAIN (TREE_VALUE (attr)));
 		  if (TREE_CHAIN (TREE_VALUE (attr)))
 		{
 		  /* Fortran is special as it does not have properly nest
@@ -1631,14 +1633,15 @@
 	{
 	  tree attr;
 	  if (flag_openmp
+	  && DECL_HAS_VALUE_EXPR_P (t)
 	  && TREE_USED (t)
 	  && ((attr = lookup_attribute ("omp allocate",
 	DECL_ATTRIBUTES (t))) != NULL_TREE)
 	  && TREE_CHAIN (TREE_VALUE (attr)) == NULL_TREE)
 	{
-	  /* For Fortran, the GOMP_free has already been added above.  */
-	  tree v = (DECL_HAS_VALUE_EXPR_P (t)
-			

Re: [PATCH] genemit: Split insn-emit.cc into ten files.

2023-10-13 Thread Robin Dapp
> Testsuite is unchanged on all but x86 where, strangely, I saw several
> illegal instructions in the pch tests.  Those were not reproducible
> in a second manual test suite run.  I'm just running another full
> bootstrap and testsuite cycle with the latest trunk.

Follow-up on the pch tests.  The errors are an artifact of my testing.
I usually build unpatched without bootstrap and patched with it, comparing
the testsuite results.

When bootstrapping unpatched, the same errors occur.  When bootstrapping
with --with-arch=native we essentially use a vpxor for a memset which is
an illegal instruction on gc188 of the compile farm.  This might be a
known bug but I haven't found something in bugzilla.

In total:  Bootstrap and testsuite unchanged on x86, aarch64 and power10.

Regarding Tamar's comment:

> I'll leave the review to Richard, but I think you should adopt the same 
> approach
> taken by the match.pd split, in that you provide the list of files as an 
> argument
> to the genemit instead of the number of files.  And if no list is provided it
> outputs to stdout as it does today.

I think this would involve rewriting the argument handling for all gen*
tools (it is shared via gensupport).  Currently, I make use of the
callback and just add two new options which helps limit the number of
changes.  Is stdout so valuable from a debugging point of view that
changing it would be prohibitive?  Of course it's a change but I usually
grep through insn-emit.cc anyways and that would still be possible.

Regards
 Robin


RE: [PATCH] genemit: Split insn-emit.cc into ten files.

2023-10-13 Thread Tamar Christina
> -Original Message-
> From: Robin Dapp 
> Sent: Friday, October 13, 2023 4:15 PM
> To: gcc-patches 
> Cc: rdapp@gmail.com; jeffreyalaw ; Tamar
> Christina ; rjie...@linux.alibaba.com
> Subject: Re: [PATCH] genemit: Split insn-emit.cc into ten files.
> 
> > Testsuite is unchanged on all but x86 where, strangely, I saw several
> > illegal instructions in the pch tests.  Those were not reproducible in
> > a second manual test suite run.  I'm just running another full
> > bootstrap and testsuite cycle with the latest trunk.
> 
> Follow-up on the pch tests.  The errors are an artifact of my testing.
> I usually build unpatched without bootstrap and patched with it, comparing
> the testsuite results.
> 
> When bootstrapping unpatched, the same errors occur.  When bootstrapping
> with --with-arch=native we essentially use a vpxor for a memset which is an
> illegal instruction on gc188 of the compile farm.  This might be a known bug
> but I haven't found something in bugzilla.
> 
> In total:  Bootstrap and testsuite unchanged on x86, aarch64 and power10.
> 
> Regarding Tamar's comment:
> 
> > I'll leave the review to Richard, but I think you should adopt the
> > same approach taken by the match.pd split, in that you provide the
> > list of files as an argument to the genemit instead of the number of
> > files.  And if no list is provided it outputs to stdout as it does today.
> 
> I think this would involve rewriting the argument handling for all gen* tools 
> (it
> is shared via gensupport).  Currently, I make use of the callback and just add
> two new options which helps limit the number of changes.  Is stdout so
> valuable from a debugging point of view that changing it would be
> prohibitive?  Of course it's a change but I usually grep through insn-emit.cc
> anyways and that would still be possible.

Debugging here refers to debugging the output of gen*, which usually one does
With small examples when modifying the tool itself.

> I think this would involve rewriting the argument handling for all gen* tools 
> (it
> is shared via gensupport).  Currently, I make use of the callback and just add
> two new options which helps limit the number of changes.  

Hmm why? The same callback you use to consume the listed arguments can be used 
to
consume the list can it not? I may be wrong, but from what I remember the 
callback
is called when main can't consume an argv value and it's allowed to eat all 
remaining input?

But I'll leave it up to Richard. Having to read multiple files to check a 
change to gen*
seems like a usability issue though.

Regards,
Tamar

> 
> Regards
>  Robin


Re: [PATCH] genemit: Split insn-emit.cc into ten files.

2023-10-13 Thread Robin Dapp


> Hmm why? The same callback you use to consume the listed arguments
> can be used to consume the list can it not? I may be wrong, but from
> what I remember the callback is called when main can't consume an
> argv value and it's allowed to eat all remaining input?

Ah, I see.  If that's possible, then surely it shouldn't be that large
a change and I can add it still.

Regards
 Robin


Re: [PATCH] gimple-match: Do not try UNCOND optimization with COND_LEN.

2023-10-13 Thread Robin Dapp
> Why are the contents of this if statement wrong for COND_LEN?
> If the "else" value doesn't matter, then the masked form can use
> the "then" value for all elements.  I would have expected the same
> thing to be true of COND_LEN.

Right, that one was overly pessimistic.  Removed.

> But isn't the test whether res_op->code itself is an internal_function?
> In other words, shouldn't it just be:
> 
>   if (internal_fn_p (res_op->code)
> && internal_fn_len_index (as_internal_fn (res_op->code)) != -1)
>   return true;
> 
> maybe_resimplify_conditional_op should already have converted to an
> internal function where possible, and if combined_fn (res_op->code)
> does any extra conversion on the fly, that conversion won't be reflected
> in res_op.

I went through some of our test cases and believe most of the problems
are due to situations like the following:

In vect-cond-arith-2.c we have (on riscv)
  vect_neg_xi_14.4_23 = -vect_xi_13.3_22;
  vect_res_2.5_24 = .COND_LEN_ADD ({ -1, ... }, vect_res_1.0_17, 
vect_neg_xi_14.4_23, vect_res_1.0_17, _29, 0);

On aarch64 this is a situation that matches the VEC_COND_EXPR
simplification that I disabled with this patch.  We valueized
to _26 = vect_res_1.0_17 - vect_xi_13.3_22 and then create
vect_res_2.5_24 = VEC_COND_EXPR ;
This is later re-assembled into a COND_SUB.

As we have two masks or COND_LEN we cannot use a VEC_COND_EXPR to
achieve the same thing.  Would it be possible to create a COND_OP
directly instead, though?  I tried the following (not very polished
obviously):

-  new_op.set_op (VEC_COND_EXPR, res_op->type,
-res_op->cond.cond, res_op->ops[0],
-res_op->cond.else_value);
-  *res_op = new_op;
-  return gimple_resimplify3 (seq, res_op, valueize);
+  if (!res_op->cond.len)
+   {
+ new_op.set_op (VEC_COND_EXPR, res_op->type,
+res_op->cond.cond, res_op->ops[0],
+res_op->cond.else_value);
+ *res_op = new_op;
+ return gimple_resimplify3 (seq, res_op, valueize);
+   }
+  else if (seq && *seq && is_gimple_assign (*seq))
+   {
+ new_op.code = gimple_assign_rhs_code (*seq);
+ new_op.type = res_op->type;
+ new_op.num_ops = gimple_num_ops (*seq) - 1;
+ new_op.ops[0] = gimple_assign_rhs1 (*seq);
+ if (new_op.num_ops > 1)
+   new_op.ops[1] = gimple_assign_rhs2 (*seq);
+ if (new_op.num_ops > 2)
+   new_op.ops[2] = gimple_assign_rhs2 (*seq);
+
+ new_op.cond = res_op->cond;
+
+ gimple_match_op bla2;
+ if (convert_conditional_op (&new_op, &bla2))
+   {
+ *res_op = bla2;
+ // SEQ should now be dead.
+ return true;
+   }
+   }

This would make the other hunk (check whether it was a LEN
and try to recreate it) redundant I hope.

I don't know enough about valueization, whether it's always
safe to do that and other implications.  On riscv this seems
to work, though and the other backends never go through the LEN
path.  If, however, this is a feasible direction it could also
be done for the non-LEN targets?

Regards
 Robin


Re: [PATCH v2] RISC-V: Make xtheadcondmov-indirect tests robust against instruction reordering

2023-10-13 Thread Jeff Law




On 10/12/23 12:28, Kito Cheng wrote:

Sorry for the late comment after Jeff say ok, but I guess we may
consider add "-fno-schedule-insns -fno-schedule-insns2" to avoid
disturbing from schedule like some of our test case in
gcc/testsuite/gcc.target/riscv/rvv?
It wouldn't be a bad idea to bring more stability, particularly to tests 
which are expecting instructions in a specific order.  THat feels like 
it's likely a distinct change though.


jeff


Re: [PATCH] combine: Fix handling of unsigned constants

2023-10-13 Thread Jeff Law




On 10/6/23 01:45, Stefan Schulze Frielinghaus wrote:

If a CONST_INT represents an integer of a mode with fewer bits than in
HOST_WIDE_INT, then the integer is sign extended.  For those two
optimizations touched by this patch, the integers of interest have only
the most significant bit set w.r.t their mode, therefore, they were sign
extended.  Thus in order to get the integer of interest, we have to chop
off the high bits.

Bootstrapped and regtested on x64, powerpc64le, and s390.  Ok for
mainline?

gcc/ChangeLog:

* combine.cc (simplify_compare_const): Fix handling of unsigned
constants.

OK
jeff


[PATCH v2] c++: Fix compile-time-hog in cp_fold_immediate_r [PR111660]

2023-10-13 Thread Marek Polacek
On Thu, Oct 12, 2023 at 09:41:43PM -0400, Jason Merrill wrote:
> On 10/12/23 17:04, Marek Polacek wrote:
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > -- >8 --
> > My recent patch introducing cp_fold_immediate_r caused exponential
> > compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
> > case recursively walks the arms of a COND_EXPR, but after processing
> > both arms it doesn't end the walk; it proceeds to walk the
> > sub-expressions of the outermost COND_EXPR, triggering again walking
> > the arms of the nested COND_EXPR, and so on.  This patch brings the
> > compile time down to about 0m0.033s.
> > 
> > I've added some debug prints to make sure that the rest of cp_fold_r
> > is still performed as before.
> > 
> >  PR c++/111660
> > 
> > gcc/cp/ChangeLog:
> > 
> >  * cp-gimplify.cc (cp_fold_immediate_r) : Return
> >  integer_zero_node instead of break;.
> >  (cp_fold_immediate): Return true if cp_fold_immediate_r returned
> >  error_mark_node.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >  * g++.dg/cpp0x/hog1.C: New test.
> > ---
> >   gcc/cp/cp-gimplify.cc |  9 ++--
> >   gcc/testsuite/g++.dg/cpp0x/hog1.C | 77 +++
> >   2 files changed, 82 insertions(+), 4 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C
> > 
> > diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
> > index bdf6e5f98ff..ca622ca169a 100644
> > --- a/gcc/cp/cp-gimplify.cc
> > +++ b/gcc/cp/cp-gimplify.cc
> > @@ -1063,16 +1063,16 @@ cp_fold_immediate_r (tree *stmt_p, int 
> > *walk_subtrees, void *data_)
> > break;
> > if (TREE_OPERAND (stmt, 1)
> >   && cp_walk_tree (&TREE_OPERAND (stmt, 1), cp_fold_immediate_r, data,
> > -  nullptr))
> > +  nullptr) == error_mark_node)
> > return error_mark_node;
> > if (TREE_OPERAND (stmt, 2)
> >   && cp_walk_tree (&TREE_OPERAND (stmt, 2), cp_fold_immediate_r, data,
> > -  nullptr))
> > +  nullptr) == error_mark_node)
> > return error_mark_node;
> > /* We're done here.  Don't clear *walk_subtrees here though: we're 
> > called
> >  from cp_fold_r and we must let it recurse on the expression with
> >  cp_fold.  */
> > -  break;
> > +  return integer_zero_node;
> 
> I'm concerned this will end up missing something like
> 
> 1 ? 1 : ((1 ? 1 : 1), immediate())
> 
> as the integer_zero_node from the inner ?: will prevent walk_tree from
> looking any farther.

You are right.  The line above works as expected, but

  1 ? 1 : ((1 ? 1 : id (42)), id (i));

shows the problem (when the expression isn't used as an initializer).

> Maybe we want to handle COND_EXPR in cp_fold_r instead of here?

I hope this version is better.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
My recent patch introducing cp_fold_immediate_r caused exponential
compile time with nested COND_EXPRs.  The problem is that the COND_EXPR
case recursively walks the arms of a COND_EXPR, but after processing
both arms it doesn't end the walk; it proceeds to walk the
sub-expressions of the outermost COND_EXPR, triggering again walking
the arms of the nested COND_EXPR, and so on.  This patch brings the
compile time down to about 0m0.033s.

The ff_fold_immediate flag is unused after this patch but since I'm
using it in the P2564 patch, I'm not removing it now.

PR c++/111660

gcc/cp/ChangeLog:

* cp-gimplify.cc (cp_fold_immediate_r) : Don't
handle it here.
(cp_fold_r): Handle COND_EXPR here.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/hog1.C: New test.
* g++.dg/cpp2a/consteval36.C: New test.
---
 gcc/cp/cp-gimplify.cc| 38 +---
 gcc/testsuite/g++.dg/cpp0x/hog1.C| 77 
 gcc/testsuite/g++.dg/cpp2a/consteval36.C | 18 ++
 3 files changed, 111 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/hog1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/consteval36.C

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index bdf6e5f98ff..801cba141cb 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1052,27 +1052,6 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, 
void *data_)
 
   switch (TREE_CODE (stmt))
 {
-/* Unfortunately we must handle code like
-false ? bar () : 42
-   where we have to check bar too.  The cp_fold call in cp_fold_r could
-   fold the ?: into a constant before we see it here.  */
-case COND_EXPR:
-  /* If we are called from cp_fold_immediate, we don't need to worry about
-cp_fold folding away the COND_EXPR.  */
-  if (data->flags & ff_fold_immediate)
-   break;
-  if (TREE_OPERAND (stmt, 1)
- && cp_walk_tree (&TREE_OPERAND (stmt, 1), cp_fold_immediate_r, data,
-  nullpt

Continued (Non)mutlib and stub header issue (was Re: [PATCH v2] RISC-V: Use stdint-gcc.h in rvv testsuite)

2023-10-13 Thread Vineet Gupta

Hi Kito, Christoph, Patrick,

I've been trying to test a specific non multilib config 
(rv64-zicond_zfa) and seeing noisy output (compared to a similar multlib 
build) and it seems there's still a bunch of this header issue (for the 
rv32 abi headers) in the non-multlib config.


e.g.
FAIL: gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul1-7.c -O3 
-ftree-vectorize --param riscv-autovec-lmul=dynamic (test for excess errors)

...
...

The errors are missing header :

 from 
gcc/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul1-7.c:4:
INSTALL/tc-up-231010-zicond-zfa-non-multilib/sysroot/usr/include/gnu/stubs.h:8:11: 
fatal error: gnu/stubs-ilp32.h: No such file or directory



When looking around, I stumbled upon commit
    d0bbecb1c41 "RISC-V: Add riscv_vector.h wrapper in testsuite to 
prevent pull in stdint.h from C library"


Which seems like a step in a right direction, but how does one ensure 
that the wrapper riscv_vector.h (containing stdint-gcc.h) is included by 
test vs. the default riscv_vector.h (which is more user facing and thus 
needs to include the system stdint.h)


P.S. I couldn't find the posting for above commit on gcc-patches ?

Thx,
-Vineet


On 10/5/23 16:45, Patrick O'Neill wrote:

stdint.h can be replaced with stdint-gcc.h to resolve some missing
system headers in non-multilib installations.

Tested using glibc rv32gcv and rv64gcv on r14-4381-g7eb5ce7f58e.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-1.h:
Replace stdint.h with stdint-gcc.h.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-1.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-1.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-1.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_convert_int2int-2.h:
Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_sqrt-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_sqrt-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-5.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-6.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-7.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_unary-8.c: Ditto.
* gcc.target/riscv/rvv/autovec/partial/slp-8.c: Ditto.
* gcc.target/riscv/rvv/autovec/partial/slp-9.c: Ditto.
* gcc.target/riscv/rvv/autovec/pr111232.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/cvt-0.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/cvt-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls-vlmax/perm.h: Ditto.
* gcc.target/riscv/rvv/base/abi-call-args-4-run.c: Ditto.
* gcc.target/riscv/rvv/base/pr110119-2.c: Ditto.
* gcc.target/riscv/rvv/vsetvl/pr111255.c: Ditto.
* gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c: Ditto.

Signed-off-by: Patrick O'Neill 
---
Changes from v1:
- Avoid changing riscv_vector.h

Failures looked like this:
In file included from 
/riscv-gnu-toolchain/build/sysroot/usr/include/features.h:515,
  from 
/riscv-gnu-toolchain/build/sysroot/usr/include/bits/libc-header-start.h:33,
  from /riscv-gnu-toolchain/build/sysroot/usr/include/stdint.h:26,
  from 
/riscv-gnu-toolchain/build/lib/gcc/riscv32-unknown-linux-gnu/14.0.0/include/stdint.h:9,
  from 
/riscv-gnu-toolchain/build/build-gcc-linux-stage2/gcc/include/stdint.h:9,
  from 
/riscv-gnu-toolchain/build/build-gcc-linux-stage2/gcc/include/riscv_vector.h:28,
  from 
/riscv-gnu-toolchain/gcc/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul1-7.c:4:
/riscv-gnu-toolchain/build/sysroot/usr/include/gnu/stubs.h:8:11: fatal error: 
gnu/stubs-ilp32.h: No such file or directory

Resolves these failures on rv32gcv (non-multilib):
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-1.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2float-rv64-2.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-1.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_float2int-rv64-2.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-1.c (test 
for excess errors)
FAIL: gcc.target/riscv/rvv/autovec/cond/cond_convert_int2float-rv64-2.c (test 
for e

Re: [PATCH] Fortran: name conflict between internal procedure and derived type [PR104351]

2023-10-13 Thread Jerry D

On 10/11/23 12:39 PM, Harald Anlauf wrote:

Dear All,

the attached trivial patch fixes (= catches) a forgotten corner-case
in the detection of a name conflict between an internal procedure and
a local declaration for the case that the latter is a derived type.
Another torture test by Gerhard... ;-)  Used to ICE previously.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald



This one is OK Harald.

Thanks,

Jerry


Re: [PATCH] Fortran: name conflict between internal procedure and derived type [PR104351]

2023-10-13 Thread Jerry D

On 10/11/23 12:44 PM, Harald Anlauf wrote:

Dear All,

sorry for attaching the wrong patch - this time it is the correct one!

Harald

On 10/11/23 21:39, Harald Anlauf wrote:

Dear All,

the attached trivial patch fixes (= catches) a forgotten corner-case
in the detection of a name conflict between an internal procedure and
a local declaration for the case that the latter is a derived type.
Another torture test by Gerhard... ;-)  Used to ICE previously.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald



This one is OK as well. Once I found the right patch on the right email. 
 Regardless, both good to go.


Thanks,

Jerry


[PATCH v18 00/40] Optimize type traits performance

2023-10-13 Thread Ken Matsui
This patch series optimizes type traits performance by implementing
built-in type traits and using them in libstdc++.

Changes in v18:

* Removed all RID values for built-in traits and used cik_trait
instead.
* Improved to handle the use of non-function-like built-in trait
identifiers.
* Reverted all changes to conflicted identifiers with new built-ins
in the existing code base.

Changes in v17:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in.
* Made ridpointers for RID_TRAIT_EXPR and RID_TRAIT_TYPE empty.

Changes in v16:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in and gperf struct.
* Supply -k option to gperf to support older versions than 2.8.

Changes in v15:

* Rebased on top of trunk.
* Use gperf to look up traits instead of enum rid.

Changes in v14:

* Added padding calculation to the commit message.

Changes in v13:

* Fixed ambiguous commit message and comment.

Changes in v12:

* Evaluated all paddings affected by the enum rid change.

Changes in v11:

* Merged all patches into one patch series.
* Rebased on top of trunk.
* Unified commit message style.
* Used _GLIBCXX_USE_BUILTIN_TRAIT.

Ken Matsui (40):
  c++: Sort built-in traits alphabetically
  c-family, c++: Look up built-in traits through gperf
  c++: Accept the use of non-function-like built-in trait identifiers
  c++: Implement __is_const built-in trait
  libstdc++: Optimize is_const trait performance
  c++: Implement __is_volatile built-in trait
  libstdc++: Optimize is_volatile trait performance
  c++: Implement __is_array built-in trait
  libstdc++: Optimize is_array trait performance
  c++: Implement __is_unbounded_array built-in trait
  libstdc++: Optimize is_unbounded_array trait performance
  c++: Implement __is_bounded_array built-in trait
  libstdc++: Optimize is_bounded_array trait performance
  c++: Implement __is_scoped_enum built-in trait
  libstdc++: Optimize is_scoped_enum trait performance
  c++: Implement __is_member_pointer built-in trait
  libstdc++: Optimize is_member_pointer trait performance
  c++: Implement __is_member_function_pointer built-in trait
  libstdc++: Optimize is_member_function_pointer trait performance
  c++: Implement __is_member_object_pointer built-in trait
  libstdc++: Optimize is_member_object_pointer trait performance
  c++: Implement __is_reference built-in trait
  libstdc++: Optimize is_reference trait performance
  c++: Implement __is_function built-in trait
  libstdc++: Optimize is_function trait performance
  libstdc++: Optimize is_object trait performance
  c++: Implement __remove_pointer built-in trait
  libstdc++: Optimize remove_pointer trait performance
  c++: Implement __is_pointer built-in trait
  libstdc++: Optimize is_pointer trait performance
  c++: Implement __is_arithmetic built-in trait
  libstdc++: Optimize is_arithmetic trait performance
  libstdc++: Optimize is_fundamental trait performance
  libstdc++: Optimize is_compound trait performance
  c++: Implement __is_unsigned built-in trait
  libstdc++: Optimize is_unsigned trait performance
  c++: Implement __is_signed built-in trait
  libstdc++: Optimize is_signed trait performance
  c++: Implement __is_scalar built-in trait
  libstdc++: Optimize is_scalar trait performance

 gcc/c-family/c-common.cc  |   7 -
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 ++
 gcc/cp/constraint.cc  | 112 +--
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 ++
 gcc/cp/cp-trait.def   |  27 +-
 gcc/cp/cp-trait.gperf |  91 ++
 gcc/cp/cp-trait.h | 285 ++
 gcc/cp/cp-tree.h  |  14 +-
 gcc/cp/lex.cc |  19 ++
 gcc/cp/parser.cc  | 144 ++---
 gcc/cp/semantics.cc   | 157 +++---
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  | 117 +--
 gcc/testsuite/g++.dg/ext/is_arithmetic.C  |  33 ++
 gcc/testsuite/g++.dg/ext/is_array.C   |  28 ++
 gcc/testsuite/g++.dg/ext/is_bounded_array.C   |  38 +++
 gcc/testsuite/g++.dg/ext/is_const.C   |  19 ++
 gcc/testsuite/g++.dg/ext/is_function.C|  58 
 .../g++.dg/ext/is_member_function_pointer.C   |  31 ++
 .../g++.dg/ext/is_member_object_pointer.C |  30 ++
 gcc/testsuite/g++.dg/ext/is_member_pointer.C  |  30 ++
 gcc/testsuite/g++.dg/ext/is_pointer.C |  51 
 gcc/testsuite/g++.dg/ext/is_reference.C   |  34 +++
 gcc/testsuite/g++.dg/ext/is_scalar.C  |  31 ++
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C |  67

[PATCH v18 01/40] c++: Sort built-in traits alphabetically

2023-10-13 Thread Ken Matsui
This patch sorts built-in traits alphabetically for better code
readability.

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Sort built-in traits
alphabetically.
* cp-trait.def: Likewise.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(finish_trait_type): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc | 68 -
 gcc/cp/cp-trait.def  | 10 +--
 gcc/cp/semantics.cc  | 94 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +-
 4 files changed, 121 insertions(+), 121 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9e4e7043cd..722fc334e6f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
   inform (loc, "  %qT is not trivially destructible", t1);
   break;
+case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+  inform (loc, "  %qT does not have unique object representations", t1);
+  break;
 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
   inform (loc, "  %qT does not have a virtual destructor", t1);
   break;
 case CPTK_IS_ABSTRACT:
   inform (loc, "  %qT is not an abstract class", t1);
   break;
+case CPTK_IS_AGGREGATE:
+  inform (loc, "  %qT is not an aggregate", t1);
+  break;
+case CPTK_IS_ASSIGNABLE:
+  inform (loc, "  %qT is not assignable from %qT", t1, t2);
+  break;
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONSTRUCTIBLE:
+  if (!t2)
+inform (loc, "  %qT is not default constructible", t1);
+  else
+inform (loc, "  %qT is not constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_CONVERTIBLE:
+  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_EMPTY:
   inform (loc, "  %qT is not an empty class", t1);
   break;
@@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_NOTHROW_ASSIGNABLE:
+  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+  if (!t2)
+   inform (loc, "  %qT is not nothrow default constructible", t1);
+  else
+   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   inform (loc, "  %qT is not pointer-interconvertible base of %qT",
  t1, t2);
@@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIAL:
   inform (loc, "  %qT is not a trivial type", t1);
   break;
-case CPTK_IS_UNION:
-  inform (loc, "  %qT is not a union", t1);
-  break;
-case CPTK_IS_AGGREGATE:
-  inform (loc, "  %qT is not an aggregate", t1);
-  break;
-case CPTK_IS_TRIVIALLY_COPYABLE:
-  inform (loc, "  %qT is not trivially copyable", t1);
-  break;
-case CPTK_IS_ASSIGNABLE:
-  inform (loc, "  %qT is not assignable from %qT", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
   inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
   break;
-case CPTK_IS_NOTHROW_ASSIGNABLE:
-  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
-  break;
-case CPTK_IS_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not default constructible", t1);
-  else
-   inform (loc, "  %qT is not constructible from %qE", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
   if (!t2)
inform (loc, "  %qT is not trivially default constructible", t1);
   else
inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
   break;
-case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not nothrow default constructible", t1);
-  else
-   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
-  break;
-case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
-  inform (loc, "  %qT does not have unique object representations", t1);
-  break;
-case CPTK_IS_CONVERTIBLE:
-  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+case CPTK_IS_TRIVIALLY_COPYABLE:
+  inform (loc, "  %qT is not trivially copyable", t1);
   break;
-case CPTK_IS_NOTHROW_CONVERTIBLE:
-   infor

[PATCH v18 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-13 Thread Ken Matsui
Since RID_MAX soon reaches 255 and all built-in traits are used approximately
once in a C++ translation unit, this patch removes all RID values for built-in
traits and uses gperf to look up the specific trait. Rather than holding
traits as keywords, we set all trait identifiers as cik_trait, which is a new
cp_identifier_kind. As cik_reserved_for_udlit was unused and
cp_identifier_kind is 3 bits, we replaced the unused field with the new
cik_trait. Also, the later patch handles a subsequent token to the built-in
identifier so that we accept the use of non-function-like built-in trait
identifiers.

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Remove all mappings of
built-in traits.
* c-common.h (enum rid): Remove all RID values for built-in traits.

gcc/cp/ChangeLog:

* Make-lang.in: Add targets to generate cp-trait.gperf and
cp-trait.h.
* cp-objcp-common.cc (names_builtin_p): Remove all RID value
cases for built-in traits.  Check for built-in traits via
the new cik_trait identifier.
* cp-tree.h (cik_reserved_for_udlit): Rename to ...
(cik_trait): ... this.
(IDENTIFIER_ANY_OP_P): Exclude cik_trait.
(IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
* lex.cc (init_cp_traits): New function to set cik_trait for all
built-in trait identifiers.
(cxx_init): Call init_cp_traits function.
* parser.cc (cp_lexer_lookup_trait): New function to look up a
built-in trait from a token by gperf.
(cp_lexer_lookup_trait_expr): Likewise, look up an
expression-yielding built-in trait.
(cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
built-in trait.
(cp_keyword_starts_decl_specifier_p): Remove all RID value cases
for built-in traits.
(cp_lexer_next_token_is_decl_specifier_keyword): Handle
type-yielding built-in traits.
(cp_parser_primary_expression): Remove all RID value cases for
built-in traits.  Handle expression-yielding built-in traits.
(cp_parser_trait): Handle cp_trait instead of enum rid.
(cp_parser_simple_type_specifier): Remove all RID value cases
for built-in traits.  Handle type-yielding built-in traits.
* cp-trait-head.in: New file.
* cp-trait.gperf: New file.
* cp-trait.h: New file.

Co-authored-by: Patrick Palka 
Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |   7 --
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 +
 gcc/cp/cp-trait.gperf |  74 
 gcc/cp/cp-trait.h | 247 ++
 gcc/cp/cp-tree.h  |  14 ++-
 gcc/cp/lex.cc |  19 +++
 gcc/cp/parser.cc  | 132 
 10 files changed, 492 insertions(+), 70 deletions(-)
 create mode 100644 gcc/cp/cp-trait-head.in
 create mode 100644 gcc/cp/cp-trait.gperf
 create mode 100644 gcc/cp/cp-trait.h

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index f044db5b797..21fd333ef57 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
   { "wchar_t", RID_WCHAR,  D_CXXONLY },
   { "while",   RID_WHILE,  0 },
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  { NAME,  RID_##CODE, D_CXXONLY },
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-  /* An alias for __is_same.  */
-  { "__is_same_as",RID_IS_SAME,D_CXXONLY },
-
   /* C++ transactional memory.  */
   { "synchronized",RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1fdba7ef3ea..051a442e0f4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -168,11 +168,6 @@ enum rid
   RID_BUILTIN_LAUNDER,
   RID_BUILTIN_BIT_CAST,
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  RID_##CODE,
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-
   /* C++11 */
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
 
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 2727fb7f8cc..a67d1c3e9f3 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -34,6 +34,8 @@
 # - the compiler proper (eg: cc1plus)
 # - define the names for selecting the language in LANGUAGES.
 
+AWK = @AWK@
+
 # Actual names to use when installing a native compiler.
 CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
 GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
@@ -186,6 +188,30 @@ endif
 # This is the file that depends on the generated header file.
 cp/name-lookup.o: $(srcdir)/cp/std-name-hint.h
 
+# We always need the dependency on the .gperf file
+# because it itself is generated.
+ifeq ($(ENABLE_MAINTAI

[PATCH v18 03/40] c++: Accept the use of non-function-like built-in trait identifiers

2023-10-13 Thread Ken Matsui
This patch accepts the use of non-function-like built-in trait
identifiers.  Specifically, we check if the subsequent token is '(' for
ordinary built-in traits or is '<' only for the special __type_pack_element
built-in trait.  If the same identifiers are used in other cases, the
parser treats them as normal identifiers.  This allows us to accept code
like:

struct __is_pointer {};

gcc/cp/ChangeLog:

* parser.cc (cp_lexer_lookup_trait): Rename to ...
(cp_lexer_peek_trait): ... this.  Handle a subsequent token for
the corresponding built-in trait.
(cp_lexer_lookup_trait_expr): Rename to ...
(cp_lexer_peek_trait_expr): ... this.
(cp_lexer_lookup_trait_type): Rename to ...
(cp_lexer_peek_trait_type): ... this.
(cp_lexer_next_token_is_decl_specifier_keyword): Call
cp_lexer_peek_trait_type.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_primary_expression): Call cp_lexer_peek_trait_expr.

Signed-off-by: Ken Matsui 
---
 gcc/cp/parser.cc | 48 ++--
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 39952893ffa..59015eac596 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -247,12 +247,12 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static const cp_trait *cp_lexer_lookup_trait
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_expr
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_type
-  (const cp_token *);
+static const cp_trait *cp_lexer_peek_trait
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_expr
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_type
+  (cp_lexer *lexer, const cp_token *);
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -1183,21 +1183,33 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
 }
 }
 
-/* Look ups the corresponding built-in trait if a given token is
+/* Peeks the corresponding built-in trait if a given token is
a built-in trait.  Otherwise, returns nullptr.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait (const cp_token *token)
+cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
 {
-  tree id = token->u.value;
+  tree id = token1->u.value;
 
-  if (token->type == CPP_NAME
+  if (token1->type == CPP_NAME
   && TREE_CODE (id) == IDENTIFIER_NODE
   && IDENTIFIER_TRAIT_P (id))
 {
   const char *id_str = IDENTIFIER_POINTER (id);
   const int id_len = IDENTIFIER_LENGTH (id);
-  return cp_trait_lookup::find (id_str, id_len);
+  const cp_trait *trait = cp_trait_lookup::find (id_str, id_len);
+
+  /* Check if the subsequent token is a `<' token to
+ __type_pack_element or is a `(' token to everything else.  */
+  const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
+  if (trait->kind == CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_LESS)
+   return nullptr;
+  if (trait->kind != CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_OPEN_PAREN)
+   return nullptr;
+
+  return trait;
 }
   return nullptr;
 }
@@ -1206,9 +1218,9 @@ cp_lexer_lookup_trait (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_expr (const cp_token *token)
+cp_lexer_peek_trait_expr (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && !trait->type)
 return trait;
 
@@ -1219,9 +1231,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_type (const cp_token *token)
+cp_lexer_peek_trait_type (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && trait->type)
 return trait;
 
@@ -1236,7 +1248,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
*lexer)
   cp_token *token;
 
   token = cp_lexer_peek_token (lexer);
-  if (cp_lexer_lookup_trait_type (token))
+  if (cp_lexer_peek_trait_type (lexer, token))
 return true;
   return cp_keyword_starts_decl_specifier_p (token->keyword);
 }
@@ -6108,7 +6120,7 @@ cp_parser_primary_expression (cp_parser *parser,
 keyword.  */
 case CPP_NAME:
   {
-   const cp_trait* trait = cp_lexer_lookup_trait_expr (token);
+   const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer, token);
if (trait)
  return cp_parser_trait (parser, trait);
   }
@@ -20117,7 +20129,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 }
 
   /* If token is a type-yielding built-in traits, parse it.  */
-  const

[PATCH v18 04/40] c++: Implement __is_const built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_const.

gcc/cp/ChangeLog:

* Make-lang.in: Update key positions for gperf, based on
automatically computed values.
* cp-trait.def: Define __is_const.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONST.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_const.
* g++.dg/ext/is_const.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/Make-lang.in  |   2 +-
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 202 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_const.C  |  19 +++
 8 files changed, 135 insertions(+), 100 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C

diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index a67d1c3e9f3..7479e7dc00b 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -195,7 +195,7 @@ $(srcdir)/cp/cp-trait.h: $(srcdir)/cp/cp-trait.gperf
 else
 $(srcdir)/cp/cp-trait.h: | $(srcdir)/cp/cp-trait.gperf
 endif
-   gperf -o -C -E -k '8' -D -N 'find' -L C++ \
+   gperf -o -C -E -k '6,8' -D -N 'find' -L C++ \
$(srcdir)/cp/cp-trait.gperf --output-file 
$(srcdir)/cp/cp-trait.h
 
 # The cp-trait.gperf file itself is generated from
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 722fc334e6f..567dd35fe0a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONST:
+  inform (loc, "  %qT is not a const type", t1);
+  break;
 case CPTK_IS_CONSTRUCTIBLE:
   if (!t2)
 inform (loc, "  %qT is not default constructible", t1);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 0e48e64b8dd..9e4e6d798a0 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
+DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
 DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
 DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 47e3c1af499..47a5ec9ee6f 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
+"__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
 "__is_convertible", CPTK_IS_CONVERTIBLE, 2, false
 "__is_empty", CPTK_IS_EMPTY, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 97ba8492d15..c9005eee1ff 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -1,5 +1,5 @@
 /* C++ code produced by gperf version 3.1 */
-/* Command-line: gperf -o -C -E -k 8 -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
+/* Command-line: gperf -o -C -E -k 6,8 -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
   && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 79, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86,  1, 86, 86,
-   0, 35, 86,  0, 86,  0, 86, 86, 10, 10,
-  50, 15, 55, 86, 30,  5, 15,  0, 86, 86,
-  86, 20, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 

[PATCH v18 07/40] libstdc++: Optimize is_volatile trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_volatile trait by dispatching
to the new __is_volatile built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_volatile): Use __is_volatile built-in
trait.
(is_volatile_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 686e38e47c3..c01f65df22b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -800,6 +800,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_volatile
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+  template
+struct is_volatile
+: public __bool_constant<__is_volatile(_Tp)>
+{ };
+#else
   template
 struct is_volatile
 : public false_type { };
@@ -807,6 +813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
@@ -3236,10 +3243,15 @@ template 
   inline constexpr bool is_const_v = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+template 
+  inline constexpr bool is_volatile_v = __is_volatile(_Tp);
+#else
 template 
   inline constexpr bool is_volatile_v = false;
 template 
   inline constexpr bool is_volatile_v = true;
+#endif
 
 template 
   inline constexpr bool is_trivial_v = __is_trivial(_Tp);
-- 
2.42.0



[PATCH v18 06/40] c++: Implement __is_volatile built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_volatile.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/cp-trait.gperf|  1 +
 gcc/cp/cp-trait.h| 38 +---
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_volatile.C   | 19 
 7 files changed, 51 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 567dd35fe0a..f031e022541 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,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_REF_CONSTRUCTS_FROM_TEMPORARY:
   inform (loc, "  %qT is not a reference that binds to a temporary "
  "object of type %qT (direct-initialization)", t1, t2);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9e4e6d798a0..d786f47e60c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,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)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 47a5ec9ee6f..ea7abda6c75 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -63,6 +63,7 @@ struct cp_trait {
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
+"__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
 "__remove_cv", CPTK_REMOVE_CV, 1, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index c9005eee1ff..f462794d5db 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
   40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0, 96, 96,
+  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
   96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 46,
+  TOTAL_KEYWORDS = 47,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,27 +125,29 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
 #line 65 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 68 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 69 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 70 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 48 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
 #line 61 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
+#line 71 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-tr

[PATCH v18 05/40] libstdc++: Optimize is_const trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_const trait by dispatching to
the new __is_const built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_const): Use __is_const built-in trait.
(is_const_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 677cd934b94..686e38e47c3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,6 +784,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Type properties.
 
   /// is_const
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+  template
+struct is_const
+: public __bool_constant<__is_const(_Tp)>
+{ };
+#else
   template
 struct is_const
 : public false_type { };
@@ -791,6 +797,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_const<_Tp const>
 : public true_type { };
+#endif
 
   /// is_volatile
   template
@@ -3218,10 +3225,17 @@ template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+template 
+  inline constexpr bool is_const_v = __is_const(_Tp);
+#else
 template 
   inline constexpr bool is_const_v = false;
 template 
   inline constexpr bool is_const_v = true;
+#endif
+
 template 
   inline constexpr bool is_volatile_v = false;
 template 
-- 
2.42.0



[PATCH v18 10/40] c++: Implement __is_unbounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_unbounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNBOUNDED_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_unbounded_array.
* g++.dg/ext/is_unbounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 ++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 42 ++-
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/is_unbounded_array.C | 37 
 7 files changed, 71 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unbounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e30a4a907a..751ac61b25a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIALLY_COPYABLE:
   inform (loc, "  %qT is not trivially copyable", t1);
   break;
+case CPTK_IS_UNBOUNDED_ARRAY:
+  inform (loc, "  %qT is not an unbounded array", t1);
+  break;
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 99bc05360b9..4e02f68e4a9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,7 @@ DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 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_UNBOUNDED_ARRAY, "__is_unbounded_array", 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index fb162cac164..a894fc8c74c 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -63,6 +63,7 @@ struct cp_trait {
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
+"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
 "__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 526e63dec42..47060ffbbef 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 48,
+  TOTAL_KEYWORDS = 49,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,30 +125,32 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 76 "../../gcc/cp/cp-trait.gperf"
+#line 77 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 71 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
 #line 62 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_volatile", CPTK_IS_VOLATILE, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
+#line 66 "../../gcc/cp/cp-trait.gperf"
+  {"__is_unbounded_ar

[PATCH v18 08/40] c++: Implement __is_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_array.
* g++.dg/ext/is_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 148 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_array.C  |  28 +
 7 files changed, 116 insertions(+), 72 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f031e022541..5e30a4a907a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARRAY:
+  inform (loc, "  %qT is not an array", t1);
+  break;
 case CPTK_IS_ASSIGNABLE:
   inform (loc, "  %qT is not assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index d786f47e60c..99bc05360b9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index ea7abda6c75..fb162cac164 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f462794d5db..526e63dec42 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
-  40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
-  96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
+   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
+   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+ 

[PATCH v18 09/40] libstdc++: Optimize is_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_array trait by dispatching to
the new __is_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_array): Use __is_array built-in trait.
(is_array_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index c01f65df22b..4e8165e5af5 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -523,6 +523,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_array
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+  template
+struct is_array
+: public __bool_constant<__is_array(_Tp)>
+{ };
+#else
   template
 struct is_array
 : public false_type { };
@@ -534,6 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_array<_Tp[]>
 : public true_type { };
+#endif
 
   template
 struct __is_pointer_helper
@@ -3183,12 +3190,17 @@ template 
 template 
   inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+template 
+  inline constexpr bool is_array_v = __is_array(_Tp);
+#else
 template 
   inline constexpr bool is_array_v = false;
 template 
   inline constexpr bool is_array_v<_Tp[]> = true;
 template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
+#endif
 
 template 
   inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
-- 
2.42.0



[PATCH v18 12/40] c++: Implement __is_bounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_bounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_bounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_BOUNDED_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_bounded_array.
* g++.dg/ext/is_bounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|  3 +
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/cp-trait.gperf   |  1 +
 gcc/cp/cp-trait.h   | 86 +++--
 gcc/cp/semantics.cc |  4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 +
 gcc/testsuite/g++.dg/ext/is_bounded_array.C | 38 +
 7 files changed, 94 insertions(+), 42 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_bounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 751ac61b25a..d09252a56b6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
+case CPTK_IS_BOUNDED_ARRAY:
+  inform (loc, "  %qT is not a bounded array", t1);
+  break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 4e02f68e4a9..6d6dff7a4c3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
+DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
 DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
 DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index a894fc8c74c..90fcdc01de6 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
+"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false
 "__is_class", CPTK_IS_CLASS, 1, false
 "__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 47060ffbbef..f22a6e93618 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
   116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 49,
+  TOTAL_KEYWORDS = 50,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,54 +125,56 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 50 "../../gcc/cp/cp-trait.gperf"
+#line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 72 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
-#line 49 "../../gcc/cp/cp-trait.gperf"
+#line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 62 "../../gcc/cp/cp-trait.gperf"
+#line 63 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE,

[PATCH v18 11/40] libstdc++: Optimize is_unbounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unbounded_array trait by
dispatching to the new __is_unbounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unbounded_array_v): Use
__is_unbounded_array built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 4e8165e5af5..cb3d9e238fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3541,11 +3541,16 @@ template
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
+  template
+inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
+# else
   template
 inline constexpr bool is_unbounded_array_v = false;
 
   template
 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+# endif
 
   /// True for a type that is an array of known bound.
   /// @since C++20
-- 
2.42.0



[PATCH v18 13/40] libstdc++: Optimize is_bounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_bounded_array trait by
dispatching to the new __is_bounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_bounded_array_v): Use __is_bounded_array
built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index cb3d9e238fa..d306073a797 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3532,11 +3532,16 @@ template
   /// True for a type that is an array of known bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
+  template
+inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
+# else
   template
 inline constexpr bool is_bounded_array_v = false;
 
   template
 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
+# endif
 
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
-- 
2.42.0



[PATCH v18 14/40] c++: Implement __is_scoped_enum built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scoped_enum.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scoped_enum.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCOPED_ENUM.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_scoped_enum.
* g++.dg/ext/is_scoped_enum.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 161 +++---
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C |  67 +
 7 files changed, 160 insertions(+), 80 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scoped_enum.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d09252a56b6..1c0b2e0f178 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3781,6 +3781,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCOPED_ENUM:
+  inform (loc, "  %qT is not a scoped enum", t1);
+  break;
 case CPTK_IS_STD_LAYOUT:
   inform (loc, "  %qT is not an standard layout type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 6d6dff7a4c3..e0e3fe1d23f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -79,6 +79,7 @@ DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertib
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 90fcdc01de6..f3fd82ba549 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -59,6 +59,7 @@ struct cp_trait {
 "__is_pod", CPTK_IS_POD, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
 "__is_trivial", CPTK_IS_TRIVIAL, 1, false
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f22a6e93618..9c18165eb68 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
-   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
-  116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 9

[PATCH v18 16/40] c++: Implement __is_member_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_MEMBER_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_member_pointer.
* g++.dg/ext/is_member_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 153 ++-
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_member_pointer.C |  30 
 7 files changed, 120 insertions(+), 75 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 1c0b2e0f178..f0d3f89464c 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_POINTER:
+  inform (loc, "  %qT is not a member pointer", t1);
+  break;
 case CPTK_IS_NOTHROW_ASSIGNABLE:
   inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e0e3fe1d23f..26087da3bdf 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index f3fd82ba549..3775b11283d 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 9c18165eb68..dfd60cec6e6 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 111, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99,  0,  5, 50,
-  30,  0, 40, 15, 99,  0, 99, 99,  5, 10,
-  30,  0,  5, 99, 10, 50,  5,  0, 35, 99,
-  99,  5, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118

[PATCH v18 15/40] libstdc++: Optimize is_scoped_enum trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_scoped_enum trait
by dispatching to the new __is_scoped_enum built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scoped_enum): Use
__is_scoped_enum built-in trait.
(is_scoped_enum_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index d306073a797..7fd29d8d9f2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3633,6 +3633,12 @@ template
   /// True if the type is a scoped enumeration type.
   /// @since C++23
 
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+struct is_scoped_enum
+: bool_constant<__is_scoped_enum(_Tp)>
+{ };
+# else
   template
 struct is_scoped_enum
 : false_type
@@ -3644,11 +3650,17 @@ template
 struct is_scoped_enum<_Tp>
 : bool_constant
 { };
+# endif
 
   /// @ingroup variable_templates
   /// @since C++23
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
+# else
   template
 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+# endif
 #endif
 
 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && 
ref_{converts,constructs}_from_temp
-- 
2.42.0



[PATCH v18 17/40] libstdc++: Optimize is_member_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_pointer trait
by dispatching to the new __is_member_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_pointer): Use __is_member_pointer
built-in trait.
(is_member_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7fd29d8d9f2..d7f89cf7c06 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -716,6 +716,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_compound
 : public __not_>::type { };
 
+  /// is_member_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+  template
+struct is_member_pointer
+: public __bool_constant<__is_member_pointer(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template
 struct __is_member_pointer_helper
@@ -726,11 +733,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
   /// @endcond
 
-  /// is_member_pointer
   template
 struct is_member_pointer
 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   template
 struct is_same;
@@ -3242,8 +3249,14 @@ template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+template 
+  inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
 template 
-- 
2.42.0



[PATCH v18 19/40] libstdc++: Optimize is_member_function_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_function_pointer trait
by dispatching to the new __is_member_function_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_function_pointer): Use
__is_member_function_pointer built-in trait.
(is_member_function_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 16 
 1 file changed, 16 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index d7f89cf7c06..e1b10240dc2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -588,6 +588,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+  /// is_member_function_pointer
+  template
+struct is_member_function_pointer
+: public __bool_constant<__is_member_function_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_function_pointer_helper
 : public false_type { };
@@ -601,6 +608,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_function_pointer
 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   /// is_enum
   template
@@ -3222,9 +3230,17 @@ template 
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+template 
+  inline constexpr bool is_member_function_pointer_v =
+__is_member_function_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_function_pointer_v =
 is_member_function_pointer<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_enum_v = __is_enum(_Tp);
 template 
-- 
2.42.0



[PATCH v18 18/40] c++: Implement __is_member_function_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_function_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_function_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_FUNCTION_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of
__is_member_function_pointer.
* g++.dg/ext/is_member_function_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 176 +-
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 .../g++.dg/ext/is_member_function_pointer.C   |  31 +++
 7 files changed, 131 insertions(+), 88 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_function_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f0d3f89464c..d0464dd4f6a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
+  inform (loc, "  %qT is not a member function pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 26087da3bdf..897b96630f2 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
 DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 3775b11283d..b28efbab322 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index dfd60cec6e6..d3d4bdf9799 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 111, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118,  20, 118,   0,  55,  50,
-   40,   0,  40,  20, 118,   0, 118, 118,   5,   5,
-   30,   0,   5, 118,  10,  50,   5,   0,   5, 118,
-  118,   5, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,

[PATCH v18 21/40] libstdc++: Optimize is_member_object_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_object_pointer trait
by dispatching to the new __is_member_object_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_object_pointer): Use
__is_member_object_pointer built-in trait.
(is_member_object_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index e1b10240dc2..792213ebfe8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -574,6 +574,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_rvalue_reference<_Tp&&>
 : public true_type { };
 
+  /// is_member_object_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+  template
+struct is_member_object_pointer
+: public __bool_constant<__is_member_object_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_object_pointer_helper
 : public false_type { };
@@ -582,11 +589,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __is_member_object_pointer_helper<_Tp _Cp::*>
 : public __not_>::type { };
 
-  /// is_member_object_pointer
+
   template
 struct is_member_object_pointer
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
   /// is_member_function_pointer
@@ -3227,9 +3235,16 @@ template 
   inline constexpr bool is_rvalue_reference_v = false;
 template 
   inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+template 
+  inline constexpr bool is_member_object_pointer_v =
+__is_member_object_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
 template 
-- 
2.42.0



[PATCH v18 20/40] c++: Implement __is_member_object_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_object_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_object_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_OBJECT_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of
__is_member_object_pointer.
* g++.dg/ext/is_member_object_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 +
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 62 ++-
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +
 .../g++.dg/ext/is_member_object_pointer.C | 30 +
 7 files changed, 74 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_object_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d0464dd4f6a..98b1f004a68 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3759,6 +3759,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
   inform (loc, "  %qT is not a member function pointer", t1);
   break;
+case CPTK_IS_MEMBER_OBJECT_POINTER:
+  inform (loc, "  %qT is not a member object pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 897b96630f2..11fd70b3964 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -73,6 +73,7 @@ DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
 DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
+DEFTRAIT_EXPR (IS_MEMBER_OBJECT_POINTER, "__is_member_object_pointer", 1)
 DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index b28efbab322..32199a1fe9a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -53,6 +53,7 @@ struct cp_trait {
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
+"__is_member_object_pointer", CPTK_IS_MEMBER_OBJECT_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index d3d4bdf9799..799fe2b792f 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 53,
+  TOTAL_KEYWORDS = 54,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,57 +125,57 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 75 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 76 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 77 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 79 "../../gcc/cp/cp-trait.gperf"
+#line 80 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
 #line 45 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__t

[PATCH v18 22/40] c++: Implement __is_reference built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_reference.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_reference.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_REFERENCE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_reference.
* g++.dg/ext/is_reference.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 113 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_reference.C  |  34 +++
 7 files changed, 104 insertions(+), 55 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_reference.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 98b1f004a68..5cdb59d174e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
+case CPTK_IS_REFERENCE:
+  inform (loc, "  %qT is not a reference", t1);
+  break;
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 11fd70b3964..e867d9c4c47 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
+DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 32199a1fe9a..5989b84727f 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -61,6 +61,7 @@ struct cp_trait {
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false
 "__is_pod", CPTK_IS_POD, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
+"__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 799fe2b792f..f0b4f96d4a9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 94, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 40,  5, 40,
-  40,  0, 25, 10, 96,  0, 96, 96,  5, 25,
-  30,  0,  5, 96, 10, 15,  5,  0, 25, 96,
-  96, 20, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
+   40,   0, 

[PATCH v18 23/40] libstdc++: Optimize is_reference trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_reference trait by dispatching
to the new __is_reference built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in
trait.
(is_reference_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 792213ebfe8..36ad9814047 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -682,6 +682,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Composite type categories.
 
   /// is_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_reference
+: public __bool_constant<__is_reference(_Tp)>
+{ };
+#else
   template
 struct is_reference
 : public false_type
@@ -696,6 +702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_reference<_Tp&&>
 : public true_type
 { };
+#endif
 
   /// is_arithmetic
   template
@@ -3264,12 +3271,19 @@ template 
   inline constexpr bool is_class_v = __is_class(_Tp);
 template 
   inline constexpr bool is_function_v = is_function<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_reference_v = __is_reference(_Tp);
+#else
 template 
   inline constexpr bool is_reference_v = false;
 template 
   inline constexpr bool is_reference_v<_Tp&> = true;
 template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
+#endif
+
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
-- 
2.42.0



ping: [PATCH] preprocessor: c++: Support `#pragma GCC target' macros [PR87299]

2023-10-13 Thread Lewis Hyatt
On Tue, Sep 12, 2023 at 04:09:21PM -0400, Lewis Hyatt wrote:
> On Tue, Aug 8, 2023 at 5:53 PM Jason Merrill  wrote:
> >
> > On 7/31/23 22:22, Lewis Hyatt via Gcc-patches wrote:
> > > `#pragma GCC target' is not currently handled in preprocess-only mode 
> > > (e.g.,
> > > when running gcc -E or gcc -save-temps). As noted in the PR, this means 
> > > that
> > > if the target pragma defines any macros, those macros are not effective in
> > > preprocess-only mode. Similarly, such macros are not effective when
> > > compiling with C++ (even when compiling without -save-temps), because C++
> > > does not process the pragma until after all tokens have been obtained from
> > > libcpp, at which point it is too late for macro expansion to take place.
> > >
> > > Since r13-1544 and r14-2893, there is a general mechanism to handle 
> > > pragmas
> > > under these conditions as well, so resolve the PR by using the new "early
> > > pragma" support.
> > >
> > > toplev.cc required some changes because the target-specific handlers for
> > > `#pragma GCC target' may call target_reinit(), and toplev.cc was not 
> > > expecting
> > > that function to be called in preprocess-only mode.
> > >
> > > I added some additional testcases from the PR for x86. The other targets
> > > that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
> > > already had tests verifying that the pragma sets macros as expected; here 
> > > I
> > > have added -save-temps to some of them, to test that it now works in
> > > preprocess-only mode as well.
> > >
> > > gcc/c-family/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * c-pragma.cc (init_pragma): Register `#pragma GCC target' and
> > >   related pragmas in preprocess-only mode, and enable early handling.
> > >   (c_reset_target_pragmas): New function refactoring code from...
> > >   (handle_pragma_reset_options): ...here.
> > >   * c-pragma.h (c_reset_target_pragmas): Declare.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * parser.cc (cp_lexer_new_main): Call c_reset_target_pragmas ()
> > >   after preprocessing is complete, before starting compilation.
> > >
> > > gcc/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * toplev.cc (no_backend): New static global.
> > >   (finalize): Remove argument no_backend, which is now a
> > >   static global.
> > >   (process_options): Likewise.
> > >   (do_compile): Likewise.
> > >   (target_reinit): Don't do anything in preprocess-only mode.
> > >   (toplev::main): Adapt to no_backend change.
> > >   (toplev::finalize): Likewise.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >   PR preprocessor/87299
> > >   * c-c++-common/pragma-target-1.c: New test.
> > >   * c-c++-common/pragma-target-2.c: New test.
> > >   * g++.target/i386/pr87299-1.C: New test.
> > >   * g++.target/i386/pr87299-2.C: New test.
> > >   * gcc.target/i386/pr87299-1.c: New test.
> > >   * gcc.target/i386/pr87299-2.c: New test.
> > >   * gcc.target/s390/target-attribute/tattr-2.c: Add -save-temps to the
> > >   options, to test preprocess-only mode as well.
> > >   * gcc.target/aarch64/pragma_cpp_predefs_1.c: Likewise.
> > >   * gcc.target/arm/pragma_arch_attribute.c: Likewise.
> > >   * gcc.target/nios2/custom-fp-2.c: Likewise.
> > >   * gcc.target/powerpc/float128-3.c: Likewise.
> > > ---
> > >
> > > Notes:
> > >  Hello-
> > >
> > >  This patch fixes the PR by enabling early pragma handling for 
> > > `#pragma GCC
> > >  target' and related pragmas such as `#pragma GCC push_options'. I 
> > > did not
> > >  need to touch any target-specific code, however I did need to make a 
> > > change
> > >  to toplev.cc, affecting all targets, to make it safe to call 
> > > target_reinit()
> > >  in preprocess-only mode. (Otherwise, it would be necessary to modify 
> > > the
> > >  implementation of target pragmas in every target, to avoid this code 
> > > path.)
> > >  That was the only complication I ran into.
> > >
> > >  Regarding testing, I did: (thanks to GCC compile farm for the non-x86
> > >  targets)
> > >
> > >  bootstrap + regtest all languages - x86_64-pc-linux-gnu
> > >  bootstrap + regtest c/c++ - powerpc64le-unknown-linux-gnu,
> > >  aarch64-unknown-linux-gnu
> > >
> > >  The following backends also implement this pragma so ought to be 
> > > tested:
> > >  arm
> > >  nios2
> > >  s390
> > >
> > >  I am not able to test those directly. I did add coverage to their 
> > > testsuites
> > >  (basically, adding -save-temps to any existing test, causes it to 
> > > test the
> > >  pragma in preprocess-only mode.) Then, I verified on x86_64 with a 
> > > cross
> > >  compiler, that the modified testcases fail before the patch and pass
> > >  afterwards. nios2 is an exception, it does not se

[PATCH v18 24/40] c++: Implement __is_function built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_function.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_function.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_FUNCTION.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_function.
* g++.dg/ext/is_function.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 143 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_function.C   |  58 +
 7 files changed, 143 insertions(+), 70 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_function.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5cdb59d174e..99a7e7247ce 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3750,6 +3750,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_FINAL:
   inform (loc, "  %qT is not a final class", t1);
   break;
+case CPTK_IS_FUNCTION:
+  inform (loc, "  %qT is not a function", t1);
+  break;
 case CPTK_IS_LAYOUT_COMPATIBLE:
   inform (loc, "  %qT is not layout compatible with %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e867d9c4c47..fa79bc0c68c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -70,6 +70,7 @@ DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
 DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
+DEFTRAIT_EXPR (IS_FUNCTION, "__is_function", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
 DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 5989b84727f..771242a7f45 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -50,6 +50,7 @@ struct cp_trait {
 "__is_empty", CPTK_IS_EMPTY, 1, false
 "__is_enum", CPTK_IS_ENUM, 1, false
 "__is_final", CPTK_IS_FINAL, 1, false
+"__is_function", CPTK_IS_FUNCTION, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f0b4f96d4a9..b6db58e93c9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 94, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
-   40,   0,  60,  10, 101,   0, 101, 101,   5,  25,
-   30,   0,   5, 101,  10,  15,   5,   0,  25, 101,
-  101,  20, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 11

[PATCH v18 25/40] libstdc++: Optimize is_function trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_function trait by dispatching
to the new __is_function built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_function): Use __is_function built-in
trait.
(is_function_v): Likewise. Optimize its implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 36ad9814047..bd57488824b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -637,6 +637,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_function
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+  template
+struct is_function
+: public __bool_constant<__is_function(_Tp)>
+{ };
+#else
   template
 struct is_function
 : public __bool_constant::value> { };
@@ -648,6 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_function<_Tp&&>
 : public false_type { };
+#endif
 
 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
   /// is_null_pointer (LWG 2247).
@@ -3269,8 +3276,18 @@ template 
   inline constexpr bool is_union_v = __is_union(_Tp);
 template 
   inline constexpr bool is_class_v = __is_class(_Tp);
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
 template 
-  inline constexpr bool is_function_v = is_function<_Tp>::value;
+  inline constexpr bool is_function_v = __is_function(_Tp);
+#else
+template 
+  inline constexpr bool is_function_v = !is_const_v;
+template 
+  inline constexpr bool is_function_v<_Tp&> = false;
+template 
+  inline constexpr bool is_function_v<_Tp&&> = false;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
 template 
-- 
2.42.0



[PATCH v18 26/40] libstdc++: Optimize is_object trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_object trait by dispatching to
the new __is_function and __is_reference built-in traits.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use __is_function and
__is_reference built-in traits.
(is_object_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index bd57488824b..674d398c075 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_object
+: public __bool_constant::value)>
+{ };
+#else
   template
 struct is_object
 : public __not_<__or_, is_reference<_Tp>,
   is_void<_Tp>>>::type
 { };
+#endif
 
   template
 struct is_member_pointer;
@@ -3305,8 +3314,17 @@ template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_object_v
+= !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
+#else
 template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v18 27/40] c++: Implement __remove_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
* g++.dg/ext/remove_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 32 +++---
 gcc/cp/semantics.cc   |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++
 6 files changed, 78 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index fa79bc0c68c..2add97ae749 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -97,6 +97,7 @@ DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_tempo
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 771242a7f45..8fbd67788d5 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -77,6 +77,7 @@ struct cp_trait {
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
 "__remove_cv", CPTK_REMOVE_CV, 1, true
 "__remove_cvref", CPTK_REMOVE_CVREF, 1, true
+"__remove_pointer", CPTK_REMOVE_POINTER, 1, true
 "__remove_reference", CPTK_REMOVE_REFERENCE, 1, true
 "__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true
 "__underlying_type", CPTK_UNDERLYING_TYPE, 1, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index b6db58e93c9..ad2c2a2d250 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 56,
+  TOTAL_KEYWORDS = 57,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,7 +125,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 84 "../../gcc/cp/cp-trait.gperf"
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
@@ -137,17 +137,19 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
+#line 80 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
 #line 69 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 80 "../../gcc/cp/cp-trait.gperf"
+#line 81 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
 #line 45 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
 #line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false},
@@ -235,21 +237,21 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__is_final", CPTK_IS_FINAL, 1, false},
 #line 53 "../../gcc/cp/cp-trait.gperf"
   {"__is_function", CPTK_IS_FUNCTION, 1, false},
-#line 83 "../../gcc/cp/cp-trait.gperf"
+#line 84 "../../gcc/cp/cp-trait.gperf"
   {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false}
 };
 
   static const signed char lookup[] =
 {
   -1, -1, -1, -1, -1, -1, -1,  0, -1,  1,  2,  3, -1, -1,
-   4,  5, -1,  6,  7,  8, -1, -1,  9, 10, 11, 12, 13, 14,
-  15, -1, 16, 17, 18, 19, -1, 20, -1, 21, 22, -1, 23, -1,
-  24, 25, 26, 27, -1, 28, 29, 30, 31, -1, 32, -1, 33, 34,
-  -1, -1, 35, 36, 37, 38, -1, 39, 40, -1, -1, -1, 41, 42,
-  43, -1, -1, -1, -1, 44, 45, -1, 46, 47, 48, -1, -1, -1,
-  -1, 49, 50, -1, 51, -1, 52, -1, -1, -1, -1, 53, -1, -1,
-  54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, 55
+   4,  5,  6,  7

[PATCH v18 28/40] libstdc++: Optimize remove_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the remove_pointer trait by
dispatching to the new remove_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (remove_pointer): Use __remove_pointer
built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 674d398c075..9c56d15c0b7 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2105,6 +2105,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
+  template
+struct remove_pointer
+{ using type = __remove_pointer(_Tp); };
+#else
   template
 struct __remove_pointer_helper
 { using type = _Tp; };
@@ -2113,11 +2119,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __remove_pointer_helper<_Tp, _Up*>
 { using type = _Up; };
 
-  /// remove_pointer
   template
 struct remove_pointer
 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
 { };
+#endif
 
   template
 struct __add_pointer_helper
-- 
2.42.0



[PATCH v18 29/40] c++: Implement __is_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_pointer.
* g++.dg/ext/is_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 155 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_pointer.C|  51 
 7 files changed, 141 insertions(+), 77 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 99a7e7247ce..c9d627fa782 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POD:
   inform (loc, "  %qT is not a POD type", t1);
   break;
+case CPTK_IS_POINTER:
+  inform (loc, "  %qT is not a pointer", t1);
+  break;
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 2add97ae749..c60724e869e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, 
"__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
+DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 8fbd67788d5..5d40e04f91c 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -61,6 +61,7 @@ struct cp_trait {
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false
 "__is_pod", CPTK_IS_POD, 1, false
+"__is_pointer", CPTK_IS_POINTER, 1, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ad2c2a2d250..ab783b161c7 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  40,   5,  40,
-   50,   0,  55,  10, 116,   0, 116, 116,   5,  25,
-   30,   0,   5, 116,  10,  15,   5,   0,  25, 116,
-  116,  20, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 

[PATCH v18 30/40] libstdc++: Optimize is_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_pointer trait by dispatching to
the new __is_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_pointer): Use __is_pointer
built-in trait.
* include/std/type_traits (is_pointer): Likewise. Optimize its
implementation.
(is_pointer_v): Likewise.

Co-authored-by: Jonathan Wakely 
Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/bits/cpp_type_traits.h |  8 
 libstdc++-v3/include/std/type_traits| 44 +
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 4312f32a4e0..cd5ce45951f 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -363,6 +363,13 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   //
   // Pointer types
   //
+#if __has_builtin(__is_pointer)
+  template
+struct __is_pointer : __truth_type<__is_pointer(_Tp)>
+{
+  enum { __value = __is_pointer(_Tp) };
+};
+#else
   template
 struct __is_pointer
 {
@@ -376,6 +383,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   enum { __value = 1 };
   typedef __true_type __type;
 };
+#endif
 
   //
   // An arithmetic type is an integer type or a floating point type
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 9c56d15c0b7..3acd843f2f2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -542,19 +542,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
 #endif
 
-  template
-struct __is_pointer_helper
+  /// is_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+  template
+struct is_pointer
+: public __bool_constant<__is_pointer(_Tp)>
+{ };
+#else
+  template
+struct is_pointer
 : public false_type { };
 
   template
-struct __is_pointer_helper<_Tp*>
+struct is_pointer<_Tp*>
 : public true_type { };
 
-  /// is_pointer
   template
-struct is_pointer
-: public __is_pointer_helper<__remove_cv_t<_Tp>>::type
-{ };
+struct is_pointer<_Tp* const>
+: public true_type { };
+
+  template
+struct is_pointer<_Tp* volatile>
+: public true_type { };
+
+  template
+struct is_pointer<_Tp* const volatile>
+: public true_type { };
+#endif
 
   /// is_lvalue_reference
   template
@@ -3254,8 +3268,22 @@ template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+template 
+  inline constexpr bool is_pointer_v = __is_pointer(_Tp);
+#else
 template 
-  inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
+  inline constexpr bool is_pointer_v = false;
+template 
+  inline constexpr bool is_pointer_v<_Tp*> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* const> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* volatile> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* const volatile> = true;
+#endif
+
 template 
   inline constexpr bool is_lvalue_reference_v = false;
 template 
-- 
2.42.0



[PATCH v18 31/40] c++: Implement __is_arithmetic built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_arithmetic.
* g++.dg/ext/is_arithmetic.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 184 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_arithmetic.C |  33 
 7 files changed, 138 insertions(+), 91 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9d627fa782..3a7f968eae8 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
 case CPTK_IS_ARRAY:
   inform (loc, "  %qT is not an array", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index c60724e869e..b2be7b7bbd7 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 5d40e04f91c..9050c36f105 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_arithmetic", CPTK_IS_ARITHMETIC, 1, false
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ab783b161c7..31fd5075f2d 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 97, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99, 40, 45, 40,
-   5,  0, 55, 10, 99,  0, 99, 99, 10, 25,
-  30,  0, 10, 99, 10, 15,  5,  0, 20, 99,
-  99, 10, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
+5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
+   35,   0,

[PATCH v18 32/40] libstdc++: Optimize is_arithmetic trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_arithmetic trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_arithmetic): Use __is_arithmetic
built-in trait.
(is_arithmetic_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 3acd843f2f2..cc466e0f606 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -726,10 +726,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_arithmetic
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_arithmetic
+: public __bool_constant<__is_arithmetic(_Tp)>
+{ };
+#else
   template
 struct is_arithmetic
 : public __or_, is_floating_point<_Tp>>::type
 { };
+#endif
 
   /// is_fundamental
   template
@@ -3344,8 +3351,14 @@ template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+template 
+  inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+#else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
 
-- 
2.42.0



[PATCH v18 33/40] libstdc++: Optimize is_fundamental trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_fundamental trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_fundamental_v): Use __is_arithmetic
built-in trait.
(is_fundamental): Likewise. Optimize the original implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index cc466e0f606..88171e1a672 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -739,11 +739,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_fundamental
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_fundamental
+: public __bool_constant<__is_arithmetic(_Tp)
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
+{ };
+#else
   template
 struct is_fundamental
-: public __or_, is_void<_Tp>,
-  is_null_pointer<_Tp>>::type
+: public __bool_constant::value
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
 { };
+#endif
 
   /// is_object
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
@@ -3354,13 +3364,15 @@ template 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
 template 
   inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+template 
+  inline constexpr bool is_fundamental_v
+= __is_arithmetic(_Tp) || is_void_v<_Tp> || is_null_pointer_v<_Tp>;
 #else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
-#endif
-
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
  && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
-- 
2.42.0



[PATCH v18 35/40] c++: Implement __is_unsigned built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_unsigned.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unsigned.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNSIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_unsigned.
* g++.dg/ext/is_unsigned.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 118 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_unsigned.C   |  47 +
 7 files changed, 120 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unsigned.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 3a7f968eae8..c28dad702c3 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3829,6 +3829,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_VOLATILE:
   inform (loc, "  %qT is not a volatile type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b2be7b7bbd7..0603b4a230f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -94,6 +94,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, 
"__is_trivially_constructible", -1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (IS_UNSIGNED, "__is_unsigned", 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)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 9050c36f105..90d05bca5c1 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -74,6 +74,7 @@ struct cp_trait {
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false
 "__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false
 "__is_union", CPTK_IS_UNION, 1, false
+"__is_unsigned", CPTK_IS_UNSIGNED, 1, false
 "__is_volatile", CPTK_IS_VOLATILE, 1, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
2, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, 
false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 31fd5075f2d..75ab2b5edfa 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 97, duplicates = 0 */
+/* maximum key range = 129, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
-5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
-   35,   0,  10, 104,  10,  15,   5,   0,  20, 104,
-  104,  20, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136

[PATCH v18 34/40] libstdc++: Optimize is_compound trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_compound trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_compound): Do not use __not_.
(is_compound_v): Use is_fundamental_v instead.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 88171e1a672..48d630a1478 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_compound
   template
 struct is_compound
-: public __not_>::type { };
+: public __bool_constant::value> { };
 
   /// is_member_pointer
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
@@ -3387,7 +3387,7 @@ template 
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-  inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+  inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
 template 
-- 
2.42.0



[PATCH v18 36/40] libstdc++: Optimize is_unsigned trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unsigned trait by dispatching
to the new __is_unsigned built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unsigned): Use __is_unsigned built-in
trait.
(is_unsigned_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 48d630a1478..f7d3815f332 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1001,10 +1001,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_unsigned
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__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
@@ -3440,8 +3447,14 @@ template 
 
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+template 
+  inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+#else
 template 
   inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+#endif
 
 template 
   inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
-- 
2.42.0



[PATCH v18 37/40] c++: Implement __is_signed built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_signed.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_signed.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_signed.
* g++.dg/ext/is_signed.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 211 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_signed.C |  47 +
 7 files changed, 165 insertions(+), 105 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_signed.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c28dad702c3..b161c9b2c9e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SIGNED:
+  inform (loc, "  %qT is not a signed type", t1);
+  break;
 case CPTK_IS_SCOPED_ENUM:
   inform (loc, "  %qT is not a scoped enum", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 0603b4a230f..b0faa4c8937 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 90d05bca5c1..de0ba162e7a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
 "__is_trivial", CPTK_IS_TRIVIAL, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 75ab2b5edfa..6d1078de2fe 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 129, duplicates = 0 */
+/* maximum key range = 119, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136,  20, 136,  45,  35,  40,
-   60,   0,  55,   0, 136,   0, 136, 136,  10,  15,
-   35,   0,  10, 136,  10,  15,   5,  15,   0, 136,
-  136,  20, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 1

[PATCH v18 38/40] libstdc++: Optimize is_signed trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_signed trait by dispatching to
the new __is_signed built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_signed): Use __is_signed built-in trait.
(is_signed_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index f7d3815f332..7e93923f44b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -982,6 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __bool_constant<__is_abstract(_Tp)>
 { };
 
+  /// is_signed
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+  template
+struct is_signed
+: public __bool_constant<__is_signed(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template::value>
@@ -994,11 +1001,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
   /// @endcond
 
-  /// is_signed
   template
 struct is_signed
 : public __is_signed_helper<_Tp>::type
 { };
+#endif
 
   /// is_unsigned
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
@@ -3445,8 +3452,13 @@ template 
 template 
   inline constexpr bool is_final_v = __is_final(_Tp);
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+template 
+  inline constexpr bool is_signed_v = __is_signed(_Tp);
+#else
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
 template 
-- 
2.42.0



[PATCH v18 39/40] c++: Implement __is_scalar built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scalar.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scalar.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCALAR.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_scalar.
* g++.dg/ext/is_scalar.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 186 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_scalar.C |  31 
 7 files changed, 137 insertions(+), 92 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scalar.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b161c9b2c9e..78f100d2745 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCALAR:
+  inform (loc, "  %qT is not a scalar type", t1);
+  break;
 case CPTK_IS_SIGNED:
   inform (loc, "  %qT is not a signed type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b0faa4c8937..08a2780c929 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCALAR, "__is_scalar", 1)
 DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index de0ba162e7a..ef51c713c58 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scalar", CPTK_IS_SCALAR, 1, false
 "__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 6d1078de2fe..8c68af420f9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -78,10 +78,10 @@ cp_trait_lookup::hash (const char *str, size_t len)
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-  126, 126, 126, 126, 126,  20, 126,  40,  45,  50,
-   55,   0,   5,  15, 126,   0, 126, 126,  35,  10,
-   35,   0,  10, 126,  30,   5,   5,  16,  30, 126,
-  126,  10, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126,  40, 126,  25,  21,  50,
+0,   0,  30,  10, 126,   0, 126, 126,  25,   5,
+   50,   0,  61, 126,  10,  10,   5,   0,  15, 126,
+  126,   5, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 61,
+  TOTAL_KEYWORDS = 62,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,141 +125,143 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 89 "../../gcc/cp/cp-trait.gperf"
+#line 90 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 52 "../../gcc/cp/cp-trait.gperf"
+  {"__is_enum", CPTK_IS_ENUM, 1, false},
+#line 78 "../../gcc/cp/cp-trait.gperf"
+  {"__is_union", CPTK_IS_UNION, 1, false},
 #line 83 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 84 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+#line 89 "../../gcc/cp/cp-trait.gperf"
+  {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false},
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"

[PATCH v18 40/40] libstdc++: Optimize is_scalar trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_scalar trait by dispatching to
the new __is_scalar built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scalar): Use __is_scalar built-in
trait.
(is_scalar_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7e93923f44b..eb16a642575 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -775,11 +775,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_pointer;
 
   /// is_scalar
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+  template
+struct is_scalar
+: public __bool_constant<__is_scalar(_Tp)>
+{ };
+#else
   template
 struct is_scalar
 : public __or_, is_enum<_Tp>, is_pointer<_Tp>,
is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
 { };
+#endif
 
   /// is_compound
   template
@@ -3398,8 +3405,14 @@ template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+template 
+  inline constexpr bool is_scalar_v = __is_scalar(_Tp);
+#else
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
-- 
2.42.0



Re: Continued (Non)mutlib and stub header issue (was Re: [PATCH v2] RISC-V: Use stdint-gcc.h in rvv testsuite)

2023-10-13 Thread Kito Cheng
> When looking around, I stumbled upon commit
>  d0bbecb1c41 "RISC-V: Add riscv_vector.h wrapper in testsuite to
> prevent pull in stdint.h from C library"
>work
> Which seems like a step in a right direction, but how does one ensure
> that the wrapper riscv_vector.h (containing stdint-gcc.h) is included by
> test vs. the default riscv_vector.h (which is more user facing and thus
> needs to include the system stdint.h)

IIRC it rely on #include "" vs #include <>, the former will
search the same folder first, then the header search path,
so...made a dummy one, and put into test folder, then it will use our
own version now :P

but I guess maybe the right way (or simpler way) is just adding an
extra header search path to CFLAG and making a dummy stdint.h as well?

>
> P.S. I couldn't find the posting for above commit on gcc-patches ?

Here is the mail:
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603140.html

>
> Thx,
> -Vineet


[PATCH] c++: fix truncated diagnostic in C++23 [PR111272]

2023-10-13 Thread Marek Polacek
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
In C++23, since P2448, a constexpr function F that calls a non-constexpr
function N is OK as long as we don't actually call F in a constexpr
context.  So instead of giving an error in maybe_save_constexpr_fundef,
we only give an error when evaluating the call.  Unfortunately, as shown
in this PR, the diagnostic can be truncated:

z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function 
because:
   10 |   constexpr Jam() { ft(); }
  | ^~~

...because what?  With this patch, we say:

z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function 
because:
   10 |   constexpr Jam() { ft(); }
  | ^~~
z.C:10:23: error: call to non-'constexpr' function 'int Jam::ft()'
   10 |   constexpr Jam() { ft(); }
  | ~~^~
z.C:8:7: note: 'int Jam::ft()' declared here
8 |   int ft() { return 42; }
  |   ^~

Like maybe_save_constexpr_fundef, explain_invalid_constexpr_fn should
also check the body of a constructor, not just the mem-initializer.

PR c++/111272

gcc/cp/ChangeLog:

* constexpr.cc (explain_invalid_constexpr_fn): Also check the body of
a constructor in C++14 and up.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-diag1.C: New test.
---
 gcc/cp/constexpr.cc  | 10 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C | 21 
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 0f948db7c2d..dde4fec4a44 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1098,7 +1098,15 @@ explain_invalid_constexpr_fn (tree fun)
  body = massage_constexpr_body (fun, body);
  require_potential_rvalue_constant_expression (body);
  if (DECL_CONSTRUCTOR_P (fun))
-   cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
+   {
+ cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
+ if (cxx_dialect > cxx11)
+   {
+ /* Also check the body, not just the ctor-initializer.  */
+ body = DECL_SAVED_TREE (fun);
+ require_potential_rvalue_constant_expression (body);
+   }
+   }
}
 }
 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C
new file mode 100644
index 000..0e2909e83ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-diag1.C
@@ -0,0 +1,21 @@
+// PR c++/111272
+// { dg-do compile { target c++14 } }
+// { dg-options "-Werror=invalid-constexpr" }
+// { dg-prune-output "some warnings being treated as errors" }
+
+struct Jam
+{
+  // constexpr  // n.b.
+  int ft() { return 42; } // { dg-message "declared here" }
+
+  constexpr Jam() { ft(); } // { dg-error "call to non-.constexpr. function" }
+// { dg-message "declared here" "" { target c++20_down } .-1 }
+};
+
+constexpr bool test()
+{
+  Jam j; // { dg-error "called in a constant expression" }
+  return true;
+}
+
+static_assert(test(), ""); // { dg-error "non-constant condition" }

base-commit: d78fef5371759849944966dec65d9e987efba509
-- 
2.41.0



[PATCH v19 00/40] Optimize type traits performance

2023-10-13 Thread Ken Matsui
This patch series optimizes type traits performance by implementing
built-in type traits and using them in libstdc++.

Changes in v19:

* Fixed a typo.
* Rebased on top of trunk.
* Improved clarity of the commit message.

Changes in v18:

* Removed all RID values for built-in traits and used cik_trait
instead.
* Improved to handle the use of non-function-like built-in trait
identifiers.
* Reverted all changes to conflicted identifiers with new built-ins
in the existing code base.

Changes in v17:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in.
* Made ridpointers for RID_TRAIT_EXPR and RID_TRAIT_TYPE empty.

Changes in v16:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in and gperf struct.
* Supply -k option to gperf to support older versions than 2.8.

Changes in v15:

* Rebased on top of trunk.
* Use gperf to look up traits instead of enum rid.

Changes in v14:

* Added padding calculation to the commit message.

Changes in v13:

* Fixed ambiguous commit message and comment.

Changes in v12:

* Evaluated all paddings affected by the enum rid change.

Changes in v11:

* Merged all patches into one patch series.
* Rebased on top of trunk.
* Unified commit message style.
* Used _GLIBCXX_USE_BUILTIN_TRAIT.

Ken Matsui (40):
  c++: Sort built-in traits alphabetically
  c-family, c++: Look up built-in traits through gperf
  c++: Accept the use of built-in trait identifiers
  c++: Implement __is_const built-in trait
  libstdc++: Optimize is_const trait performance
  c++: Implement __is_volatile built-in trait
  libstdc++: Optimize is_volatile trait performance
  c++: Implement __is_array built-in trait
  libstdc++: Optimize is_array trait performance
  c++: Implement __is_unbounded_array built-in trait
  libstdc++: Optimize is_unbounded_array trait performance
  c++: Implement __is_bounded_array built-in trait
  libstdc++: Optimize is_bounded_array trait performance
  c++: Implement __is_scoped_enum built-in trait
  libstdc++: Optimize is_scoped_enum trait performance
  c++: Implement __is_member_pointer built-in trait
  libstdc++: Optimize is_member_pointer trait performance
  c++: Implement __is_member_function_pointer built-in trait
  libstdc++: Optimize is_member_function_pointer trait performance
  c++: Implement __is_member_object_pointer built-in trait
  libstdc++: Optimize is_member_object_pointer trait performance
  c++: Implement __is_reference built-in trait
  libstdc++: Optimize is_reference trait performance
  c++: Implement __is_function built-in trait
  libstdc++: Optimize is_function trait performance
  libstdc++: Optimize is_object trait performance
  c++: Implement __remove_pointer built-in trait
  libstdc++: Optimize remove_pointer trait performance
  c++: Implement __is_pointer built-in trait
  libstdc++: Optimize is_pointer trait performance
  c++: Implement __is_arithmetic built-in trait
  libstdc++: Optimize is_arithmetic trait performance
  libstdc++: Optimize is_fundamental trait performance
  libstdc++: Optimize is_compound trait performance
  c++: Implement __is_unsigned built-in trait
  libstdc++: Optimize is_unsigned trait performance
  c++: Implement __is_signed built-in trait
  libstdc++: Optimize is_signed trait performance
  c++: Implement __is_scalar built-in trait
  libstdc++: Optimize is_scalar trait performance

 gcc/c-family/c-common.cc  |   7 -
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 ++
 gcc/cp/constraint.cc  | 112 +--
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 ++
 gcc/cp/cp-trait.def   |  27 +-
 gcc/cp/cp-trait.gperf |  91 ++
 gcc/cp/cp-trait.h | 285 ++
 gcc/cp/cp-tree.h  |  14 +-
 gcc/cp/lex.cc |  19 ++
 gcc/cp/parser.cc  | 144 ++---
 gcc/cp/semantics.cc   | 157 +++---
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  | 117 +--
 gcc/testsuite/g++.dg/ext/is_arithmetic.C  |  33 ++
 gcc/testsuite/g++.dg/ext/is_array.C   |  28 ++
 gcc/testsuite/g++.dg/ext/is_bounded_array.C   |  38 +++
 gcc/testsuite/g++.dg/ext/is_const.C   |  19 ++
 gcc/testsuite/g++.dg/ext/is_function.C|  58 
 .../g++.dg/ext/is_member_function_pointer.C   |  31 ++
 .../g++.dg/ext/is_member_object_pointer.C |  30 ++
 gcc/testsuite/g++.dg/ext/is_member_pointer.C  |  30 ++
 gcc/testsuite/g++.dg/ext/is_pointer.C |  51 
 gcc/testsuite/g++.dg/ext/is_reference.C   |  34 +++

[PATCH v19 01/40] c++: Sort built-in traits alphabetically

2023-10-13 Thread Ken Matsui
This patch sorts built-in traits alphabetically for better code
readability.

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Sort built-in traits
alphabetically.
* cp-trait.def: Likewise.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(finish_trait_type): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc | 68 -
 gcc/cp/cp-trait.def  | 10 +--
 gcc/cp/semantics.cc  | 94 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +-
 4 files changed, 121 insertions(+), 121 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9e4e7043cd..722fc334e6f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
   inform (loc, "  %qT is not trivially destructible", t1);
   break;
+case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+  inform (loc, "  %qT does not have unique object representations", t1);
+  break;
 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
   inform (loc, "  %qT does not have a virtual destructor", t1);
   break;
 case CPTK_IS_ABSTRACT:
   inform (loc, "  %qT is not an abstract class", t1);
   break;
+case CPTK_IS_AGGREGATE:
+  inform (loc, "  %qT is not an aggregate", t1);
+  break;
+case CPTK_IS_ASSIGNABLE:
+  inform (loc, "  %qT is not assignable from %qT", t1, t2);
+  break;
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONSTRUCTIBLE:
+  if (!t2)
+inform (loc, "  %qT is not default constructible", t1);
+  else
+inform (loc, "  %qT is not constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_CONVERTIBLE:
+  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_EMPTY:
   inform (loc, "  %qT is not an empty class", t1);
   break;
@@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_NOTHROW_ASSIGNABLE:
+  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+  if (!t2)
+   inform (loc, "  %qT is not nothrow default constructible", t1);
+  else
+   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   inform (loc, "  %qT is not pointer-interconvertible base of %qT",
  t1, t2);
@@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIAL:
   inform (loc, "  %qT is not a trivial type", t1);
   break;
-case CPTK_IS_UNION:
-  inform (loc, "  %qT is not a union", t1);
-  break;
-case CPTK_IS_AGGREGATE:
-  inform (loc, "  %qT is not an aggregate", t1);
-  break;
-case CPTK_IS_TRIVIALLY_COPYABLE:
-  inform (loc, "  %qT is not trivially copyable", t1);
-  break;
-case CPTK_IS_ASSIGNABLE:
-  inform (loc, "  %qT is not assignable from %qT", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
   inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
   break;
-case CPTK_IS_NOTHROW_ASSIGNABLE:
-  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
-  break;
-case CPTK_IS_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not default constructible", t1);
-  else
-   inform (loc, "  %qT is not constructible from %qE", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
   if (!t2)
inform (loc, "  %qT is not trivially default constructible", t1);
   else
inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
   break;
-case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not nothrow default constructible", t1);
-  else
-   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
-  break;
-case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
-  inform (loc, "  %qT does not have unique object representations", t1);
-  break;
-case CPTK_IS_CONVERTIBLE:
-  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+case CPTK_IS_TRIVIALLY_COPYABLE:
+  inform (loc, "  %qT is not trivially copyable", t1);
   break;
-case CPTK_IS_NOTHROW_CONVERTIBLE:
-   infor

[PATCH v19 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-13 Thread Ken Matsui
Since RID_MAX soon reaches 255 and all built-in traits are used approximately
once in a C++ translation unit, this patch removes all RID values for built-in
traits and uses gperf to look up the specific trait.  Rather than holding
traits as keywords, we set all trait identifiers as cik_trait, which is a new
cp_identifier_kind.  As cik_reserved_for_udlit was unused and
cp_identifier_kind is 3 bits, we replaced the unused field with the new
cik_trait.  Also, the later patch handles a subsequent token to the built-in
identifier so that we accept the use of non-function-like built-in trait
identifiers.

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Remove all mappings of
built-in traits.
* c-common.h (enum rid): Remove all RID values for built-in traits.

gcc/cp/ChangeLog:

* Make-lang.in: Add targets to generate cp-trait.gperf and
cp-trait.h.
* cp-objcp-common.cc (names_builtin_p): Remove all RID value
cases for built-in traits.  Check for built-in traits via
the new cik_trait identifier.
* cp-tree.h (cik_reserved_for_udlit): Rename to ...
(cik_trait): ... this.
(IDENTIFIER_ANY_OP_P): Exclude cik_trait.
(IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
* lex.cc (init_cp_traits): New function to set cik_trait for all
built-in trait identifiers.
(cxx_init): Call init_cp_traits function.
* parser.cc (cp_lexer_lookup_trait): New function to look up a
built-in trait from a token by gperf.
(cp_lexer_lookup_trait_expr): Likewise, look up an
expression-yielding built-in trait.
(cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
built-in trait.
(cp_keyword_starts_decl_specifier_p): Remove all RID value cases
for built-in traits.
(cp_lexer_next_token_is_decl_specifier_keyword): Handle
type-yielding built-in traits.
(cp_parser_primary_expression): Remove all RID value cases for
built-in traits.  Handle expression-yielding built-in traits.
(cp_parser_trait): Handle cp_trait instead of enum rid.
(cp_parser_simple_type_specifier): Remove all RID value cases
for built-in traits.  Handle type-yielding built-in traits.
* cp-trait-head.in: New file.
* cp-trait.gperf: New file.
* cp-trait.h: New file.

Co-authored-by: Patrick Palka 
Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |   7 --
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/Make-lang.in   |  26 
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait-head.in   |  30 +
 gcc/cp/cp-trait.gperf |  74 
 gcc/cp/cp-trait.h | 247 ++
 gcc/cp/cp-tree.h  |  14 ++-
 gcc/cp/lex.cc |  19 +++
 gcc/cp/parser.cc  | 132 
 10 files changed, 492 insertions(+), 70 deletions(-)
 create mode 100644 gcc/cp/cp-trait-head.in
 create mode 100644 gcc/cp/cp-trait.gperf
 create mode 100644 gcc/cp/cp-trait.h

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index f044db5b797..21fd333ef57 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
   { "wchar_t", RID_WCHAR,  D_CXXONLY },
   { "while",   RID_WHILE,  0 },
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  { NAME,  RID_##CODE, D_CXXONLY },
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-  /* An alias for __is_same.  */
-  { "__is_same_as",RID_IS_SAME,D_CXXONLY },
-
   /* C++ transactional memory.  */
   { "synchronized",RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1fdba7ef3ea..051a442e0f4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -168,11 +168,6 @@ enum rid
   RID_BUILTIN_LAUNDER,
   RID_BUILTIN_BIT_CAST,
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  RID_##CODE,
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-
   /* C++11 */
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
 
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 2727fb7f8cc..a67d1c3e9f3 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -34,6 +34,8 @@
 # - the compiler proper (eg: cc1plus)
 # - define the names for selecting the language in LANGUAGES.
 
+AWK = @AWK@
+
 # Actual names to use when installing a native compiler.
 CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
 GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
@@ -186,6 +188,30 @@ endif
 # This is the file that depends on the generated header file.
 cp/name-lookup.o: $(srcdir)/cp/std-name-hint.h
 
+# We always need the dependency on the .gperf file
+# because it itself is generated.
+ifeq ($(ENABLE_MAIN

[PATCH v19 03/40] c++: Accept the use of built-in trait identifiers

2023-10-13 Thread Ken Matsui
This patch accepts the use of built-in trait identifiers when they are
actually not used as traits.  Specifically, we check if the subsequent token
is '(' for ordinary built-in traits or is '<' only for the special
__type_pack_element built-in trait.  If those identifiers are used
differently, the parser treats them as normal identifiers.  This allows
us to accept code like: struct __is_pointer {};.

gcc/cp/ChangeLog:

* parser.cc (cp_lexer_lookup_trait): Rename to ...
(cp_lexer_peek_trait): ... this.  Handle a subsequent token for
the corresponding built-in trait.
(cp_lexer_lookup_trait_expr): Rename to ...
(cp_lexer_peek_trait_expr): ... this.
(cp_lexer_lookup_trait_type): Rename to ...
(cp_lexer_peek_trait_type): ... this.
(cp_lexer_next_token_is_decl_specifier_keyword): Call
cp_lexer_peek_trait_type.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_primary_expression): Call cp_lexer_peek_trait_expr.

Signed-off-by: Ken Matsui 
---
 gcc/cp/parser.cc | 48 ++--
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 39952893ffa..59015eac596 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -247,12 +247,12 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static const cp_trait *cp_lexer_lookup_trait
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_expr
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_type
-  (const cp_token *);
+static const cp_trait *cp_lexer_peek_trait
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_expr
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_type
+  (cp_lexer *lexer, const cp_token *);
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -1183,21 +1183,33 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
 }
 }
 
-/* Look ups the corresponding built-in trait if a given token is
+/* Peeks the corresponding built-in trait if a given token is
a built-in trait.  Otherwise, returns nullptr.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait (const cp_token *token)
+cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
 {
-  tree id = token->u.value;
+  tree id = token1->u.value;
 
-  if (token->type == CPP_NAME
+  if (token1->type == CPP_NAME
   && TREE_CODE (id) == IDENTIFIER_NODE
   && IDENTIFIER_TRAIT_P (id))
 {
   const char *id_str = IDENTIFIER_POINTER (id);
   const int id_len = IDENTIFIER_LENGTH (id);
-  return cp_trait_lookup::find (id_str, id_len);
+  const cp_trait *trait = cp_trait_lookup::find (id_str, id_len);
+
+  /* Check if the subsequent token is a `<' token to
+ __type_pack_element or is a `(' token to everything else.  */
+  const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
+  if (trait->kind == CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_LESS)
+   return nullptr;
+  if (trait->kind != CPTK_TYPE_PACK_ELEMENT
+ && token2->type != CPP_OPEN_PAREN)
+   return nullptr;
+
+  return trait;
 }
   return nullptr;
 }
@@ -1206,9 +1218,9 @@ cp_lexer_lookup_trait (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_expr (const cp_token *token)
+cp_lexer_peek_trait_expr (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && !trait->type)
 return trait;
 
@@ -1219,9 +1231,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_type (const cp_token *token)
+cp_lexer_peek_trait_type (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && trait->type)
 return trait;
 
@@ -1236,7 +1248,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
*lexer)
   cp_token *token;
 
   token = cp_lexer_peek_token (lexer);
-  if (cp_lexer_lookup_trait_type (token))
+  if (cp_lexer_peek_trait_type (lexer, token))
 return true;
   return cp_keyword_starts_decl_specifier_p (token->keyword);
 }
@@ -6108,7 +6120,7 @@ cp_parser_primary_expression (cp_parser *parser,
 keyword.  */
 case CPP_NAME:
   {
-   const cp_trait* trait = cp_lexer_lookup_trait_expr (token);
+   const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer, token);
if (trait)
  return cp_parser_trait (parser, trait);
   }
@@ -20117,7 +20129,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 }
 
   /* If token is a type-yielding built-in traits, pars

[PATCH v19 28/40] libstdc++: Optimize remove_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the remove_pointer trait by
dispatching to the new remove_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (remove_pointer): Use __remove_pointer
built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 674d398c075..9c56d15c0b7 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2105,6 +2105,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
+  template
+struct remove_pointer
+{ using type = __remove_pointer(_Tp); };
+#else
   template
 struct __remove_pointer_helper
 { using type = _Tp; };
@@ -2113,11 +2119,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __remove_pointer_helper<_Tp, _Up*>
 { using type = _Up; };
 
-  /// remove_pointer
   template
 struct remove_pointer
 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
 { };
+#endif
 
   template
 struct __add_pointer_helper
-- 
2.42.0



[PATCH v19 36/40] libstdc++: Optimize is_unsigned trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unsigned trait by dispatching
to the new __is_unsigned built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unsigned): Use __is_unsigned built-in
trait.
(is_unsigned_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 48d630a1478..f7d3815f332 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1001,10 +1001,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_unsigned
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__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
@@ -3440,8 +3447,14 @@ template 
 
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+template 
+  inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+#else
 template 
   inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+#endif
 
 template 
   inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
-- 
2.42.0



[PATCH v19 38/40] libstdc++: Optimize is_signed trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_signed trait by dispatching to
the new __is_signed built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_signed): Use __is_signed built-in trait.
(is_signed_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index f7d3815f332..7e93923f44b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -982,6 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __bool_constant<__is_abstract(_Tp)>
 { };
 
+  /// is_signed
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+  template
+struct is_signed
+: public __bool_constant<__is_signed(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template::value>
@@ -994,11 +1001,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
   /// @endcond
 
-  /// is_signed
   template
 struct is_signed
 : public __is_signed_helper<_Tp>::type
 { };
+#endif
 
   /// is_unsigned
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
@@ -3445,8 +3452,13 @@ template 
 template 
   inline constexpr bool is_final_v = __is_final(_Tp);
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+template 
+  inline constexpr bool is_signed_v = __is_signed(_Tp);
+#else
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
 template 
-- 
2.42.0



[PATCH v19 39/40] c++: Implement __is_scalar built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_scalar.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scalar.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCALAR.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_scalar.
* g++.dg/ext/is_scalar.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 186 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_scalar.C |  31 
 7 files changed, 137 insertions(+), 92 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scalar.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b161c9b2c9e..78f100d2745 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCALAR:
+  inform (loc, "  %qT is not a scalar type", t1);
+  break;
 case CPTK_IS_SIGNED:
   inform (loc, "  %qT is not a signed type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b0faa4c8937..08a2780c929 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCALAR, "__is_scalar", 1)
 DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index de0ba162e7a..ef51c713c58 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -66,6 +66,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false
 "__is_reference", CPTK_IS_REFERENCE, 1, false
 "__is_same", CPTK_IS_SAME, 2, false
+"__is_scalar", CPTK_IS_SCALAR, 1, false
 "__is_signed", CPTK_IS_SIGNED, 1, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, 1, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 6d1078de2fe..8c68af420f9 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -78,10 +78,10 @@ cp_trait_lookup::hash (const char *str, size_t len)
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-  126, 126, 126, 126, 126,  20, 126,  40,  45,  50,
-   55,   0,   5,  15, 126,   0, 126, 126,  35,  10,
-   35,   0,  10, 126,  30,   5,   5,  16,  30, 126,
-  126,  10, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126,  40, 126,  25,  21,  50,
+0,   0,  30,  10, 126,   0, 126, 126,  25,   5,
+   50,   0,  61, 126,  10,  10,   5,   0,  15, 126,
+  126,   5, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 61,
+  TOTAL_KEYWORDS = 62,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,141 +125,143 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 89 "../../gcc/cp/cp-trait.gperf"
+#line 90 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 82 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 52 "../../gcc/cp/cp-trait.gperf"
+  {"__is_enum", CPTK_IS_ENUM, 1, false},
+#line 78 "../../gcc/cp/cp-trait.gperf"
+  {"__is_union", CPTK_IS_UNION, 1, false},
 #line 83 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 84 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
+#line 89 "../../gcc/cp/cp-trait.gperf"
+  {"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false},
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__remove_pointer", CPTK_REMOVE_POINTER, 1, true},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"

[PATCH v19 05/40] libstdc++: Optimize is_const trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_const trait by dispatching to
the new __is_const built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_const): Use __is_const built-in trait.
(is_const_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 677cd934b94..686e38e47c3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,6 +784,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Type properties.
 
   /// is_const
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+  template
+struct is_const
+: public __bool_constant<__is_const(_Tp)>
+{ };
+#else
   template
 struct is_const
 : public false_type { };
@@ -791,6 +797,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_const<_Tp const>
 : public true_type { };
+#endif
 
   /// is_volatile
   template
@@ -3218,10 +3225,17 @@ template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+template 
+  inline constexpr bool is_const_v = __is_const(_Tp);
+#else
 template 
   inline constexpr bool is_const_v = false;
 template 
   inline constexpr bool is_const_v = true;
+#endif
+
 template 
   inline constexpr bool is_volatile_v = false;
 template 
-- 
2.42.0



[PATCH v19 25/40] libstdc++: Optimize is_function trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_function trait by dispatching
to the new __is_function built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_function): Use __is_function built-in
trait.
(is_function_v): Likewise. Optimize its implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 36ad9814047..bd57488824b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -637,6 +637,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_function
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+  template
+struct is_function
+: public __bool_constant<__is_function(_Tp)>
+{ };
+#else
   template
 struct is_function
 : public __bool_constant::value> { };
@@ -648,6 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_function<_Tp&&>
 : public false_type { };
+#endif
 
 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
   /// is_null_pointer (LWG 2247).
@@ -3269,8 +3276,18 @@ template 
   inline constexpr bool is_union_v = __is_union(_Tp);
 template 
   inline constexpr bool is_class_v = __is_class(_Tp);
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
 template 
-  inline constexpr bool is_function_v = is_function<_Tp>::value;
+  inline constexpr bool is_function_v = __is_function(_Tp);
+#else
+template 
+  inline constexpr bool is_function_v = !is_const_v;
+template 
+  inline constexpr bool is_function_v<_Tp&> = false;
+template 
+  inline constexpr bool is_function_v<_Tp&&> = false;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
 template 
-- 
2.42.0



[PATCH v19 11/40] libstdc++: Optimize is_unbounded_array trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_unbounded_array trait by
dispatching to the new __is_unbounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unbounded_array_v): Use
__is_unbounded_array built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 4e8165e5af5..cb3d9e238fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3541,11 +3541,16 @@ template
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
+  template
+inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
+# else
   template
 inline constexpr bool is_unbounded_array_v = false;
 
   template
 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+# endif
 
   /// True for a type that is an array of known bound.
   /// @since C++20
-- 
2.42.0



[PATCH v19 21/40] libstdc++: Optimize is_member_object_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_object_pointer trait
by dispatching to the new __is_member_object_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_object_pointer): Use
__is_member_object_pointer built-in trait.
(is_member_object_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index e1b10240dc2..792213ebfe8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -574,6 +574,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_rvalue_reference<_Tp&&>
 : public true_type { };
 
+  /// is_member_object_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+  template
+struct is_member_object_pointer
+: public __bool_constant<__is_member_object_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_object_pointer_helper
 : public false_type { };
@@ -582,11 +589,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __is_member_object_pointer_helper<_Tp _Cp::*>
 : public __not_>::type { };
 
-  /// is_member_object_pointer
+
   template
 struct is_member_object_pointer
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
   /// is_member_function_pointer
@@ -3227,9 +3235,16 @@ template 
   inline constexpr bool is_rvalue_reference_v = false;
 template 
   inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+template 
+  inline constexpr bool is_member_object_pointer_v =
+__is_member_object_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
 template 
-- 
2.42.0



[PATCH v19 08/40] c++: Implement __is_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_array.
* g++.dg/ext/is_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 148 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_array.C  |  28 +
 7 files changed, 116 insertions(+), 72 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f031e022541..5e30a4a907a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARRAY:
+  inform (loc, "  %qT is not an array", t1);
+  break;
 case CPTK_IS_ASSIGNABLE:
   inform (loc, "  %qT is not assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index d786f47e60c..99bc05360b9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index ea7abda6c75..fb162cac164 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
 "__is_class", CPTK_IS_CLASS, 1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f462794d5db..526e63dec42 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
-  40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
-  96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
+   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
+   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+ 

[PATCH v19 07/40] libstdc++: Optimize is_volatile trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_volatile trait by dispatching
to the new __is_volatile built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_volatile): Use __is_volatile built-in
trait.
(is_volatile_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 686e38e47c3..c01f65df22b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -800,6 +800,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_volatile
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+  template
+struct is_volatile
+: public __bool_constant<__is_volatile(_Tp)>
+{ };
+#else
   template
 struct is_volatile
 : public false_type { };
@@ -807,6 +813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
@@ -3236,10 +3243,15 @@ template 
   inline constexpr bool is_const_v = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+template 
+  inline constexpr bool is_volatile_v = __is_volatile(_Tp);
+#else
 template 
   inline constexpr bool is_volatile_v = false;
 template 
   inline constexpr bool is_volatile_v = true;
+#endif
 
 template 
   inline constexpr bool is_trivial_v = __is_trivial(_Tp);
-- 
2.42.0



[PATCH v19 12/40] c++: Implement __is_bounded_array built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_bounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_bounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_BOUNDED_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_bounded_array.
* g++.dg/ext/is_bounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|  3 +
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/cp-trait.gperf   |  1 +
 gcc/cp/cp-trait.h   | 86 +++--
 gcc/cp/semantics.cc |  4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 +
 gcc/testsuite/g++.dg/ext/is_bounded_array.C | 38 +
 7 files changed, 94 insertions(+), 42 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_bounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 751ac61b25a..d09252a56b6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
+case CPTK_IS_BOUNDED_ARRAY:
+  inform (loc, "  %qT is not a bounded array", t1);
+  break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 4e02f68e4a9..6d6dff7a4c3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
+DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
 DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
 DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index a894fc8c74c..90fcdc01de6 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -42,6 +42,7 @@ struct cp_trait {
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
+"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false
 "__is_class", CPTK_IS_CLASS, 1, false
 "__is_const", CPTK_IS_CONST, 1, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 47060ffbbef..f22a6e93618 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
   116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 49,
+  TOTAL_KEYWORDS = 50,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -125,54 +125,56 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, 1, true},
-#line 50 "../../gcc/cp/cp-trait.gperf"
+#line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
 #line 72 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
-#line 49 "../../gcc/cp/cp-trait.gperf"
+#line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 62 "../../gcc/cp/cp-trait.gperf"
+#line 63 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE,

[PATCH v19 23/40] libstdc++: Optimize is_reference trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_reference trait by dispatching
to the new __is_reference built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in
trait.
(is_reference_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 792213ebfe8..36ad9814047 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -682,6 +682,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Composite type categories.
 
   /// is_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_reference
+: public __bool_constant<__is_reference(_Tp)>
+{ };
+#else
   template
 struct is_reference
 : public false_type
@@ -696,6 +702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_reference<_Tp&&>
 : public true_type
 { };
+#endif
 
   /// is_arithmetic
   template
@@ -3264,12 +3271,19 @@ template 
   inline constexpr bool is_class_v = __is_class(_Tp);
 template 
   inline constexpr bool is_function_v = is_function<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_reference_v = __is_reference(_Tp);
+#else
 template 
   inline constexpr bool is_reference_v = false;
 template 
   inline constexpr bool is_reference_v<_Tp&> = true;
 template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
+#endif
+
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v19 17/40] libstdc++: Optimize is_member_pointer trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_member_pointer trait
by dispatching to the new __is_member_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_pointer): Use __is_member_pointer
built-in trait.
(is_member_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7fd29d8d9f2..d7f89cf7c06 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -716,6 +716,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_compound
 : public __not_>::type { };
 
+  /// is_member_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+  template
+struct is_member_pointer
+: public __bool_constant<__is_member_pointer(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template
 struct __is_member_pointer_helper
@@ -726,11 +733,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
   /// @endcond
 
-  /// is_member_pointer
   template
 struct is_member_pointer
 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   template
 struct is_same;
@@ -3242,8 +3249,14 @@ template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+template 
+  inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
 template 
-- 
2.42.0



[PATCH v19 31/40] c++: Implement __is_arithmetic built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_arithmetic.
* g++.dg/ext/is_arithmetic.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 184 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_arithmetic.C |  33 
 7 files changed, 138 insertions(+), 91 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9d627fa782..3a7f968eae8 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
 case CPTK_IS_ARRAY:
   inform (loc, "  %qT is not an array", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index c60724e869e..b2be7b7bbd7 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 5d40e04f91c..9050c36f105 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -39,6 +39,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false
 "__is_abstract", CPTK_IS_ABSTRACT, 1, false
 "__is_aggregate", CPTK_IS_AGGREGATE, 1, false
+"__is_arithmetic", CPTK_IS_ARITHMETIC, 1, false
 "__is_array", CPTK_IS_ARRAY, 1, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
 "__is_base_of", CPTK_IS_BASE_OF, 2, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index ab783b161c7..31fd5075f2d 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 97, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99, 40, 45, 40,
-   5,  0, 55, 10, 99,  0, 99, 99, 10, 25,
-  30,  0, 10, 99, 10, 15,  5,  0, 20, 99,
-  99, 10, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
+5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
+   35,   0,

[PATCH v19 18/40] c++: Implement __is_member_function_pointer built-in trait

2023-10-13 Thread Ken Matsui
This patch implements built-in trait for std::is_member_function_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_function_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_FUNCTION_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of
__is_member_function_pointer.
* g++.dg/ext/is_member_function_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |   3 +
 gcc/cp/cp-trait.def   |   1 +
 gcc/cp/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 176 +-
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 .../g++.dg/ext/is_member_function_pointer.C   |  31 +++
 7 files changed, 131 insertions(+), 88 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_function_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f0d3f89464c..d0464dd4f6a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
+  inform (loc, "  %qT is not a member function pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 26087da3bdf..897b96630f2 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
 DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 3775b11283d..b28efbab322 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -52,6 +52,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, 1, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false
+"__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, 1, false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, 1, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index dfd60cec6e6..d3d4bdf9799 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -54,7 +54,7 @@ struct cp_trait {
   short arity;
   bool type;
 };
-/* maximum key range = 111, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -69,32 +69,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118,  20, 118,   0,  55,  50,
-   40,   0,  40,  20, 118,   0, 118, 118,   5,   5,
-   30,   0,   5, 118,  10,  50,   5,   0,   5, 118,
-  118,   5, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,

[PATCH v19 26/40] libstdc++: Optimize is_object trait performance

2023-10-13 Thread Ken Matsui
This patch optimizes the performance of the is_object trait by dispatching to
the new __is_function and __is_reference built-in traits.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use __is_function and
__is_reference built-in traits.
(is_object_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index bd57488824b..674d398c075 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_object
+: public __bool_constant::value)>
+{ };
+#else
   template
 struct is_object
 : public __not_<__or_, is_reference<_Tp>,
   is_void<_Tp>>>::type
 { };
+#endif
 
   template
 struct is_member_pointer;
@@ -3305,8 +3314,17 @@ template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_object_v
+= !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
+#else
 template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-- 
2.42.0



  1   2   >