Re: [PATCH] PHIOPT: Value-replacement check undef

2024-04-30 Thread Richard Biener
On Mon, Apr 29, 2024 at 8:52 AM Andrew Pinski  wrote:
>
> While moving value replacement part of PHIOPT over
> to use match-and-simplify, I ran into the case where
> we would have an undef use that was conditional become
> unconditional. This prevents that. I can't remember at this
> point what the testcase was though.
>
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.

OK.

Thanks,
Richard.

> gcc/ChangeLog:
>
> * tree-ssa-phiopt.cc (value_replacement): Reject undef variables
> so they don't become unconditional used.
>
> Signed-off-by: Andrew Pinski 
> ---
>  gcc/tree-ssa-phiopt.cc | 7 +++
>  1 file changed, 7 insertions(+)
>
> diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
> index a2bdcb5eae8..f166c3132cb 100644
> --- a/gcc/tree-ssa-phiopt.cc
> +++ b/gcc/tree-ssa-phiopt.cc
> @@ -1146,6 +1146,13 @@ value_replacement (basic_block cond_bb, basic_block 
> middle_bb,
>if (code != NE_EXPR && code != EQ_EXPR)
>  return 0;
>
> +  /* Do not make conditional undefs unconditional.  */
> +  if ((TREE_CODE (arg0) == SSA_NAME
> +   && ssa_name_maybe_undef_p (arg0))
> +  || (TREE_CODE (arg1) == SSA_NAME
> + && ssa_name_maybe_undef_p (arg1)))
> +return false;
> +
>/* If the type says honor signed zeros we cannot do this
>   optimization.  */
>if (HONOR_SIGNED_ZEROS (arg1))
> --
> 2.43.0
>


[PATCH v3] DSE: Fix ICE after allow vector type in get_stored_val

2024-04-30 Thread pan2 . li
From: Pan Li 

We allowed vector type for get_stored_val when read is less than or
equal to store in previous.  Unfortunately,  the valididate_subreg
treats the vector type's size is less than vector register as
invalid.  Then we will have ICE here.

This patch would like to fix it by filter-out the invalid type size,
and make sure the subreg is valid for both the read_mode and store_mode
before perform the real gen_lowpart.

The below test suites are passed for this patch:

* The x86 bootstrap test.
* The x86 regression test.
* The riscv rv64gcv regression test.
* The riscv rv64gc regression test.
* The aarch64 regression test.

gcc/ChangeLog:

* dse.cc (get_stored_val): Make sure read_mode size is greater
than or equal to the vector register size before gen_lowpart.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr111720-10.c: Adjust asm checker.
* gcc.target/riscv/rvv/base/bug-6.c: New test.

Signed-off-by: Pan Li 
---
 gcc/dse.cc|  4 +++-
 .../gcc.target/riscv/rvv/base/bug-6.c | 22 +++
 .../gcc.target/riscv/rvv/base/pr111720-10.c   |  2 +-
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c

diff --git a/gcc/dse.cc b/gcc/dse.cc
index edc7a1dfecf..258d2ccc299 100644
--- a/gcc/dse.cc
+++ b/gcc/dse.cc
@@ -1946,7 +1946,9 @@ get_stored_val (store_info *store_info, machine_mode 
read_mode,
 copy_rtx (store_info->const_rhs));
   else if (VECTOR_MODE_P (read_mode) && VECTOR_MODE_P (store_mode)
 && known_le (GET_MODE_BITSIZE (read_mode), GET_MODE_BITSIZE (store_mode))
-&& targetm.modes_tieable_p (read_mode, store_mode))
+&& targetm.modes_tieable_p (read_mode, store_mode)
+/* It's invalid in validate_subreg if read_mode size is < reg natural.  */
+&& known_ge (GET_MODE_SIZE (read_mode), REGMODE_NATURAL_SIZE (read_mode)))
 read_reg = gen_lowpart (read_mode, copy_rtx (store_info->rhs));
   else
 read_reg = extract_low_bits (read_mode, store_mode,
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c
new file mode 100644
index 000..5bb00b8f587
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c
@@ -0,0 +1,22 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize" } */
+
+struct A { float x, y; };
+struct B { struct A u; };
+
+extern void bar (struct A *);
+
+float
+f3 (struct B *x, int y)
+{
+  struct A p = {1.0f, 2.0f};
+  struct A *q = &x[y].u;
+
+  __builtin_memcpy (&q->x, &p.x, sizeof (float));
+  __builtin_memcpy (&q->y, &p.y, sizeof (float));
+
+  bar (&p);
+
+  return x[y].u.x + x[y].u.y;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
index 215eb99ce0f..ee6b2ccf7ad 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
@@ -15,4 +15,4 @@ vbool4_t test () {
 }
 
 /* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } 
} */
-/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } 
} */
+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} 
1 }  } */
-- 
2.34.1



[PATCH-1, rs6000] Add a new type of CC mode - CCBCD for bcd insns [PR100736, PR114732]

2024-04-30 Thread HAO CHEN GUI
Hi,
  It's the first patch of a series of patches optimizing CC modes on
rs6000.

  bcd insns set all four bits of a CR field. But it has different single
bit reverse behavior than CCFP's. The forth bit of bcd cr fields is used
to indict overflow or invalid number. It's not a bit for unordered test.
So the "le" test should be reversed to "gt" not "ungt". The "ge" test
should be reversed to "lt" not "unlt". That's the root cause of PR100736
and PR114732.

  This patch fixes the issue by adding a new type of CC mode - CCBCD for
all bcd insns. Here a new setcc_rev pattern is added for ccbcd. It will
be merged to a uniform pattern which is for all CC modes in sequential
patch.

  The rtl code "unordered" is still used for testing overflow or
invalid number. IMHO, the "unordered" on a CC mode can be considered as
testing the forth bit of a CR field setting or not. The "eq" on a CC mode
can be considered as testing the third bit setting or not. Thus we avoid
creating lots of unspecs for the CR bit testing.

  Bootstrapped and tested on powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?

Thanks
Gui Haochen


ChangeLog
rs6000: Add a new type of CC mode - CCBCD for bcd insns

gcc/
PR target/100736
PR target/114732
* config/rs6000/altivec.md (bcd_): Replace CCFP
with CCBCD.
(*bcd_test_): Likewise.
(*bcd_test2_): Likewise.
(bcd__): Likewise.
(*bcdinvalid_): Likewise.
(bcdinvalid_): Likewise.
(bcdshift_v16qi): Likewise.
(bcdmul10_v16qi): Likewise.
(bcddiv10_v16qi): Likewise.
(peephole for bcd_add/sub): Likewise.
* config/rs6000/predicates.md (branch_comparison_operator): Add CCBCD
and its supported comparison codes.
* config/rs6000/rs6000-modes.def (CC_MODE): Add CCBCD.
* config/rs6000/rs6000.cc (validate_condition_mode): Add CCBCD
assertion.
* config/rs6000/rs6000.md (CC_any): Add CCBCD.
(ccbcd_rev): New code iterator.
(*_cc): New insn and split pattern for CCBCD reverse
compare.

gcc/testsuite/
PR target/100736
PR target/114732
* gcc.target/powerpc/pr100736.c: New.
* gcc.target/powerpc/pr114732.c: New.

patch.diff
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index bb20441c096..9fa8cf89f61 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -4443,7 +4443,7 @@ (define_insn "bcd_"
  (match_operand:VBCD 2 "register_operand" "v")
  (match_operand:QI 3 "const_0_to_1_operand" "n")]
 UNSPEC_BCD_ADD_SUB))
-   (clobber (reg:CCFP CR6_REGNO))]
+   (clobber (reg:CCBCD CR6_REGNO))]
   "TARGET_P8_VECTOR"
   "bcd. %0,%1,%2,%3"
   [(set_attr "type" "vecsimple")])
@@ -4454,8 +4454,8 @@ (define_insn "bcd_"
 ;; probably should be one that can go in the VMX (Altivec) registers, so we
 ;; can't use DDmode or DFmode.
 (define_insn "*bcd_test_"
-  [(set (reg:CCFP CR6_REGNO)
-   (compare:CCFP
+  [(set (reg:CCBCD CR6_REGNO)
+   (compare:CCBCD
 (unspec:V2DF [(match_operand:VBCD 1 "register_operand" "v")
   (match_operand:VBCD 2 "register_operand" "v")
   (match_operand:QI 3 "const_0_to_1_operand" "i")]
@@ -4472,8 +4472,8 @@ (define_insn "*bcd_test2_"
  (match_operand:VBCD 2 "register_operand" "v")
  (match_operand:QI 3 "const_0_to_1_operand" "i")]
 UNSPEC_BCD_ADD_SUB))
-   (set (reg:CCFP CR6_REGNO)
-   (compare:CCFP
+   (set (reg:CCBCD CR6_REGNO)
+   (compare:CCBCD
 (unspec:V2DF [(match_dup 1)
   (match_dup 2)
   (match_dup 3)]
@@ -4566,8 +4566,8 @@ (define_insn "vclrrb"
[(set_attr "type" "vecsimple")])

 (define_expand "bcd__"
-  [(parallel [(set (reg:CCFP CR6_REGNO)
-  (compare:CCFP
+  [(parallel [(set (reg:CCBCD CR6_REGNO)
+  (compare:CCBCD
(unspec:V2DF [(match_operand:VBCD 1 "register_operand")
  (match_operand:VBCD 2 "register_operand")
  (match_operand:QI 3 "const_0_to_1_operand")]
@@ -4575,7 +4575,7 @@ (define_expand "bcd__"
(match_dup 4)))
  (clobber (match_scratch:VBCD 5))])
(set (match_operand:SI 0 "register_operand")
-   (BCD_TEST:SI (reg:CCFP CR6_REGNO)
+   (BCD_TEST:SI (reg:CCBCD CR6_REGNO)
 (const_int 0)))]
   "TARGET_P8_VECTOR"
 {
@@ -4583,8 +4583,8 @@ (define_expand "bcd__"
 })

 (define_insn "*bcdinvalid_"
-  [(set (reg:CCFP CR6_REGNO)
-   (compare:CCFP
+  [(set (reg:CCBCD CR6_REGNO)
+   (compare:CCBCD
 (unspec:V2DF [(match_operand:VBCD 1 "register_operand" "v")]
  UNSPEC_BCDSUB)
 (match_operand:V2DF 2 "zero_constant" "j")))
@@ -4594,14 +4594,14 @@ (define_insn "*bcdinvalid_"
   [(set_attr "type"

[PATCH-2, rs6000] Add a new type of CC mode - CCLTEQ

2024-04-30 Thread HAO CHEN GUI
Hi,
  It's the second patch of a series of patches optimizing CC modes on
rs6000.

  This patch adds a new type of CC mode - CCLTEQ used for the case which
only set CR bit 0 and 2. The bit 1 and 3 are not used. The vector compare
and test data class instructions are the cases.

  Bootstrapped and tested on powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?

Thanks
Gui Haochen

ChangeLog
rs6000: Add a new type of CC mode - CCLTEQ

The new mode is used for the case which only checks cr bit 0 and 2.

gcc/
* config/rs6000/altivec.md (altivec_vcmpequ_p): Replace
CCFP with CCLTEQ.
(altivec_vcmpequt_p): Likewise.
(*altivec_vcmpgts_p): Likewise.
(*altivec_vcmpgtst_p): Likewise.
(*altivec_vcmpgtu_p): Likewise.
(*altivec_vcmpgtut_p): Likewise.
(*altivec_vcmpeqfp_p): Likewise.
(*altivec_vcmpgtfp_p): Likewise.
(*altivec_vcmpgefp_p): Likewise.
(altivec_vcmpbfp_p): Likewise.
* config/rs6000/predicates.md (branch_comparison_operator): Add
CCLTEQ and its supported comparison codes.
* config/rs6000/rs6000-modes.def (CC_MODE): Add CCLTEQ.
* config/rs6000/rs6000.cc (validate_condition_mode): Add assertion
for CCLTEQ.
* config/rs6000/rs6000.md (CC_any): Add CCLTEQ.
* config/rs6000/vector.md (vector_eq__p): Replace CCFP with
CCLTEQ.
(vector_eq_v1ti_p): Likewise.
(vector_ne__p): Likewise.
(vector_ae__p): Likewise.
(vector_nez__p): Likewise.
(vector_ne_v2di_p): Likewise.
(vector_ne_v1ti_p): Likewise.
(vector_ae_v2di_p): Likewise.
(vector_ae_v1ti_p): Likewise.
(vector_ne__p): Likewise.
(vector_ae__p): Likewise.
(vector_gt__p): Likewise.
(vector_gt_v1ti_p): Likewise.
(vector_ge__p): Likewise.
(vector_gtu__p): Likewise.
(cr6_test_for_zero): Likewise.
(cr6_test_for_zero_reverse): Likewise.
(cr6_test_for_lt): Likewise.
(cr6_test_for_lt_reverse): Likewise.
* config/rs6000/vsx.md (*vsx_eq__p): Likewise.
(*vsx_gt__p): Likewise.
(*vsx_ge__p): Likewise.
(xststdcqp_): Likewise.
(xststdcp): Likewise.
(xststdcnegqp_): Likewise.
(xststdcnegp): Likewise.
(*xststdcqp_): Likewise.
(*xststdcp): Likewise.
(*vsx_ne__p): Likewise.
(*vector_nez__p): Likewise.
(vcmpnezb_p): Likewise.

patch.diff
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 9fa8cf89f61..bd79a3f9e84 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -2650,10 +2650,10 @@ (define_expand "cbranchv16qi4"
 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
 ;; indicate a combined status
 (define_insn "altivec_vcmpequ_p"
-  [(set (reg:CC CR6_REGNO)
-   (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
-  (match_operand:VI2 2 "register_operand" "v"))]
-  UNSPEC_PREDICATE))
+  [(set (reg:CCLTEQ CR6_REGNO)
+   (unspec:CCLTEQ [(eq:CC (match_operand:VI2 1 "register_operand" "v")
+  (match_operand:VI2 2 "register_operand" "v"))]
+  UNSPEC_PREDICATE))
(set (match_operand:VI2 0 "register_operand" "=v")
(eq:VI2 (match_dup 1)
(match_dup 2)))]
@@ -2662,10 +2662,11 @@ (define_insn "altivec_vcmpequ_p"
   [(set_attr "type" "veccmpfx")])

 (define_insn "altivec_vcmpequt_p"
-  [(set (reg:CC CR6_REGNO)
-   (unspec:CC [(eq:CC (match_operand:V1TI 1 "altivec_register_operand" "v")
-  (match_operand:V1TI 2 "altivec_register_operand" 
"v"))]
-  UNSPEC_PREDICATE))
+  [(set (reg:CCLTEQ CR6_REGNO)
+   (unspec:CCLTEQ
+ [(eq:CC (match_operand:V1TI 1 "altivec_register_operand" "v")
+ (match_operand:V1TI 2 "altivec_register_operand" "v"))]
+ UNSPEC_PREDICATE))
(set (match_operand:V1TI 0 "altivec_register_operand" "=v")
(eq:V1TI (match_dup 1)
 (match_dup 2)))]
@@ -2686,10 +2687,10 @@ (define_expand "altivec_vcmpne_"
   })

 (define_insn "*altivec_vcmpgts_p"
-  [(set (reg:CC CR6_REGNO)
-   (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
-  (match_operand:VI2 2 "register_operand" "v"))]
-  UNSPEC_PREDICATE))
+  [(set (reg:CCLTEQ CR6_REGNO)
+   (unspec:CCLTEQ [(gt:CC (match_operand:VI2 1 "register_operand" "v")
+  (match_operand:VI2 2 "register_operand" "v"))]
+  UNSPEC_PREDICATE))
(set (match_operand:VI2 0 "register_operand" "=v")
(gt:VI2 (match_dup 1)
(match_dup 2)))]
@@ -2698,10 +2699,10 @@ (define_insn "*altivec_vcmpgts_p"
   [(set_attr "type" "veccmpfx")])

 (define_insn "*altivec_vcmpgtst_p"
-  [(set (reg:CC CR6_REGNO)
-   (unspec:CC [(gt:CC (ma

[PATCH-3, rs6000] Set CC mode of vector string isolate insns to CCEQ

2024-04-30 Thread HAO CHEN GUI
Hi,
  It's the third patch of a series of patches optimizing CC modes on
rs6000.

  This patch sets CC mode of vector string isolate insns to CCEQ instead
of CCFP as these insns only set/check CR bit 2.

  Bootstrapped and tested on powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?

Thanks
Gui Haochen

ChangeLog
rs6000: Set CC mode of vector string isolate insns to CCEQ

gcc/
* config/rs6000/altivec.md (vstrir_p_direct_): Replace CCFP
with CCEQ.
(vstril_p_direct_): Likewise.

patch.diff
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index bd79a3f9e84..a883a814a82 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -932,9 +932,9 @@ (define_insn "vstrir_p_direct_"
(unspec:VIshort
   [(match_operand:VIshort 1 "altivec_register_operand" "v")]
   UNSPEC_VSTRIR))
-   (set (reg:CC CR6_REGNO)
-   (unspec:CC [(match_dup 1)]
-  UNSPEC_VSTRIR))]
+   (set (reg:CCEQ CR6_REGNO)
+   (unspec:CCEQ [(match_dup 1)]
+UNSPEC_VSTRIR))]
   "TARGET_POWER10"
   "vstrir. %0,%1"
   [(set_attr "type" "vecsimple")])
@@ -984,9 +984,9 @@ (define_insn "vstril_p_direct_"
(unspec:VIshort
   [(match_operand:VIshort 1 "altivec_register_operand" "v")]
   UNSPEC_VSTRIL))
-   (set (reg:CC CR6_REGNO)
-   (unspec:CC [(match_dup 1)]
-  UNSPEC_VSTRIR))]
+   (set (reg:CCEQ CR6_REGNO)
+   (unspec:CCEQ [(match_dup 1)]
+UNSPEC_VSTRIR))]
   "TARGET_POWER10"
   "vstril. %0,%1"
   [(set_attr "type" "vecsimple")])



[PATCH-4, rs6000] Optimize single cc bit reverse implementation

2024-04-30 Thread HAO CHEN GUI
Hi,
  It's the forth patch of a series of patches optimizing CC modes on
rs6000.

  The single CC bit reverse can be implemented by setbcr on Power10 or
isel on Power9 or mfcr on Power8 and below. Originally CCFP is not
supported for isel and setbcr as bcd insns use CCFP and its bit reverse
is not the same as normal CCFP mode. Previous patches add new CC modes
according to the usage of CC bits. So now single CC bit reverse can be
supported on all CC modes with a uniform pattern.

  This patch removes unordered and ordered from codes list of CCFP with
finite_math_only set. These two are no needed as bcd insns use a separate
CC mode now. reverse_condition is replaced with rs6000_reverse_condition
as all CC modes can be reversed. A new isel version single CC bit reverse
pattern is added. fp and bcd CC reverse pattern are removed and a uniform
single CC bit reverse pattern is added, which is mfcr version.

  The new test cases illustrate the different implementation of single cc
bit reverse test.

  Bootstrapped and tested on powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?

Thanks
Gui Haochen

ChangeLog
rs6000: Optimize single cc bit reverse implementation

This patch implements single cc bit reverse by mfcr (on Power8 and below)
or isel (on Power9) or setbcr (on Power10) with all CC modes.

gcc/
* config/rs6000/predicates.md (branch_comparison_operator): Remove
unordered and ordered from CCFP with finite_math_only.
(scc_comparison_operator): Add unle and unge.
* config/rs6000/rs6000.md (CCANY): Add CCFP, CCBCD, CCLTEQ and CCEQ.
(*isel_reversed__): Replace reverse_condition
with rs6000_reverse_condition.
(*set_rev): New insn_and_split pattern for
single cc bit reverse P9 version.
(fp_rev, ccbcd_rev): Remove.
(*_cc): Remove the pattern for CCFP and CCBCD.  Merge
them to...
(*set_rev): ...this, the new insn_and_split
pattern for single cc bit reverse P8 and below version.

gcc/testsuite/
* gcc.target/powerpc/cc_rev.h: New.
* gcc.target/powerpc/cc_rev_1.c: New.
* gcc.target/powerpc/cc_rev_2.c: New.
* gcc.target/powerpc/cc_rev_3.c: New.

patch.diff
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 322e7639fd4..ddb46799bff 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1348,7 +1348,7 @@ (define_predicate "branch_comparison_operator"
(match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC")
(if_then_else (match_test "GET_MODE (XEXP (op, 0)) == CCFPmode")
  (if_then_else (match_test "flag_finite_math_only")
-   (match_code "lt,le,gt,ge,eq,ne,unordered,ordered")
+   (match_code "lt,le,gt,ge,eq,ne")
(match_code "lt,gt,eq,unordered,unge,unle,ne,ordered"))
  (if_then_else (match_test "GET_MODE (XEXP (op, 0)) == CCBCDmode")
(match_code "lt,le,gt,ge,eq,ne,unordered,ordered")
@@ -1397,7 +1397,7 @@ (define_predicate "scc_comparison_operator"
 ;; an SCC insn.
 (define_predicate "scc_rev_comparison_operator"
   (and (match_operand 0 "branch_comparison_operator")
-   (match_code "ne,le,ge,leu,geu,ordered")))
+   (match_code "ne,le,ge,leu,geu,ordered,unle,unge")))

 ;; Return 1 if OP is a comparison operator suitable for floating point
 ;; vector/scalar comparisons that generate a -1/0 mask.
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 2c6255395d1..ccf392b6409 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5509,7 +5509,7 @@ (define_expand "movcc"
 ;; leave out the mode in operand 4 and use one pattern, but reload can
 ;; change the mode underneath our feet and then gets confused trying
 ;; to reload the value.
-(define_mode_iterator CCANY [CC CCUNS])
+(define_mode_iterator CCANY [CC CCUNS CCFP CCBCD CCLTEQ CCEQ])
 (define_insn "isel__"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(if_then_else:GPR
@@ -5536,7 +5536,8 @@ (define_insn "*isel_reversed__"
 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
   "TARGET_ISEL"
 {
-  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+  PUT_CODE (operands[1], rs6000_reverse_condition (mode,
+  GET_CODE (operands[1])));
   return "isel %0,%3,%2,%j1";
 }
   [(set_attr "type" "isel")])
@@ -12764,6 +12765,27 @@ (define_insn "set_cc"
(const_string "mfcr")))
(set_attr "length" "8")])

+(define_insn_and_split "*set_rev"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+   (match_operator:GPR 1 "scc_rev_comparison_operator"
+   [(match_operand:CCANY 2 "cc_reg_operand" "y")
+(const_int 0)]))]
+  "TARGET_ISEL
+   && !TARGET_POWER10"
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+   (const_int 1))
+   (set (match_dup 0)
+   (if_then_else:GPR
+ (match_dup

[PATCH] gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) 0 argument [PR114876]

2024-04-30 Thread Jakub Jelinek
Hi!

Seems when Martin S. implemented this, he coded there strict reading
of the standard, which said that %lc with (wint_t) 0 argument is handled
as wchar_t[2] temp = { arg, 0 }; %ls with temp arg and so shouldn't print
any values.  But, most of the libc implementations actually handled that
case like %c with '\0' argument, adding a single NUL character, the only
known exception is musl.
Recently, C23 changed this in response to GB-141 and POSIX in
https://austingroupbugs.net/view.php?id=1647
so that it should have the same behavior as %c with '\0'.

Because there is implementation divergence, the following patch uses
a range rather than hardcoding it to all 1s (i.e. the %c behavior),
though the likely case is still 1 (forward looking plus most of
implementations).
The res.knownrange = true; assignment removed is redundant due to
the same assignment done unconditionally before the if statement,
rest is formatting fixes.

I don't think the min >= 0 && min < 128 case is right either, I'd think
it should be min >= 0 && max < 128, otherwise it is just some possible
inputs are (maybe) ASCII and there can be others, but this code is a total
mess anyway, with the min, max, likely (somewhere in [min, max]?) and then
unlikely possibly larger than max, dunno, perhaps for at least some chars
in the ASCII range the likely case could be for the ascii case; so perhaps
just the one_2_one_ascii shouldn't set max to 1 and mayfail should be true
for max >= 128.  Anyway, didn't feel I should touch that right now.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Shall it go to 14.1, or wait for 14.2?

2024-04-30  Jakub Jelinek  

PR tree-optimization/114876
* gimple-ssa-sprintf.cc (format_character): For min == 0 && max == 0,
set max, likely and unlikely members to 1 rather than 0.  Remove
useless res.knownrange = true;.  Formatting fixes.

* gcc.dg/pr114876.c: New test.
* gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected
diagnostics.

--- gcc/gimple-ssa-sprintf.cc.jj2024-01-03 11:51:22.225860346 +0100
+++ gcc/gimple-ssa-sprintf.cc   2024-04-29 12:52:59.760668894 +0200
@@ -2177,8 +2177,7 @@ format_character (const directive &dir,
 
   res.knownrange = true;
 
-  if (dir.specifier == 'C'
-  || dir.modifier == FMT_LEN_l)
+  if (dir.specifier == 'C' || dir.modifier == FMT_LEN_l)
 {
   /* A wide character can result in as few as zero bytes.  */
   res.range.min = 0;
@@ -2189,10 +2188,13 @@ format_character (const directive &dir,
{
  if (min == 0 && max == 0)
{
- /* The NUL wide character results in no bytes.  */
- res.range.max = 0;
- res.range.likely = 0;
- res.range.unlikely = 0;
+ /* In strict reading of older ISO C or POSIX, this required
+no characters to be emitted.  ISO C23 changes that, so
+does POSIX, to match what has been implemented in most of the
+implementations, namely emitting a single NUL character.
+Let's use 0 for minimum and 1 for all the other values.  */
+ res.range.max = 1;
+ res.range.likely = res.range.unlikely = 1;
}
  else if (min >= 0 && min < 128)
{
@@ -2200,11 +2202,12 @@ format_character (const directive &dir,
 is not a 1-to-1 mapping to the source character set or
 if the source set is not ASCII.  */
  bool one_2_one_ascii
-   = (target_to_host_charmap[0] == 1 && target_to_host ('a') == 
97);
+   = (target_to_host_charmap[0] == 1
+  && target_to_host ('a') == 97);
 
  /* A wide character in the ASCII range most likely results
 in a single byte, and only unlikely in up to MB_LEN_MAX.  */
- res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();;
+ res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();
  res.range.likely = 1;
  res.range.unlikely = target_mb_len_max ();
  res.mayfail = !one_2_one_ascii;
@@ -2235,7 +2238,6 @@ format_character (const directive &dir,
   /* A plain '%c' directive.  Its output is exactly 1.  */
   res.range.min = res.range.max = 1;
   res.range.likely = res.range.unlikely = 1;
-  res.knownrange = true;
 }
 
   /* Bump up the byte counters if WIDTH is greater.  */
--- gcc/testsuite/gcc.dg/pr114876.c.jj  2024-04-29 12:26:45.774965158 +0200
+++ gcc/testsuite/gcc.dg/pr114876.c 2024-04-29 12:51:37.863777055 +0200
@@ -0,0 +1,34 @@
+/* PR tree-optimization/114876 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "return \[01\];" "optimized" } } */
+/* { dg-final { scan-tree-dump "return 3;" "optimized" } } */
+/* { dg-final { scan-tree-dump "return 4;" "optimized" } } */
+
+int
+foo (void)
+{
+  char bu

[PATCH] testsuite: gm2: Remove timeout overrides [PR114886]

2024-04-30 Thread Rainer Orth
A large number of gm2 tests are timing out even on current Solaris/SPARC
systems.  As detailed in the PR, the problem is that the gm2 testsuite
artificially lowers many timeouts way below the DejaGnu default of 300
seconds, often as short as 10 seconds.  The problem lies both in the
values (they may be appropriate for some targets, but too low for
others, especially under high load) and the fact that it uses absolute
values, overriding e.g. settings from a build-wide site.exp.

Therefore this patch removes all those overrides, restoring the
defaults.

Tested on sparc-sun-solaris2.11 (where all the previous timeouts are
gone) and i386-pc-solaris2.11.

Ok for trunk and the gcc-14 branch once GCC 14.1.0 has been released?

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


2024-04-29  Rainer Orth  

gcc/testsuite:
PR modula2/114886
* lib/gm2.exp: Don't load timeout-dg.exp.
Don't set gm2_previous_timeout.
Don't call dg-timeout.
(gm2_push_timeout, gm2_pop_timeout): Remove.
(gm2_init): Don't call dg-timeout.
* lib/gm2-torture.exp: Don't load timeout-dg.exp.
Don't set gm2_previous_timeout.
Don't call dg-timeout.
(gm2_push_timeout, gm2_pop_timeout): Remove.

* gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp: Don't
load timeout-dg.exp.
Don't call gm2_push_timeout, gm2_pop_timeout.
* gm2/examples/map/pass/examples-map-pass.exp: Don't call
gm2_push_timeout, gm2_pop_timeout.
* gm2/iso/run/pass/iso-run-pass.exp: Don't load timeout-dg.exp.
Don't call gm2_push_timeout, gm2_pop_timeout.
* gm2/pimlib/base/run/pass/pimlib-base-run-pass.exp: Don't load
timeout-dg.exp.
Don't call gm2_push_timeout, gm2_pop_timeout.
* gm2/projects/iso/run/pass/halma/projects-iso-run-pass-halma.exp:
Don't call gm2_push_timeout, gm2_pop_timeout.
* 
gm2/switches/whole-program/pass/run/switches-whole-program-pass-run.exp:
Don't load timeout-dg.exp.
Don't call gm2_push_timeout, gm2_pop_timeout.

# HG changeset patch
# Parent  7ce0689744625483e581866918724503e5630773
testsuite: gm2: Remove timeout overrides [PR114886]

diff --git a/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp b/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp
--- a/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp
+++ b/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp
@@ -24,16 +24,11 @@ if $tracelevel then {
 
 # load support procs
 load_lib gm2-torture.exp
-load_lib timeout-dg.exp
 
 set gm2src ${srcdir}/../gm2
 
 gm2_init_cor ""
 
-# We should be able to compile, link or run in 20 seconds.
-gm2_push_timeout 20
-
-
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
 # If we're only testing specific files and this isn't one of them, skip it.
 if ![runtest_file_p $runtests $testcase] then {
@@ -42,5 +37,3 @@ foreach testcase [lsort [glob -nocomplai
 
 gm2-torture-execute $testcase "" "pass"
 }
-
-gm2_pop_timeout
diff --git a/gcc/testsuite/gm2/examples/map/pass/examples-map-pass.exp b/gcc/testsuite/gm2/examples/map/pass/examples-map-pass.exp
--- a/gcc/testsuite/gm2/examples/map/pass/examples-map-pass.exp
+++ b/gcc/testsuite/gm2/examples/map/pass/examples-map-pass.exp
@@ -27,9 +27,6 @@ load_lib gm2-torture.exp
 
 gm2_init_pim "${srcdir}/${subdir}"
 
-# We should be able to compile, link or run in 30 seconds.
-gm2_push_timeout 30
-
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
 # If we're only testing specific files and this isn't one of them, skip it.
 if ![runtest_file_p $runtests $testcase] then {
@@ -38,5 +35,3 @@ foreach testcase [lsort [glob -nocomplai
 
 gm2-torture $testcase
 }
-
-gm2_pop_timeout
diff --git a/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp b/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp
--- a/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp
+++ b/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp
@@ -23,14 +23,10 @@ if $tracelevel then {
 
 # load support procs
 load_lib gm2-torture.exp
-load_lib timeout-dg.exp
 
 gm2_init_iso "${srcdir}/gm2/iso/run/pass" -fsoft-check-all
 gm2_link_obj fileio.o
 
-# We should be able to compile, link or run in 60 seconds.
-gm2_push_timeout 60
-
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
 # If we're only testing specific files and this isn't one of them, skip it.
 if ![runtest_file_p $runtests $testcase] then {
@@ -42,5 +38,3 @@ foreach testcase [lsort [glob -nocomplai
 	gm2-torture-execute $testcase "" "pass"
 }
 }
-
-gm2_pop_timeout
diff --git a/gcc/testsuite/gm2/pimlib/base/run/pass/pimlib-base-run-pass.exp b/gcc/testsuite/gm2/pimlib/base/run/pass/pimlib-base-run-pass.exp
--- a/gcc/testsuite/gm2/pimlib/base/run/pass/pimlib-

Re: [PATCH] Don't assert for IFN_COND_{MIN, MAX} in vect_transform_reduction

2024-04-30 Thread Richard Biener
On Mon, Apr 29, 2024 at 5:30 PM H.J. Lu  wrote:
>
> On Mon, Apr 29, 2024 at 6:47 AM liuhongt  wrote:
> >
> > The Fortran standard does not specify what the result of the MAX
> > and MIN intrinsics are if one of the arguments is a NaN. So it
> > should be ok to tranform reduction for IFN_COND_MIN with vectorized
> > COND_MIN and REDUC_MIN.
>
> The commit subject isn't very clear.   This patch isn't about "Don't assert
> for IFN_COND_{MIN,MAX}".  It allows IFN_COND_{MIN,MAX} in
> vect_transform_reduction.

Well, we allow it elsewhere, we just fail to enumerate all COND_* we allow
here correctly.

> > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > Ok for trunk and backport to GCC14?

OK for trunk and branch.

Thanks,
Richard.

> >
> > gcc/ChangeLog:
> >
> > PR 114883
> > * tree-vect-loop.cc (vect_transform_reduction): Don't assert
> > for IFN_COND_{MIN, MAX}.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gfortran.dg/pr114883.f90: New test.
> > ---
> >  gcc/testsuite/gfortran.dg/pr114883.f90 | 191 +
> >  gcc/tree-vect-loop.cc  |   3 +-
> >  2 files changed, 193 insertions(+), 1 deletion(-)
> >  create mode 100644 gcc/testsuite/gfortran.dg/pr114883.f90
> >
> > diff --git a/gcc/testsuite/gfortran.dg/pr114883.f90 
> > b/gcc/testsuite/gfortran.dg/pr114883.f90
> > new file mode 100644
> > index 000..86b664a521e
> > --- /dev/null
> > +++ b/gcc/testsuite/gfortran.dg/pr114883.f90
> > @@ -0,0 +1,191 @@
> > +! { dg-do compile }
> > +! { dg-options "-O3" }
> > +! { dg-additional-options "-march=x86-64-v4" { target { x86_64-*-* 
> > i?86-*-* } } }
> > +
> > +module ndrop
> > +
> > +
> > +  implicit none
> > +
> > +  private
> > +  save
> > +
> > +  public dropmixnuc
> > +
> > +  real(8) :: npv(1011) ! number per volume concentration
> > +  real(8) :: alogsig(1011) ! natl log of geometric standard dev of aerosol
> > +
> > +  type qqcw_type
> > + real(8), pointer :: fldcw(:,:)
> > +  end type qqcw_type
> > +
> > +contains
> > +
> > +  subroutine dropmixnuc(lchnk, ncol, temp,  &
> > +   cldn,cldo, &
> > +   raer, dtmicro   &
> > +   )
> > +implicit none
> > +
> > +! input
> > +
> > +integer, intent(in) :: lchnk! chunk identifier
> > +integer, intent(in) :: ncol ! number of columns
> > +!  type(physics_state), intent(in) :: state  ! Physics state 
> > variables
> > +real(8), intent(in) :: dtmicro ! time step for 
> > microphysics (s)
> > +real(8), intent(in) :: temp(1,1011)! temperature (K)
> > +real(8), intent(in) :: cldo(1,1011)! cloud fraction on previous 
> > time step
> > +real(8), intent(in) :: cldn(1,1011)! cloud fraction
> > +real(8), intent(in) :: raer(1,1011,1011) ! aerosol mass, number mixing 
> > ratios
> > +
> > +
> > +type(qqcw_type) :: QQCW(1011)
> > +
> > +real(8) depvel(1,1011)! deposition velocity for droplets (m/s)
> > +real(8) wtke(1,1011) ! turbulent vertical velocity at base of 
> > layer k (m/s)
> > +real(8) wtke_cen(1,1011) ! turbulent vertical velocity at center of 
> > layer k (m/s)
> > +real(8) zn(1011) ! g/pdel (m2/g) for layer
> > +real(8) zs(1011) ! inverse of distance between levels (m)
> > +real(8), parameter :: zkmin=0.01_8,zkmax=100._8
> > +real(8) cs(1,1011)  ! air density (kg/m3)
> > +real(8) dz(1,1011)  ! geometric thickness of layers (m)
> > +real(8) zero
> > +
> > +real(8) wdiab   ! diabatic vertical velocity
> > +real(8), parameter :: wmixmin = 0.1 ! minimum turbulence vertical 
> > velocity (m/s)
> > +!   real(8), parameter :: wmixmin = 0.2 ! minimum turbulence 
> > vertical velocity (m/s)
> > +!  real(8), parameter :: wmixmin = 1.0 ! minimum turbulence 
> > vertical velocity (m/s)
> > +real(8) ekk(0:1011)   ! density*diffusivity for droplets (kg/m3 
> > m2/s)
> > +real(8), parameter :: sq2pi=2.5066283_8
> > +real(8) dtinv
> > +
> > +integer km1,kp1
> > +real(8) wbar,wmix,wmin,wmax
> > +real(8) dumc
> > +real(8) fac_srflx
> > +real(8) surfrate(1011) ! surface exchange rate (/s)
> > +real(8) surfratemax  ! max surfrate for all species treated here
> > +real(8) dtmin,tinv,dtt
> > +integer nsubmix,nsubmix_bnd
> > +integer i,k,m
> > +real(8) dtmix
> > +real(8) pi
> > +integer nnew,nsav,ntemp
> > +real(8) ekkp(1011),ekkm(1011) ! zn*zs*density*diffusivity
> > +integer count_submix(100)
> > +save count_submix
> > +real(8) nsource(1,1011)! droplet number source (#/kg/s)
> > +real(8) ndropmix(1,1011)   ! droplet number mixing (#/kg/s)
> > +real(8) ndropcol(1)   ! column droplet number (#/m2)
> > +
> > +real(8) na(1),va(1),hy(1)
> > +real(8) naermod(1011) ! (/m3)
> > +real(8) hygro(1011)  ! hygroscopicity of aerosol mode
> > +real(8) vaerosol(1

[PATCH] vect: Adjust vect_transform_reduction assertion [PR114883]

2024-04-30 Thread Jakub Jelinek
Hi!

The assertion doesn't allow IFN_COND_MIN/IFN_COND_MAX, which are
commutative conditional binary operations like ADD/MUL/AND/IOR/XOR,
and can be handled just fine.
In particular, we emit
vminpd  %zmm3, %zmm5, %zmm0{%k2}
vminpd  %zmm0, %zmm3, %zmm5{%k1}
and
vmaxpd  %zmm3, %zmm5, %zmm0{%k2}
vmaxpd  %zmm0, %zmm3, %zmm5{%k1}
in the vectorized loops of the first and second subroutine.

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

2024-04-30  Jakub Jelinek  
Hongtao Liu  

PR tree-optimization/114883
* tree-vect-loop.cc (vect_transform_reduction): Allow IFN_COND_MIN and
IFN_COND_MAX in the assert.

* gfortran.dg/pr114883.f90: New test.

--- gcc/tree-vect-loop.cc.jj2024-04-17 11:34:02.465185397 +0200
+++ gcc/tree-vect-loop.cc   2024-04-29 20:41:04.973723992 +0200
@@ -8505,7 +8505,8 @@ vect_transform_reduction (loop_vec_info
 {
   gcc_assert (code == IFN_COND_ADD || code == IFN_COND_SUB
  || code == IFN_COND_MUL || code == IFN_COND_AND
- || code == IFN_COND_IOR || code == IFN_COND_XOR);
+ || code == IFN_COND_IOR || code == IFN_COND_XOR
+ || code == IFN_COND_MIN || code == IFN_COND_MAX);
   gcc_assert (op.num_ops == 4
  && (op.ops[reduc_index]
  == op.ops[internal_fn_else_index ((internal_fn) code)]));
--- gcc/testsuite/gfortran.dg/pr114883.f90.jj   2024-04-29 20:39:39.000871849 
+0200
+++ gcc/testsuite/gfortran.dg/pr114883.f90  2024-04-29 20:39:27.757021972 
+0200
@@ -0,0 +1,53 @@
+! PR tree-optimization/114883
+! { dg-do compile }
+! { dg-options "-O2 -fvect-cost-model=cheap" }
+! { dg-additional-options "-march=x86-64-v4" { target i?86-*-* x86_64-*-* } }
+
+subroutine pr114883_1(a, b, c, d, e, f, g, h, o)
+  real(8) :: c(1011), d(1011), e(0:1011)
+  real(8) :: p, q, f, r, g(1011), h(1011), b, bar
+  integer :: o(100), a, t, u
+  p = 0.0_8
+  r = bar()
+  u = 1
+  do i = 1,a
+do k = 1,1011
+  km1 = max0(k-1,1)
+  h(k) = c(k) * e(k-1) * d(km1)
+  f = g(k) + h(k)
+  if(f.gt.1.e-6)then
+p = min(p,r)
+  endif
+end do
+q = 0.9_8 * p
+t = integer(b/q + 1)
+if(t>100)then
+  u = t
+endif
+o(u) = o(u) + 1
+  end do
+end subroutine pr114883_1
+subroutine pr114883_2(a, b, c, d, e, f, g, h, o)
+  real(8) :: c(1011), d(1011), e(0:1011)
+  real(8) :: p, q, f, r, g(1011), h(1011), b, bar
+  integer :: o(100), a, t, u
+  p = 0.0_8
+  r = bar()
+  u = 1
+  do i = 1,a
+do k = 1,1011
+  km1 = max0(k-1,1)
+  h(k) = c(k) * e(k-1) * d(km1)
+  f = g(k) + h(k)
+  if(f.gt.1.e-6)then
+p = max(p,r)
+  endif
+end do
+q = 0.9_8 * p
+t = integer(b/q + 1)
+if(t>100)then
+  u = t
+endif
+o(u) = o(u) + 1
+  end do
+end subroutine pr114883_2

Jakub



Re: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.

2024-04-30 Thread Richard Biener
On Tue, Apr 30, 2024 at 1:06 AM Roger Sayle  wrote:
>
>
> This patch solves another ICE-after-error problem in the C family
> front-ends.  Upon a conflicting type redeclaration, the ambiguous
> type is poisoned with an error_mark_node to indicate to the middle-end
> that the type is suspect, but care has to be taken by the front-end to
> avoid passing these malformed trees into the middle-end during error
> recovery. In this case, a var_decl with a poisoned type appears within
> a sizeof() expression (wrapped in NOP_EXPR) which causes problems.
>
> This revision of the patch tests seen_error() to avoid tree traversal
> (STRIP_NOPs) in the most common case that an error hasn't occurred.
> Both this version (and an earlier revision that didn't test seen_error)
> have survived bootstrap and regression testing on x86_64-pc-linux-gnu.
> As a consolation, this code also contains a minor performance improvement,
> by avoiding trying to create (and folding away) a CEIL_DIV_EXPR in the
> common case that "char" is a single-byte.  The current code relies on
> the middle-end's tree folding to recognize that CEIL_DIV_EXPR of
> integer_one_node is a no-op, that can be optimized away.
>
> Ok for mainline?

Where does it end up ICEing?  I see size_binop_loc guards against
error_mark_node operands already, maybe it should use
error_operand_p instead?

>
> 2024-04-30  Roger Sayle  
>
> gcc/c-family/ChangeLog
> PR c/109618
> * c-common.cc (c_sizeof_or_alignof_type): If seen_error() check
> whether value is (a VAR_DECL) of type error_mark_node, or a
> NOP_EXPR thereof.  Avoid folding CEIL_DIV_EXPR for the common
> case where char_type is a single byte.
>
> gcc/testsuite/ChangeLog
> PR c/109618
> * gcc.dg/pr109618.c: New test case.
>
>
> Thanks in advance,
> Roger
> --
>


Re: [PATCH] Don't assert for IFN_COND_{MIN, MAX} in vect_transform_reduction

2024-04-30 Thread Jakub Jelinek
On Tue, Apr 30, 2024 at 09:30:00AM +0200, Richard Biener wrote:
> On Mon, Apr 29, 2024 at 5:30 PM H.J. Lu  wrote:
> >
> > On Mon, Apr 29, 2024 at 6:47 AM liuhongt  wrote:
> > >
> > > The Fortran standard does not specify what the result of the MAX
> > > and MIN intrinsics are if one of the arguments is a NaN. So it
> > > should be ok to tranform reduction for IFN_COND_MIN with vectorized
> > > COND_MIN and REDUC_MIN.
> >
> > The commit subject isn't very clear.   This patch isn't about "Don't assert
> > for IFN_COND_{MIN,MAX}".  It allows IFN_COND_{MIN,MAX} in
> > vect_transform_reduction.
> 
> Well, we allow it elsewhere, we just fail to enumerate all COND_* we allow
> here correctly.
> 
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > > Ok for trunk and backport to GCC14?
> 
> OK for trunk and branch.

Oops, I've just sent the same patch, just with a different testcase
(reduced and which tests both the min and max).
I think the reduced testcase is better.

> > > gcc/ChangeLog:
> > >
> > > PR 114883

Missing tree-optimization/

> > > * tree-vect-loop.cc (vect_transform_reduction): Don't assert
> > > for IFN_COND_{MIN, MAX}.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gfortran.dg/pr114883.f90: New test.

Jakub



Re: [PATCH] make -freg-struct-return visibly a negative alias of -fpcc-struct-return

2024-04-30 Thread Richard Biener
On Sun, Apr 28, 2024 at 10:24 AM Alexandre Oliva  wrote:
>
>
> The fact that both options accept negative forms suggests that maybe
> they aren't negative forms of each other.  They are, but that isn't
> clear even by examining common.opt.  Use NegativeAlias to make it
> abundantly clear.
>
> The 'Optimization' keyword next to freg-struct-return was the only
> thing that caused flag_pcc_struct_return to be a per-function flag,
> and ipa-inline relied on that.  After making it an alias, the
> Optimization keyword was no longer operational.  I'm not sure it was
> sensible or desirable for flag_pcc_struct_return to be a per-function
> setting, but this patch does not intend to change behavior.
>
> Regstrapped on x86_64-linux-gnu and ppc64le-linux-gnu.  Ok to install?

OK.

Thanks,
Richard.

>
> for  gcc/ChangeLog
>
> * common.opt (freg-struct-return): Make it explicitly
> fpcc-struct-return's NegativeAlias.  Copy Optimization...
> (freg-struct-return): ... here.
> ---
>  gcc/common.opt |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/common.opt b/gcc/common.opt
> index ad3488447752b..12d93c76a1e63 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2406,7 +2406,7 @@ Common RejectNegative Joined UInteger Optimization
>  -fpack-struct= Set initial maximum structure member alignment.
>
>  fpcc-struct-return
> -Common Var(flag_pcc_struct_return,1) Init(DEFAULT_PCC_STRUCT_RETURN)
> +Common Var(flag_pcc_struct_return,1) Init(DEFAULT_PCC_STRUCT_RETURN) 
> Optimization
>  Return small aggregates in memory, not registers.
>
>  fpeel-loops
> @@ -2596,7 +2596,7 @@ Common Var(flag_record_gcc_switches)
>  Record gcc command line switches in the object file.
>
>  freg-struct-return
> -Common Var(flag_pcc_struct_return,0) Optimization
> +Common NegativeAlias Alias(fpcc_struct_return) Optimization
>  Return small aggregates in registers.
>
>  fregmove
>
> --
> Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
>Free Software Activist   GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive


Re: [COMMITTED 03/16] Make some Value_Range's explicitly integer.

2024-04-30 Thread Richard Biener
On Sun, Apr 28, 2024 at 9:07 PM Aldy Hernandez  wrote:
>
> Fix some Value_Range's that we know ahead of time will be only
> integers.  This avoids using the polymorphic Value_Range unnecessarily

But isn't Value_Range a variable-size irange but int_range<2> doesn't
support more than two sub-ranges?

So it doesn't look obvious that this isn't actually a regression?

Richard.

> gcc/ChangeLog:
>
> * gimple-ssa-warn-access.cc (check_nul_terminated_array): Make 
> Value_Range an int_range.
> (memmodel_to_uhwi): Same
> * tree-ssa-loop-niter.cc (refine_value_range_using_guard): Same.
> (determine_value_range): Same.
> (infer_loop_bounds_from_signedness): Same.
> (scev_var_range_cant_overflow): Same.
> ---
>  gcc/gimple-ssa-warn-access.cc |  4 ++--
>  gcc/tree-ssa-loop-niter.cc| 12 ++--
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
> index dedaae27b31..450c1caa765 100644
> --- a/gcc/gimple-ssa-warn-access.cc
> +++ b/gcc/gimple-ssa-warn-access.cc
> @@ -330,7 +330,7 @@ check_nul_terminated_array (GimpleOrTree expr, tree src, 
> tree bound)
>wide_int bndrng[2];
>if (bound)
>  {
> -  Value_Range r (TREE_TYPE (bound));
> +  int_range<2> r (TREE_TYPE (bound));
>
>get_range_query (cfun)->range_of_expr (r, bound);
>
> @@ -2816,7 +2816,7 @@ memmodel_to_uhwi (tree ord, gimple *stmt, unsigned 
> HOST_WIDE_INT *cstval)
>  {
>/* Use the range query to determine constant values in the absence
>  of constant propagation (such as at -O0).  */
> -  Value_Range rng (TREE_TYPE (ord));
> +  int_range<2> rng (TREE_TYPE (ord));
>if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
>   || !rng.singleton_p (&ord))
> return false;
> diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
> index c6d010f6d89..cbc9dbc5a1f 100644
> --- a/gcc/tree-ssa-loop-niter.cc
> +++ b/gcc/tree-ssa-loop-niter.cc
> @@ -214,7 +214,7 @@ refine_value_range_using_guard (tree type, tree var,
>get_type_static_bounds (type, mint, maxt);
>mpz_init (minc1);
>mpz_init (maxc1);
> -  Value_Range r (TREE_TYPE (varc1));
> +  int_range<2> r (TREE_TYPE (varc1));
>/* Setup range information for varc1.  */
>if (integer_zerop (varc1))
>  {
> @@ -368,7 +368,7 @@ determine_value_range (class loop *loop, tree type, tree 
> var, mpz_t off,
>gphi_iterator gsi;
>
>/* Either for VAR itself...  */
> -  Value_Range var_range (TREE_TYPE (var));
> +  int_range<2> var_range (TREE_TYPE (var));
>get_range_query (cfun)->range_of_expr (var_range, var);
>if (var_range.varying_p () || var_range.undefined_p ())
> rtype = VR_VARYING;
> @@ -382,7 +382,7 @@ determine_value_range (class loop *loop, tree type, tree 
> var, mpz_t off,
>
>/* Or for PHI results in loop->header where VAR is used as
>  PHI argument from the loop preheader edge.  */
> -  Value_Range phi_range (TREE_TYPE (var));
> +  int_range<2> phi_range (TREE_TYPE (var));
>for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next 
> (&gsi))
> {
>   gphi *phi = gsi.phi ();
> @@ -408,7 +408,7 @@ determine_value_range (class loop *loop, tree type, tree 
> var, mpz_t off,
>  involved.  */
>   if (wi::gt_p (minv, maxv, sgn))
> {
> - Value_Range vr (TREE_TYPE (var));
> + int_range<2> vr (TREE_TYPE (var));
>   get_range_query (cfun)->range_of_expr (vr, var);
>   if (vr.varying_p () || vr.undefined_p ())
> rtype = VR_VARYING;
> @@ -4367,7 +4367,7 @@ infer_loop_bounds_from_signedness (class loop *loop, 
> gimple *stmt)
>
>low = lower_bound_in_type (type, type);
>high = upper_bound_in_type (type, type);
> -  Value_Range r (TREE_TYPE (def));
> +  int_range<2> r (TREE_TYPE (def));
>get_range_query (cfun)->range_of_expr (r, def);
>if (!r.varying_p () && !r.undefined_p ())
>  {
> @@ -5426,7 +5426,7 @@ scev_var_range_cant_overflow (tree var, tree step, 
> class loop *loop)
>if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb))
>  return false;
>
> -  Value_Range r (TREE_TYPE (var));
> +  int_range<2> r (TREE_TYPE (var));
>get_range_query (cfun)->range_of_expr (r, var);
>if (r.varying_p () || r.undefined_p ())
>  return false;
> --
> 2.44.0
>


Re: [PATCH] rust: Do not link with libdl and libpthread unconditionally

2024-04-30 Thread Richard Biener
On Fri, Apr 19, 2024 at 11:49 AM Arthur Cohen  wrote:
>
> Hi everyone,
>
> This patch checks for the presence of dlopen and pthread_create in libc. If 
> that is not the
> case, we check for the existence of -ldl and -lpthread, as these libraries 
> are required to
> link the Rust runtime to our Rust frontend.
>
> If these libs are not present on the system, then we disable the Rust 
> frontend.
>
> This was tested on x86_64, in an environment with a recent GLIBC and in a 
> container with GLIBC
> 2.27.
>
> Apologies for sending it in so late.

For example GCC_ENABLE_PLUGINS simply does

 # Check -ldl
 saved_LIBS="$LIBS"
 AC_SEARCH_LIBS([dlopen], [dl])
 if test x"$ac_cv_search_dlopen" = x"-ldl"; then
   pluginlibs="$pluginlibs -ldl"
 fi
 LIBS="$saved_LIBS"

which I guess would also work for pthread_create?  This would simplify
the code a bit.

> ChangeLog:
>
> * Makefile.tpl: Add CRAB1_LIBS variable.
> * Makefile.in: Regenerate.
> * configure: Regenerate.
> * configure.ac: Check if -ldl and -lpthread are needed, and if so, add
> them to CRAB1_LIBS.
>
> gcc/rust/ChangeLog:
>
> * Make-lang.in: Remove overazealous LIBS = -ldl -lpthread line, link
> crab1 against CRAB1_LIBS.
> ---
>  Makefile.in   |   3 +
>  Makefile.tpl  |   3 +
>  configure | 157 ++
>  configure.ac  |  94 +
>  gcc/rust/Make-lang.in |   2 +-
>  5 files changed, 258 insertions(+), 1 deletion(-)
>
> diff --git a/Makefile.in b/Makefile.in
> index db4fa6c6260..34c5550beca 100644
> --- a/Makefile.in
> +++ b/Makefile.in
> @@ -197,6 +197,7 @@ HOST_EXPORTS = \
> $(BASE_EXPORTS) \
> CC="$(CC)"; export CC; \
> ADA_CFLAGS="$(ADA_CFLAGS)"; export ADA_CFLAGS; \
> +   CRAB1_LIBS="$(CRAB1_LIBS)"; export CRAB1_LIBS; \
> CFLAGS="$(CFLAGS)"; export CFLAGS; \
> CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
> CXX="$(CXX)"; export CXX; \
> @@ -450,6 +451,8 @@ GOCFLAGS = $(CFLAGS)
>  GDCFLAGS = @GDCFLAGS@
>  GM2FLAGS = $(CFLAGS)
>
> +CRAB1_LIBS = @CRAB1_LIBS@
> +
>  PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
>
>  GUILE = guile
> diff --git a/Makefile.tpl b/Makefile.tpl
> index 1d5813cd569..8f4bf297918 100644
> --- a/Makefile.tpl
> +++ b/Makefile.tpl
> @@ -200,6 +200,7 @@ HOST_EXPORTS = \
> $(BASE_EXPORTS) \
> CC="$(CC)"; export CC; \
> ADA_CFLAGS="$(ADA_CFLAGS)"; export ADA_CFLAGS; \
> +   CRAB1_LIBS="$(CRAB1_LIBS)"; export CRAB1_LIBS; \
> CFLAGS="$(CFLAGS)"; export CFLAGS; \
> CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
> CXX="$(CXX)"; export CXX; \
> @@ -453,6 +454,8 @@ GOCFLAGS = $(CFLAGS)
>  GDCFLAGS = @GDCFLAGS@
>  GM2FLAGS = $(CFLAGS)
>
> +CRAB1_LIBS = @CRAB1_LIBS@
> +
>  PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
>
>  GUILE = guile
> diff --git a/configure b/configure
> index 3b0abeb8b2e..75b489a5f57 100755
> --- a/configure
> +++ b/configure
> @@ -690,6 +690,7 @@ extra_host_zlib_configure_flags
>  extra_host_libiberty_configure_flags
>  stage1_languages
>  host_libs_picflag
> +CRAB1_LIBS
>  PICFLAG
>  host_shared
>  gcc_host_pie
> @@ -8875,6 +8876,142 @@ fi
>
>
>
> +# Rust requires -ldl and -lpthread if you are using an old glibc that does 
> not include them by
> +# default, so we check for them here
> +
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libc includes libdl and 
> libpthread" >&5
> +$as_echo_n "checking if libc includes libdl and libpthread... " >&6; }
> +
> +ac_ext=c
> +ac_cpp='$CPP $CPPFLAGS'
> +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
> +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS 
> conftest.$ac_ext $LIBS >&5'
> +ac_compiler_gnu=$ac_cv_c_compiler_gnu
> +
> +
> +requires_ldl=no
> +requires_lpthread=no
> +missing_rust_dynlibs=none
> +
> +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +#include 
> +int
> +main ()
> +{
> +dlopen(0,0);
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_link "$LINENO"; then :
> +
> +else
> +  requires_ldl=yes
> +
> +fi
> +rm -f core conftest.err conftest.$ac_objext \
> +conftest$ac_exeext conftest.$ac_ext
> +
> +if test $requires_ldl = yes; then
> +tmp_LIBS=$LIBS
> +LIBS="$LIBS -ldl"
> +
> +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +#include 
> +int
> +main ()
> +{
> +dlopen(0,0);
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_link "$LINENO"; then :
> +  CRAB1_LIBS="$CRAB1_LIBS -ldl"
> +else
> +  missing_rust_dynlibs="libdl"
> +
> +fi
> +rm -f core conftest.err conftest.$ac_objext \
> +conftest$ac_exeext conftest.$ac_ext
> +
> +LIBS=$tmp_LIBS
> +fi
> +
> +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +#include 
> +int
> +main ()
> +{
> +pthread_create(NULL,NULL,NULL,NULL);
> +
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_link "$LINENO"; then :
> +
> +else
> +  require

Re: [PATCH 2/3] c++/modules: Propagate using decls from partitions

2024-04-30 Thread Nathaniel Shead
On Sun, Apr 14, 2024 at 01:40:18AM +1000, Nathaniel Shead wrote:
> On Fri, Apr 12, 2024 at 01:50:47PM -0400, Jason Merrill wrote:
> > On 4/11/24 20:40, Nathaniel Shead wrote:
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> > > 
> > > -- >8 --
> > > 
> > > The modules code currently neglects to set OVL_USING_P on the dependency
> > > created for a using-decl, which causes it not to remember that the
> > > OVL_EXPORT_P flag had been set on it when emitted from the primary
> > > interface unit. This patch ensures that it occurs.
> > > 
> > > gcc/cp/ChangeLog:
> > > 
> > >   * module.cc (depset::hash::add_binding_entity): Propagate
> > >   OVL_USING_P for using-declarations.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > >   * g++.dg/modules/using-15_a.C: New test.
> > >   * g++.dg/modules/using-15_b.C: New test.
> > >   * g++.dg/modules/using-15_c.C: New test.
> > > 
> > > Signed-off-by: Nathaniel Shead 
> > > ---
> > >   gcc/cp/module.cc  |  4 
> > >   gcc/testsuite/g++.dg/modules/using-15_a.C | 13 +
> > >   gcc/testsuite/g++.dg/modules/using-15_b.C |  5 +
> > >   gcc/testsuite/g++.dg/modules/using-15_c.C |  7 +++
> > >   4 files changed, 29 insertions(+)
> > >   create mode 100644 gcc/testsuite/g++.dg/modules/using-15_a.C
> > >   create mode 100644 gcc/testsuite/g++.dg/modules/using-15_b.C
> > >   create mode 100644 gcc/testsuite/g++.dg/modules/using-15_c.C
> > > 
> > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> > > index 9d054c4c792..527c9046c67 100644
> > > --- a/gcc/cp/module.cc
> > > +++ b/gcc/cp/module.cc
> > > @@ -12915,10 +12915,12 @@ depset::hash::add_binding_entity (tree decl, 
> > > WMB_Flags flags, void *data_)
> > >   /* Ignore NTTP objects.  */
> > >   return false;
> > > +  bool unscoped_enum_const_p = false;
> > > if (!(flags & WMB_Using) && CP_DECL_CONTEXT (decl) != data->ns)
> > >   {
> > > /* A using that lost its wrapper or an unscoped enum
> > >constant.  */
> > > +   unscoped_enum_const_p = (TREE_CODE (decl) == CONST_DECL);
> > 
> > How does this interact with C++20 using enum?
> 
> Looks like it ignores those (so they still suffer from this error).  But
> in general we don't handle usings of non-functions correctly anyway yet
> (for the reasons I described in the cover letter); I just added this for
> now to prevent regressing some test-cases caused by importing enum
> consts wrapped in an OVERLOAD.
> 
> Otherwise happy to defer this patch until GCC 15 when I can look at
> exploring what needs to be done to handle non-function using-decls
> correctly, but I'll need to work out a new testcase for the followup
> patch in this series (or just defer that one too, I suppose).
> 

Ping.  Or should I just scrap this patch for now, find a new testcase
for the followup patch, and submit it again once we have a general
solution for using-decls of non-functions?

> > > flags = WMB_Flags (flags | WMB_Using);
> > > if (DECL_MODULE_EXPORT_P (TREE_CODE (decl) == CONST_DECL
> > >   ? TYPE_NAME (TREE_TYPE (decl))
> > > @@ -12979,6 +12981,8 @@ depset::hash::add_binding_entity (tree decl, 
> > > WMB_Flags flags, void *data_)
> > > if (flags & WMB_Using)
> > >   {
> > > decl = ovl_make (decl, NULL_TREE);
> > > +   if (!unscoped_enum_const_p)
> > > + OVL_USING_P (decl) = true;
> > > if (flags & WMB_Export)
> > >   OVL_EXPORT_P (decl) = true;
> > >   }
> > > diff --git a/gcc/testsuite/g++.dg/modules/using-15_a.C 
> > > b/gcc/testsuite/g++.dg/modules/using-15_a.C
> > > new file mode 100644
> > > index 000..23895bd8c4a
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/modules/using-15_a.C
> > > @@ -0,0 +1,13 @@
> > > +// { dg-additional-options "-fmodules-ts -Wno-global-module" }
> > > +// { dg-module-cmi M:a }
> > > +
> > > +module;
> > > +namespace foo {
> > > +  void a();
> > > +};
> > > +export module M:a;
> > > +
> > > +namespace bar {
> > > +  // propagate usings from partitions
> > > +  export using foo::a;
> > > +};
> > > diff --git a/gcc/testsuite/g++.dg/modules/using-15_b.C 
> > > b/gcc/testsuite/g++.dg/modules/using-15_b.C
> > > new file mode 100644
> > > index 000..a88f86af61f
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/modules/using-15_b.C
> > > @@ -0,0 +1,5 @@
> > > +// { dg-additional-options "-fmodules-ts" }
> > > +// { dg-module-cmi M }
> > > +
> > > +export module M;
> > > +export import :a;
> > > diff --git a/gcc/testsuite/g++.dg/modules/using-15_c.C 
> > > b/gcc/testsuite/g++.dg/modules/using-15_c.C
> > > new file mode 100644
> > > index 000..0651efffc91
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/modules/using-15_c.C
> > > @@ -0,0 +1,7 @@
> > > +// { dg-additional-options "-fmodules-ts" }
> > > +import M;
> > > +
> > > +int main() {
> > > +  bar::a();
> > > +  foo::a();  // { dg

Re: [PATCH 1/2] Add verification of gimple_assign_nontemporal_move_p [PR112976]

2024-04-30 Thread Richard Biener
On Sat, Apr 27, 2024 at 1:04 AM Andrew Pinski  wrote:
>
> Currently the middle-end only knows how to support temporal stores
> (the undocumented storent optab) so let's verify that the only time
> we set nontemporal_move on an assign is if the the lhs is not a
> gimple reg.
>
> Bootstrapped and tested on x86_64-linux-gnu no regressions.

OK.

> gcc/ChangeLog:
>
> PR middle-end/112976
> * tree-cfg.cc (verify_gimple_assign): Verify that
> nontmporal moves are stores.
> * gimple.h (struct gimple): Note that only
> nontemporal stores are supported.
>
> Signed-off-by: Andrew Pinski 
> ---
>  gcc/gimple.h|  3 ++-
>  gcc/tree-cfg.cc | 11 +++
>  2 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/gimple.h b/gcc/gimple.h
> index 8a8ca109bbf..bd315ffc2dd 100644
> --- a/gcc/gimple.h
> +++ b/gcc/gimple.h
> @@ -236,7 +236,8 @@ struct GTY((desc ("gimple_statement_structure (&%h)"), 
> tag ("GSS_BASE"),
>   for clearing this bit before using it.  */
>unsigned int visited : 1;
>
> -  /* Nonzero if this tuple represents a non-temporal move.  */
> +  /* Nonzero if this tuple represents a non-temporal move; currently
> + only stores are supported.  */
>unsigned int nontemporal_move: 1;
>
>/* Pass local flags.  These flags are free for any pass to use as
> diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
> index b1ba33018fd..06a96f96be7 100644
> --- a/gcc/tree-cfg.cc
> +++ b/gcc/tree-cfg.cc
> @@ -4837,6 +4837,17 @@ verify_gimple_assign_single (gassign *stmt)
>  static bool
>  verify_gimple_assign (gassign *stmt)
>  {
> +  if (gimple_assign_nontemporal_move_p (stmt))
> +{
> +  tree lhs = gimple_assign_lhs (stmt);
> +  if (is_gimple_reg (lhs))
> +   {
> + error ("nontemporal store lhs cannot a gimple register");
> + debug_generic_stmt (lhs);
> + return true;
> +   }
> +}
> +
>switch (gimple_assign_rhs_class (stmt))
>  {
>  case GIMPLE_SINGLE_RHS:
> --
> 2.43.0
>


Re: [PATCH 2/2] Remove support for nontemporal stores with ssa_names on lhs [PR112976]

2024-04-30 Thread Richard Biener
On Sat, Apr 27, 2024 at 1:04 AM Andrew Pinski  wrote:
>
> When cfgexpand was changed to support expanding from tuple gimple
> (r0-95521-g28ed065ef9f345), the code was added to support
> doing nontemporal stores with LHS of a SSA_NAME but that will
> never be a nontemporal store.
> This patch removes that and asserts that expanding with a LHS
> of a SSA_NAME is not a nontemporal store.
>
> Bootstrapped and tested on x86_64-linux-gnu.

OK.

> gcc/ChangeLog:
>
> PR middle-end/112976
> * cfgexpand.cc (expand_gimple_stmt_1): Remove
> support for expanding nontemporal "moves" with
> ssa names on the LHS.
>
> Signed-off-by: Andrew Pinski 
> ---
>  gcc/cfgexpand.cc | 11 ---
>  1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
> index eef565eddb5..cfc5291aa0c 100644
> --- a/gcc/cfgexpand.cc
> +++ b/gcc/cfgexpand.cc
> @@ -4002,17 +4002,16 @@ expand_gimple_stmt_1 (gimple *stmt)
> else
>   {
> rtx target, temp;
> -   bool nontemporal = gimple_assign_nontemporal_move_p (assign_stmt);
> +   gcc_assert (!gimple_assign_nontemporal_move_p (assign_stmt));
> bool promoted = false;
>
> target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
> if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
>   promoted = true;
>
> -  /* If we want to use a nontemporal store, force the value to
> - register first.  If we store into a promoted register,
> - don't directly expand to target.  */
> -   temp = nontemporal || promoted ? NULL_RTX : target;
> +  /* If we store into a promoted register, don't directly
> + expand to target.  */
> +   temp = promoted ? NULL_RTX : target;
> temp = expand_expr_real_gassign (assign_stmt, temp,
>  GET_MODE (target), 
> EXPAND_NORMAL);
>
> @@ -4034,8 +4033,6 @@ expand_gimple_stmt_1 (gimple *stmt)
>
> convert_move (SUBREG_REG (target), temp, unsignedp);
>   }
> -   else if (nontemporal && emit_storent_insn (target, temp))
> - ;
> else
>   {
> temp = force_operand (temp, target);
> --
> 2.43.0
>


Re: [PATCH] Don't assert for IFN_COND_{MIN, MAX} in vect_transform_reduction

2024-04-30 Thread Hongtao Liu
On Tue, Apr 30, 2024 at 3:38 PM Jakub Jelinek  wrote:
>
> On Tue, Apr 30, 2024 at 09:30:00AM +0200, Richard Biener wrote:
> > On Mon, Apr 29, 2024 at 5:30 PM H.J. Lu  wrote:
> > >
> > > On Mon, Apr 29, 2024 at 6:47 AM liuhongt  wrote:
> > > >
> > > > The Fortran standard does not specify what the result of the MAX
> > > > and MIN intrinsics are if one of the arguments is a NaN. So it
> > > > should be ok to tranform reduction for IFN_COND_MIN with vectorized
> > > > COND_MIN and REDUC_MIN.
> > >
> > > The commit subject isn't very clear.   This patch isn't about "Don't 
> > > assert
> > > for IFN_COND_{MIN,MAX}".  It allows IFN_COND_{MIN,MAX} in
> > > vect_transform_reduction.
> >
> > Well, we allow it elsewhere, we just fail to enumerate all COND_* we allow
> > here correctly.
> >
> > > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > > > Ok for trunk and backport to GCC14?
> >
> > OK for trunk and branch.
>
> Oops, I've just sent the same patch, just with a different testcase
> (reduced and which tests both the min and max).
> I think the reduced testcase is better.
Yes, please commit your patch :)
>
> > > > gcc/ChangeLog:
> > > >
> > > > PR 114883
>
> Missing tree-optimization/
>
> > > > * tree-vect-loop.cc (vect_transform_reduction): Don't assert
> > > > for IFN_COND_{MIN, MAX}.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > > * gfortran.dg/pr114883.f90: New test.
>
> Jakub
>


-- 
BR,
Hongtao


Re: [PATCH 2/2] PHI-OPT: speed up value_replacement slightly

2024-04-30 Thread Richard Biener
On Sun, Apr 28, 2024 at 8:31 AM Andrew Pinski  wrote:
>
> This adds a few early outs to value_replacement that I noticed
> while rewriting this to use match-and-simplify but could be committed
> seperately.
> * virtual operands won't change so return early for them
> * special case `A ? B : B` as that is already just `B`
>
> Also moves the check for NE/EQ earlier as calculating empty_or_with_defined_p
> is an IR walk for a BB and that might be big.
>
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.

OK.

> gcc/ChangeLog:
>
> * tree-ssa-phiopt.cc (value_replacement): Move check for
> NE/EQ earlier.
>
> Signed-off-by: Andrew Pinski 
> ---
>  gcc/tree-ssa-phiopt.cc | 22 +++---
>  1 file changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
> index f1e07502b02..a2bdcb5eae8 100644
> --- a/gcc/tree-ssa-phiopt.cc
> +++ b/gcc/tree-ssa-phiopt.cc
> @@ -1131,6 +1131,21 @@ value_replacement (basic_block cond_bb, basic_block 
> middle_bb,
>enum tree_code code;
>bool empty_or_with_defined_p = true;
>
> +  /* Virtual operands don't need to be handled. */
> +  if (virtual_operand_p (arg1))
> +return 0;
> +
> +  /* Special case A ? B : B as this will always simplify to B. */
> +  if (operand_equal_for_phi_arg_p (arg0, arg1))
> +return 0;
> +
> +  gcond *cond = as_a  (*gsi_last_bb (cond_bb));
> +  code = gimple_cond_code (cond);
> +
> +  /* This transformation is only valid for equality comparisons.  */
> +  if (code != NE_EXPR && code != EQ_EXPR)
> +return 0;
> +
>/* If the type says honor signed zeros we cannot do this
>   optimization.  */
>if (HONOR_SIGNED_ZEROS (arg1))
> @@ -1161,13 +1176,6 @@ value_replacement (basic_block cond_bb, basic_block 
> middle_bb,
> empty_or_with_defined_p = false;
>  }
>
> -  gcond *cond = as_a  (*gsi_last_bb (cond_bb));
> -  code = gimple_cond_code (cond);
> -
> -  /* This transformation is only valid for equality comparisons.  */
> -  if (code != NE_EXPR && code != EQ_EXPR)
> -return 0;
> -
>/* We need to know which is the true edge and which is the false
>edge so that we know if have abs or negative abs.  */
>extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
> --
> 2.43.0
>


Re: [PATCH 1/2] MATCH: change single_non_singleton_phi_for_edges for singleton phis

2024-04-30 Thread Richard Biener
On Sun, Apr 28, 2024 at 8:31 AM Andrew Pinski  wrote:
>
> I noticed that single_non_singleton_phi_for_edges could
> return a phi whos entry are all the same for the edge.
> This happens only if there was a single phis in the first place.
> Also gimple_seq_singleton_p walks the sequence to see if it the one
> element in the sequence so there is removing that check actually
> reduces the number of pointer walks needed.
>
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.

OK.

Richard.

> gcc/ChangeLog:
>
> * tree-ssa-phiopt.cc (single_non_singleton_phi_for_edges):
> Remove the special case of gimple_seq_singleton_p.
>
> Signed-off-by: Andrew Pinski 
> ---
>  gcc/tree-ssa-phiopt.cc | 8 
>  1 file changed, 8 deletions(-)
>
> diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
> index d1746c4b468..f1e07502b02 100644
> --- a/gcc/tree-ssa-phiopt.cc
> +++ b/gcc/tree-ssa-phiopt.cc
> @@ -62,14 +62,6 @@ single_non_singleton_phi_for_edges (gimple_seq seq, edge 
> e0, edge e1)
>  {
>gimple_stmt_iterator i;
>gphi *phi = NULL;
> -  if (gimple_seq_singleton_p (seq))
> -{
> -  phi = as_a  (gsi_stmt (gsi_start (seq)));
> -  /* Never return virtual phis.  */
> -  if (virtual_operand_p (gimple_phi_result (phi)))
> -   return NULL;
> -  return phi;
> -}
>for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
>  {
>gphi *p = as_a  (gsi_stmt (i));
> --
> 2.43.0
>


RE: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.

2024-04-30 Thread Roger Sayle


Hi Richard,
Thanks for looking into this.

It’s not the call to size_binop_loc (for CEIL_DIV_EXPR) that's problematic, but 
the
call to fold_convert_loc (loc, size_type_node, value) on line 4009 of 
c-common.cc.
At this point, value is (NOP_EXPR:sizetype (VAR_DECL:error_mark_node)).

Ultimately, it's the code in match.pd /* Handle cases of two conversions in a 
row.  */
with the problematic line being (match.pd:4748):
  unsigned int inside_prec = element_precision (inside_type); 

Here inside_type is error_mark_node, and so tree type checking in 
element_precision
throws an internal_error.

There doesn’t seem to be a good way to fix this in element_precision, and it's
complicated to reorganize the logic in match.pd's "with clause" inside the
(ocvt (icvt@1 @0)), but perhaps a (ocvt (icvt:non_error_type@1 @0))?

The last place/opportunity the front-end could sanitize this operand before
passing the dubious tree to the middle-end is c_sizeof_or_alignof_type (which
alas doesn't appear in the backtrace due to inlining).

#5  0x0227b0e9 in internal_error (
gmsgid=gmsgid@entry=0x249c7b8 "tree check: expected class %qs, have %qs 
(%s) in %s, at %s:%d") at ../../gcc/gcc/diagnostic.cc:2232
#6  0x0081e32a in tree_class_check_failed (node=0x76c1ef30,
cl=cl@entry=tcc_type, file=file@entry=0x2495f3f "../../gcc/gcc/tree.cc",
line=line@entry=6795, function=function@entry=0x24961fe "element_precision")
at ../../gcc/gcc/tree.cc:9005
#7  0x0081ef4c in tree_class_check (__t=, 
__class=tcc_type,
__f=0x2495f3f "../../gcc/gcc/tree.cc", __l=6795,
__g=0x24961fe "element_precision") at ../../gcc/gcc/tree.h:4067
#8  element_precision (type=, type@entry=0x76c1ef30)
at ../../gcc/gcc/tree.cc:6795
#9  0x017f66a4 in generic_simplify_CONVERT_EXPR (loc=201632,
code=, type=0x76c3e7e0, _p0=0x76dc95c0)
at generic-match-6.cc:3386
#10 0x00c1b18c in fold_unary_loc (loc=201632, code=NOP_EXPR,
type=0x76c3e7e0, op0=0x76dc95c0) at ../../gcc/gcc/fold-const.cc:9523
#11 0x00c1d94a in fold_build1_loc (loc=201632, code=NOP_EXPR,
type=0x76c3e7e0, op0=0x76dc95c0) at 
../../gcc/gcc/fold-const.cc:14165
#12 0x0094068c in c_expr_sizeof_expr (loc=loc@entry=201632, expr=...)
at ../../gcc/gcc/tree.h:3771
#13 0x0097f06c in c_parser_sizeof_expression (parser=)
at ../../gcc/gcc/c/c-parser.cc:9932


I hope this explains what's happening.  The size_binop_loc call is a bit of a 
red
herring that returns the same tree it is given (as TYPE_PRECISION 
(char_type_node)
== BITS_PER_UNIT), so it's the "TYPE_SIZE_UNIT (type)" which needs to be checked
for the embedded VAR_DECL with a TREE_TYPE of error_mark_node.

As Andrew Pinski writes in comment #3, this one is trickier than average.

A more comprehensive fix might be to write deep_error_operand_p which does
more of a tree traversal checking error_operand_p within the unary and binary
operators of an expression tree.

Please let me know what you think/recommend.
Best regards,
Roger
--

> -Original Message-
> From: Richard Biener 
> Sent: 30 April 2024 08:38
> To: Roger Sayle 
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.
> 
> On Tue, Apr 30, 2024 at 1:06 AM Roger Sayle 
> wrote:
> >
> >
> > This patch solves another ICE-after-error problem in the C family
> > front-ends.  Upon a conflicting type redeclaration, the ambiguous type
> > is poisoned with an error_mark_node to indicate to the middle-end that
> > the type is suspect, but care has to be taken by the front-end to
> > avoid passing these malformed trees into the middle-end during error
> > recovery. In this case, a var_decl with a poisoned type appears within
> > a sizeof() expression (wrapped in NOP_EXPR) which causes problems.
> >
> > This revision of the patch tests seen_error() to avoid tree traversal
> > (STRIP_NOPs) in the most common case that an error hasn't occurred.
> > Both this version (and an earlier revision that didn't test
> > seen_error) have survived bootstrap and regression testing on 
> > x86_64-pc-linux-
> gnu.
> > As a consolation, this code also contains a minor performance
> > improvement, by avoiding trying to create (and folding away) a
> > CEIL_DIV_EXPR in the common case that "char" is a single-byte.  The
> > current code relies on the middle-end's tree folding to recognize that
> > CEIL_DIV_EXPR of integer_one_node is a no-op, that can be optimized away.
> >
> > Ok for mainline?
> 
> Where does it end up ICEing?  I see size_binop_loc guards against
> error_mark_node operands already, maybe it should use error_operand_p
> instead?
> 
> >
> > 2024-04-30  Roger Sayle  
> >
> > gcc/c-family/ChangeLog
> > PR c/109618
> > * c-common.cc (c_sizeof_or_alignof_type): If seen_error() check
> > whether value is (a VAR_DECL) of type error_mark_node, or a
> > NOP_EXPR thereof.  Avoid folding CEIL_DIV_E

[PATCH] s390: testsuite: Fix zero_bits_compound-1.c

2024-04-30 Thread Stefan Schulze Frielinghaus
Starting with r12-2731-g96146e61cd7aee we do not generate code like

_5 = (unsigned int) c_2(D);
i_6 = _5 << 8;
_7 = _5 << 20;
i_8 = i_6 | _7;

anymore but instead

_5 = (unsigned int) c_2(D);
_3 = _5 * 1048832;

which leads finally to slightly different assembly code where we
previously ended up for z10 or newer with

lr  %r1,%r2
sll %r1,8
rosbg   %r1,%r2,32,43,20
llgfr   %r2,%r1
br  %r14

and now

lr  %r1,%r2
sll %r1,12
ar  %r2,%r1
risbg   %r2,%r2,35,128+55,8
br  %r14

The zero-extend materializes via risbg for which the pattern contains an
"and" which is why the test fails.  Thus, instead of scanning for RTL
expressions rather scan for assembler instructions for s390.
---
 Ok for mainline?

 gcc/testsuite/gcc.dg/zero_bits_compound-1.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/zero_bits_compound-1.c 
b/gcc/testsuite/gcc.dg/zero_bits_compound-1.c
index e71594911b2..f1e267e0fb0 100644
--- a/gcc/testsuite/gcc.dg/zero_bits_compound-1.c
+++ b/gcc/testsuite/gcc.dg/zero_bits_compound-1.c
@@ -39,4 +39,5 @@ unsigned long bar (unsigned char c)
 }
 
 /* Check that no pattern containing an AND expression was used.  */
-/* { dg-final { scan-assembler-not "\\(and:" } } */
+/* { dg-final { scan-assembler-not "\\(and:" { target { ! { s390*-*-* } } } } 
} */
+/* { dg-final { scan-assembler-not "\\tng?rk?\\t" { target { s390*-*-* } } } } 
*/
-- 
2.44.0



[PATCH] s390: testsuite: Fix risbg-ll-2.c

2024-04-30 Thread Stefan Schulze Frielinghaus
Starting with r14-2047-gd0e891406b16dc we see through subregs which
means for f10 in risbg-ll-2.c we do not end up with rosbg_si_noshift but
rather rosbg_di_noshift which materializes in slightly different start
index.  This saves us an extend.

gcc/testsuite/ChangeLog:

* gcc.target/s390/risbg-ll-2.c: Fix start offset for rosbg of
f10.
---
 Ok for mainline?

 gcc/testsuite/gcc.target/s390/risbg-ll-2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/s390/risbg-ll-2.c 
b/gcc/testsuite/gcc.target/s390/risbg-ll-2.c
index 8bf1a0ff88b..ca80602a83f 100644
--- a/gcc/testsuite/gcc.target/s390/risbg-ll-2.c
+++ b/gcc/testsuite/gcc.target/s390/risbg-ll-2.c
@@ -113,7 +113,7 @@ i32 f9 (i64 v_x, i32 v_y)
 // ands with incompatible masks.
 i32 f10 (i64 v_x, i32 v_y)
 {
-  /* { dg-final { scan-assembler 
"f10:\n\tsrlg\t%r2,%r2,48\n\trosbg\t%r2,%r3,32,39,0" { target { lp64 } } } } */
+  /* { dg-final { scan-assembler 
"f10:\n\tsrlg\t%r2,%r2,48\n\trosbg\t%r2,%r3,0,39,0" { target { lp64 } } } } */
   /* { dg-final { scan-assembler 
"f10:\n\tnilf\t%r4,4278190080\n\trosbg\t%r4,%r2,48,63,48" { target { ! lp64 } } 
} } */
   i64 v_shr6 = ((ui64)v_x) >> 48;
   i32 v_conv = (ui32)v_shr6;
-- 
2.44.0



Re: [COMMITTED 03/16] Make some Value_Range's explicitly integer.

2024-04-30 Thread Aldy Hernandez
Ughhh, you're right.  Thanks for spotting this.

I'm testing the attached patch and will commit if it passes tests.

Aldy

On Tue, Apr 30, 2024 at 9:46 AM Richard Biener
 wrote:
>
> On Sun, Apr 28, 2024 at 9:07 PM Aldy Hernandez  wrote:
> >
> > Fix some Value_Range's that we know ahead of time will be only
> > integers.  This avoids using the polymorphic Value_Range unnecessarily
>
> But isn't Value_Range a variable-size irange but int_range<2> doesn't
> support more than two sub-ranges?
>
> So it doesn't look obvious that this isn't actually a regression?
>
> Richard.
>
> > gcc/ChangeLog:
> >
> > * gimple-ssa-warn-access.cc (check_nul_terminated_array): Make 
> > Value_Range an int_range.
> > (memmodel_to_uhwi): Same
> > * tree-ssa-loop-niter.cc (refine_value_range_using_guard): Same.
> > (determine_value_range): Same.
> > (infer_loop_bounds_from_signedness): Same.
> > (scev_var_range_cant_overflow): Same.
> > ---
> >  gcc/gimple-ssa-warn-access.cc |  4 ++--
> >  gcc/tree-ssa-loop-niter.cc| 12 ++--
> >  2 files changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
> > index dedaae27b31..450c1caa765 100644
> > --- a/gcc/gimple-ssa-warn-access.cc
> > +++ b/gcc/gimple-ssa-warn-access.cc
> > @@ -330,7 +330,7 @@ check_nul_terminated_array (GimpleOrTree expr, tree 
> > src, tree bound)
> >wide_int bndrng[2];
> >if (bound)
> >  {
> > -  Value_Range r (TREE_TYPE (bound));
> > +  int_range<2> r (TREE_TYPE (bound));
> >
> >get_range_query (cfun)->range_of_expr (r, bound);
> >
> > @@ -2816,7 +2816,7 @@ memmodel_to_uhwi (tree ord, gimple *stmt, unsigned 
> > HOST_WIDE_INT *cstval)
> >  {
> >/* Use the range query to determine constant values in the absence
> >  of constant propagation (such as at -O0).  */
> > -  Value_Range rng (TREE_TYPE (ord));
> > +  int_range<2> rng (TREE_TYPE (ord));
> >if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
> >   || !rng.singleton_p (&ord))
> > return false;
> > diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
> > index c6d010f6d89..cbc9dbc5a1f 100644
> > --- a/gcc/tree-ssa-loop-niter.cc
> > +++ b/gcc/tree-ssa-loop-niter.cc
> > @@ -214,7 +214,7 @@ refine_value_range_using_guard (tree type, tree var,
> >get_type_static_bounds (type, mint, maxt);
> >mpz_init (minc1);
> >mpz_init (maxc1);
> > -  Value_Range r (TREE_TYPE (varc1));
> > +  int_range<2> r (TREE_TYPE (varc1));
> >/* Setup range information for varc1.  */
> >if (integer_zerop (varc1))
> >  {
> > @@ -368,7 +368,7 @@ determine_value_range (class loop *loop, tree type, 
> > tree var, mpz_t off,
> >gphi_iterator gsi;
> >
> >/* Either for VAR itself...  */
> > -  Value_Range var_range (TREE_TYPE (var));
> > +  int_range<2> var_range (TREE_TYPE (var));
> >get_range_query (cfun)->range_of_expr (var_range, var);
> >if (var_range.varying_p () || var_range.undefined_p ())
> > rtype = VR_VARYING;
> > @@ -382,7 +382,7 @@ determine_value_range (class loop *loop, tree type, 
> > tree var, mpz_t off,
> >
> >/* Or for PHI results in loop->header where VAR is used as
> >  PHI argument from the loop preheader edge.  */
> > -  Value_Range phi_range (TREE_TYPE (var));
> > +  int_range<2> phi_range (TREE_TYPE (var));
> >for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next 
> > (&gsi))
> > {
> >   gphi *phi = gsi.phi ();
> > @@ -408,7 +408,7 @@ determine_value_range (class loop *loop, tree type, 
> > tree var, mpz_t off,
> >  involved.  */
> >   if (wi::gt_p (minv, maxv, sgn))
> > {
> > - Value_Range vr (TREE_TYPE (var));
> > + int_range<2> vr (TREE_TYPE (var));
> >   get_range_query (cfun)->range_of_expr (vr, var);
> >   if (vr.varying_p () || vr.undefined_p ())
> > rtype = VR_VARYING;
> > @@ -4367,7 +4367,7 @@ infer_loop_bounds_from_signedness (class loop *loop, 
> > gimple *stmt)
> >
> >low = lower_bound_in_type (type, type);
> >high = upper_bound_in_type (type, type);
> > -  Value_Range r (TREE_TYPE (def));
> > +  int_range<2> r (TREE_TYPE (def));
> >get_range_query (cfun)->range_of_expr (r, def);
> >if (!r.varying_p () && !r.undefined_p ())
> >  {
> > @@ -5426,7 +5426,7 @@ scev_var_range_cant_overflow (tree var, tree step, 
> > class loop *loop)
> >if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb))
> >  return false;
> >
> > -  Value_Range r (TREE_TYPE (var));
> > +  int_range<2> r (TREE_TYPE (var));
> >get_range_query (cfun)->range_of_expr (r, var);
> >if (r.varying_p () || r.undefined_p ())
> >  return false;
> > --
> > 2.44.0
> >
>
From f43749b8381a9b1b0a

Re: [PATCH] libgm2: re-generate with autoreconf

2024-04-30 Thread Christophe Lyon
On Tue, 30 Apr 2024 at 04:01, Simon Marchi  wrote:
>
> I get a diff when running "autoreconf" in this directory.  I think that
> the current state is erroneous: it appears to have been generated using
>
> aclocal -I ../config -I ..
>
> even though configure.ac and Makefile.am list the include flag in the
> reverse order:
>
>aclocal -I .. -I ../config
>
> Running "autoreconf" uses the latter order, so I think that's the
> "right" output.
>
> No functional difference expected.

Thanks, this matches what I noticed.
I'm not a maintainer, so I cannot approve, but a minor remark: in GCC
we still need a ChangeLog entry in the commit message.

Christophe

> ---
>  libgm2/Makefile.in  | 10 +-
>  libgm2/aclocal.m4   | 10 +-
>  libgm2/libm2cor/Makefile.in | 10 +-
>  libgm2/libm2iso/Makefile.in | 10 +-
>  libgm2/libm2log/Makefile.in | 10 +-
>  libgm2/libm2min/Makefile.in | 10 +-
>  libgm2/libm2pim/Makefile.in | 10 +-
>  7 files changed, 35 insertions(+), 35 deletions(-)
>
> diff --git a/libgm2/Makefile.in b/libgm2/Makefile.in
> index f259df7842cf..9cd79824a53d 100644
> --- a/libgm2/Makefile.in
> +++ b/libgm2/Makefile.in
> @@ -90,15 +90,15 @@ host_triplet = @host@
>  target_triplet = @target@
>  subdir = .
>  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
> -am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
> -   $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
> -   $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
> -   $(top_srcdir)/../config/acx.m4 \
> +am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
> $(top_srcdir)/../config/depstand.m4 \
> $(top_srcdir)/../config/lead-dot.m4 \
> $(top_srcdir)/../config/multi.m4 \
> $(top_srcdir)/../config/no-executables.m4 \
> -   $(top_srcdir)/../config/override.m4 $(top_srcdir)/acinclude.m4 \
> +   $(top_srcdir)/../config/override.m4 \
> +   $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
> +   $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
> +   $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
> $(top_srcdir)/../config/gc++filt.m4 \
> $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
> $(top_srcdir)/../config/cet.m4 $(top_srcdir)/configure.ac
> diff --git a/libgm2/aclocal.m4 b/libgm2/aclocal.m4
> index bee67b05dee2..19cfb0d1eb26 100644
> --- a/libgm2/aclocal.m4
> +++ b/libgm2/aclocal.m4
> @@ -1187,15 +1187,15 @@ AC_SUBST([am__tar])
>  AC_SUBST([am__untar])
>  ]) # _AM_PROG_TAR
>
> -m4_include([../libtool.m4])
> -m4_include([../ltoptions.m4])
> -m4_include([../ltsugar.m4])
> -m4_include([../ltversion.m4])
> -m4_include([../lt~obsolete.m4])
>  m4_include([../config/acx.m4])
>  m4_include([../config/depstand.m4])
>  m4_include([../config/lead-dot.m4])
>  m4_include([../config/multi.m4])
>  m4_include([../config/no-executables.m4])
>  m4_include([../config/override.m4])
> +m4_include([../libtool.m4])
> +m4_include([../ltoptions.m4])
> +m4_include([../ltsugar.m4])
> +m4_include([../ltversion.m4])
> +m4_include([../lt~obsolete.m4])
>  m4_include([acinclude.m4])
> diff --git a/libgm2/libm2cor/Makefile.in b/libgm2/libm2cor/Makefile.in
> index 63299388dd8f..f9952cff71a7 100644
> --- a/libgm2/libm2cor/Makefile.in
> +++ b/libgm2/libm2cor/Makefile.in
> @@ -108,15 +108,15 @@ target_triplet = @target@
>  @BUILD_CORLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = 
> -nodefaultrpaths -Wl,-rpath,@loader_path/
>  subdir = libm2cor
>  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
> -am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \
> -   $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
> -   $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
> -   $(top_srcdir)/../config/acx.m4 \
> +am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
> $(top_srcdir)/../config/depstand.m4 \
> $(top_srcdir)/../config/lead-dot.m4 \
> $(top_srcdir)/../config/multi.m4 \
> $(top_srcdir)/../config/no-executables.m4 \
> -   $(top_srcdir)/../config/override.m4 $(top_srcdir)/acinclude.m4 \
> +   $(top_srcdir)/../config/override.m4 \
> +   $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
> +   $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
> +   $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
> $(top_srcdir)/../config/gc++filt.m4 \
> $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
> $(top_srcdir)/../config/cet.m4 $(top_srcdir)/configure.ac
> diff --git a/libgm2/libm2iso/Makefile.in b/libgm2/libm2iso/Makefile.in
> index 964c6da85270..370837f15b82 100644
> --- a/libgm2/libm2iso/Makefile.in
> +++ b/libgm2/libm2iso/Makefile.in
> @@ -108,15 +108,15 @@ target_triplet = @target@
>  @BUILD_ISOLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = 
> -nodefaultrpaths -Wl,-rpath,@loader_path/
>  subdir = libm2iso
>  ACLOCAL_M4 = $

Re: [PATCH] fixincludes: add AC_CONFIG_MACRO_DIRS to configure.ac

2024-04-30 Thread Christophe Lyon
On Tue, 30 Apr 2024 at 04:25, Simon Marchi  wrote:
>
> Add an "AC_CONFIG_MACRO_DIRS" call in configure.ac, with the same
> directories as specified in "ACLOCAL_AMFLAGS", in Makefile.in.
>
> This makes it possible to re-generate aclocal.m4 using "autoreconf".

Thanks, this LGTM, although like in your other patch, we need a
ChangeLog entry in the commit message.

Christophe

> ---
>  fixincludes/configure| 1 +
>  fixincludes/configure.ac | 1 +
>  2 files changed, 2 insertions(+)
>
> diff --git a/fixincludes/configure b/fixincludes/configure
> index 662c94dc1120..7147c9a618aa 100755
> --- a/fixincludes/configure
> +++ b/fixincludes/configure
> @@ -4627,6 +4627,7 @@ $as_echo "$ac_cv_path_SED" >&6; }
>rm -f conftest.sed
>
>
> +
>  # Figure out what compiler warnings we can enable.
>  # See config/warnings.m4 for details.
>
> diff --git a/fixincludes/configure.ac b/fixincludes/configure.ac
> index 4e78511d20fc..3d177699ebfa 100644
> --- a/fixincludes/configure.ac
> +++ b/fixincludes/configure.ac
> @@ -7,6 +7,7 @@ AC_CANONICAL_SYSTEM
>  AC_PROG_CC
>  AC_USE_SYSTEM_EXTENSIONS
>  AC_PROG_SED
> +AC_CONFIG_MACRO_DIRS([.. ../config])
>
>  # Figure out what compiler warnings we can enable.
>  # See config/warnings.m4 for details.
>
> base-commit: 22b20ac6c6aead2d3f36c413a77dd0b80adfec39
> --
> 2.44.0
>


Re: [PATCH] gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) 0 argument [PR114876]

2024-04-30 Thread Richard Biener
On Tue, 30 Apr 2024, Jakub Jelinek wrote:

> Hi!
> 
> Seems when Martin S. implemented this, he coded there strict reading
> of the standard, which said that %lc with (wint_t) 0 argument is handled
> as wchar_t[2] temp = { arg, 0 }; %ls with temp arg and so shouldn't print
> any values.  But, most of the libc implementations actually handled that
> case like %c with '\0' argument, adding a single NUL character, the only
> known exception is musl.
> Recently, C23 changed this in response to GB-141 and POSIX in
> https://austingroupbugs.net/view.php?id=1647
> so that it should have the same behavior as %c with '\0'.
> 
> Because there is implementation divergence, the following patch uses
> a range rather than hardcoding it to all 1s (i.e. the %c behavior),
> though the likely case is still 1 (forward looking plus most of
> implementations).
> The res.knownrange = true; assignment removed is redundant due to
> the same assignment done unconditionally before the if statement,
> rest is formatting fixes.
> 
> I don't think the min >= 0 && min < 128 case is right either, I'd think
> it should be min >= 0 && max < 128, otherwise it is just some possible
> inputs are (maybe) ASCII and there can be others, but this code is a total
> mess anyway, with the min, max, likely (somewhere in [min, max]?) and then
> unlikely possibly larger than max, dunno, perhaps for at least some chars
> in the ASCII range the likely case could be for the ascii case; so perhaps
> just the one_2_one_ascii shouldn't set max to 1 and mayfail should be true
> for max >= 128.  Anyway, didn't feel I should touch that right now.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK for trunk.

> Shall it go to 14.1, or wait for 14.2?

I think this can wait for 14.2.

Richard.

> 2024-04-30  Jakub Jelinek  
> 
>   PR tree-optimization/114876
>   * gimple-ssa-sprintf.cc (format_character): For min == 0 && max == 0,
>   set max, likely and unlikely members to 1 rather than 0.  Remove
>   useless res.knownrange = true;.  Formatting fixes.
> 
>   * gcc.dg/pr114876.c: New test.
>   * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected
>   diagnostics.
> 
> --- gcc/gimple-ssa-sprintf.cc.jj  2024-01-03 11:51:22.225860346 +0100
> +++ gcc/gimple-ssa-sprintf.cc 2024-04-29 12:52:59.760668894 +0200
> @@ -2177,8 +2177,7 @@ format_character (const directive &dir,
>  
>res.knownrange = true;
>  
> -  if (dir.specifier == 'C'
> -  || dir.modifier == FMT_LEN_l)
> +  if (dir.specifier == 'C' || dir.modifier == FMT_LEN_l)
>  {
>/* A wide character can result in as few as zero bytes.  */
>res.range.min = 0;
> @@ -2189,10 +2188,13 @@ format_character (const directive &dir,
>   {
> if (min == 0 && max == 0)
>   {
> -   /* The NUL wide character results in no bytes.  */
> -   res.range.max = 0;
> -   res.range.likely = 0;
> -   res.range.unlikely = 0;
> +   /* In strict reading of older ISO C or POSIX, this required
> +  no characters to be emitted.  ISO C23 changes that, so
> +  does POSIX, to match what has been implemented in most of the
> +  implementations, namely emitting a single NUL character.
> +  Let's use 0 for minimum and 1 for all the other values.  */
> +   res.range.max = 1;
> +   res.range.likely = res.range.unlikely = 1;
>   }
> else if (min >= 0 && min < 128)
>   {
> @@ -2200,11 +2202,12 @@ format_character (const directive &dir,
>is not a 1-to-1 mapping to the source character set or
>if the source set is not ASCII.  */
> bool one_2_one_ascii
> - = (target_to_host_charmap[0] == 1 && target_to_host ('a') == 
> 97);
> + = (target_to_host_charmap[0] == 1
> +&& target_to_host ('a') == 97);
>  
> /* A wide character in the ASCII range most likely results
>in a single byte, and only unlikely in up to MB_LEN_MAX.  */
> -   res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();;
> +   res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();
> res.range.likely = 1;
> res.range.unlikely = target_mb_len_max ();
> res.mayfail = !one_2_one_ascii;
> @@ -2235,7 +2238,6 @@ format_character (const directive &dir,
>/* A plain '%c' directive.  Its output is exactly 1.  */
>res.range.min = res.range.max = 1;
>res.range.likely = res.range.unlikely = 1;
> -  res.knownrange = true;
>  }
>  
>/* Bump up the byte counters if WIDTH is greater.  */
> --- gcc/testsuite/gcc.dg/pr114876.c.jj2024-04-29 12:26:45.774965158 
> +0200
> +++ gcc/testsuite/gcc.dg/pr114876.c   2024-04-29 12:51:37.863777055 +0200
> @@ -0,0 +1,34 @@
> +/* PR tree-optimization/114876 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" 

Re: [PATCH] vect: Adjust vect_transform_reduction assertion [PR114883]

2024-04-30 Thread Richard Biener
On Tue, 30 Apr 2024, Jakub Jelinek wrote:

> Hi!
> 
> The assertion doesn't allow IFN_COND_MIN/IFN_COND_MAX, which are
> commutative conditional binary operations like ADD/MUL/AND/IOR/XOR,
> and can be handled just fine.
> In particular, we emit
>   vminpd  %zmm3, %zmm5, %zmm0{%k2}
>   vminpd  %zmm0, %zmm3, %zmm5{%k1}
> and
>   vmaxpd  %zmm3, %zmm5, %zmm0{%k2}
>   vmaxpd  %zmm0, %zmm3, %zmm5{%k1}
> in the vectorized loops of the first and second subroutine.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
> 14.1?

OK for both.

Richard.

> 2024-04-30  Jakub Jelinek  
>   Hongtao Liu  
> 
>   PR tree-optimization/114883
>   * tree-vect-loop.cc (vect_transform_reduction): Allow IFN_COND_MIN and
>   IFN_COND_MAX in the assert.
> 
>   * gfortran.dg/pr114883.f90: New test.
> 
> --- gcc/tree-vect-loop.cc.jj  2024-04-17 11:34:02.465185397 +0200
> +++ gcc/tree-vect-loop.cc 2024-04-29 20:41:04.973723992 +0200
> @@ -8505,7 +8505,8 @@ vect_transform_reduction (loop_vec_info
>  {
>gcc_assert (code == IFN_COND_ADD || code == IFN_COND_SUB
> || code == IFN_COND_MUL || code == IFN_COND_AND
> -   || code == IFN_COND_IOR || code == IFN_COND_XOR);
> +   || code == IFN_COND_IOR || code == IFN_COND_XOR
> +   || code == IFN_COND_MIN || code == IFN_COND_MAX);
>gcc_assert (op.num_ops == 4
> && (op.ops[reduc_index]
> == op.ops[internal_fn_else_index ((internal_fn) code)]));
> --- gcc/testsuite/gfortran.dg/pr114883.f90.jj 2024-04-29 20:39:39.000871849 
> +0200
> +++ gcc/testsuite/gfortran.dg/pr114883.f902024-04-29 20:39:27.757021972 
> +0200
> @@ -0,0 +1,53 @@
> +! PR tree-optimization/114883
> +! { dg-do compile }
> +! { dg-options "-O2 -fvect-cost-model=cheap" }
> +! { dg-additional-options "-march=x86-64-v4" { target i?86-*-* x86_64-*-* } }
> +
> +subroutine pr114883_1(a, b, c, d, e, f, g, h, o)
> +  real(8) :: c(1011), d(1011), e(0:1011)
> +  real(8) :: p, q, f, r, g(1011), h(1011), b, bar
> +  integer :: o(100), a, t, u
> +  p = 0.0_8
> +  r = bar()
> +  u = 1
> +  do i = 1,a
> +do k = 1,1011
> +  km1 = max0(k-1,1)
> +  h(k) = c(k) * e(k-1) * d(km1)
> +  f = g(k) + h(k)
> +  if(f.gt.1.e-6)then
> +p = min(p,r)
> +  endif
> +end do
> +q = 0.9_8 * p
> +t = integer(b/q + 1)
> +if(t>100)then
> +  u = t
> +endif
> +o(u) = o(u) + 1
> +  end do
> +end subroutine pr114883_1
> +subroutine pr114883_2(a, b, c, d, e, f, g, h, o)
> +  real(8) :: c(1011), d(1011), e(0:1011)
> +  real(8) :: p, q, f, r, g(1011), h(1011), b, bar
> +  integer :: o(100), a, t, u
> +  p = 0.0_8
> +  r = bar()
> +  u = 1
> +  do i = 1,a
> +do k = 1,1011
> +  km1 = max0(k-1,1)
> +  h(k) = c(k) * e(k-1) * d(km1)
> +  f = g(k) + h(k)
> +  if(f.gt.1.e-6)then
> +p = max(p,r)
> +  endif
> +end do
> +q = 0.9_8 * p
> +t = integer(b/q + 1)
> +if(t>100)then
> +  u = t
> +endif
> +o(u) = o(u) + 1
> +  end do
> +end subroutine pr114883_2
> 
>   Jakub
> 
> 

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


Re: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.

2024-04-30 Thread Richard Biener
On Tue, Apr 30, 2024 at 10:23 AM Roger Sayle  wrote:
>
>
> Hi Richard,
> Thanks for looking into this.
>
> It’s not the call to size_binop_loc (for CEIL_DIV_EXPR) that's problematic, 
> but the
> call to fold_convert_loc (loc, size_type_node, value) on line 4009 of 
> c-common.cc.
> At this point, value is (NOP_EXPR:sizetype (VAR_DECL:error_mark_node)).

I see.  Can we catch this when we build (NOP_EXPR:sizetype
(VAR_DECL:error_mark_node))
and instead have it "build" error_mark_node?

>
> Ultimately, it's the code in match.pd /* Handle cases of two conversions in a 
> row.  */
> with the problematic line being (match.pd:4748):
>   unsigned int inside_prec = element_precision (inside_type);
>
> Here inside_type is error_mark_node, and so tree type checking in 
> element_precision
> throws an internal_error.
>
> There doesn’t seem to be a good way to fix this in element_precision, and it's
> complicated to reorganize the logic in match.pd's "with clause" inside the
> (ocvt (icvt@1 @0)), but perhaps a (ocvt (icvt:non_error_type@1 @0))?
>
> The last place/opportunity the front-end could sanitize this operand before
> passing the dubious tree to the middle-end is c_sizeof_or_alignof_type (which
> alas doesn't appear in the backtrace due to inlining).
>
> #5  0x0227b0e9 in internal_error (
> gmsgid=gmsgid@entry=0x249c7b8 "tree check: expected class %qs, have %qs 
> (%s) in %s, at %s:%d") at ../../gcc/gcc/diagnostic.cc:2232
> #6  0x0081e32a in tree_class_check_failed (node=0x76c1ef30,
> cl=cl@entry=tcc_type, file=file@entry=0x2495f3f "../../gcc/gcc/tree.cc",
> line=line@entry=6795, function=function@entry=0x24961fe 
> "element_precision")
> at ../../gcc/gcc/tree.cc:9005
> #7  0x0081ef4c in tree_class_check (__t=, 
> __class=tcc_type,
> __f=0x2495f3f "../../gcc/gcc/tree.cc", __l=6795,
> __g=0x24961fe "element_precision") at ../../gcc/gcc/tree.h:4067
> #8  element_precision (type=, type@entry=0x76c1ef30)
> at ../../gcc/gcc/tree.cc:6795
> #9  0x017f66a4 in generic_simplify_CONVERT_EXPR (loc=201632,
> code=, type=0x76c3e7e0, _p0=0x76dc95c0)
> at generic-match-6.cc:3386
> #10 0x00c1b18c in fold_unary_loc (loc=201632, code=NOP_EXPR,
> type=0x76c3e7e0, op0=0x76dc95c0) at 
> ../../gcc/gcc/fold-const.cc:9523
> #11 0x00c1d94a in fold_build1_loc (loc=201632, code=NOP_EXPR,
> type=0x76c3e7e0, op0=0x76dc95c0) at 
> ../../gcc/gcc/fold-const.cc:14165
> #12 0x0094068c in c_expr_sizeof_expr (loc=loc@entry=201632, expr=...)
> at ../../gcc/gcc/tree.h:3771
> #13 0x0097f06c in c_parser_sizeof_expression (parser=)
> at ../../gcc/gcc/c/c-parser.cc:9932
>
>
> I hope this explains what's happening.  The size_binop_loc call is a bit of a 
> red
> herring that returns the same tree it is given (as TYPE_PRECISION 
> (char_type_node)
> == BITS_PER_UNIT), so it's the "TYPE_SIZE_UNIT (type)" which needs to be 
> checked
> for the embedded VAR_DECL with a TREE_TYPE of error_mark_node.
>
> As Andrew Pinski writes in comment #3, this one is trickier than average.
>
> A more comprehensive fix might be to write deep_error_operand_p which does
> more of a tree traversal checking error_operand_p within the unary and binary
> operators of an expression tree.
>
> Please let me know what you think/recommend.
> Best regards,
> Roger
> --
>
> > -Original Message-
> > From: Richard Biener 
> > Sent: 30 April 2024 08:38
> > To: Roger Sayle 
> > Cc: gcc-patches@gcc.gnu.org
> > Subject: Re: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.
> >
> > On Tue, Apr 30, 2024 at 1:06 AM Roger Sayle 
> > wrote:
> > >
> > >
> > > This patch solves another ICE-after-error problem in the C family
> > > front-ends.  Upon a conflicting type redeclaration, the ambiguous type
> > > is poisoned with an error_mark_node to indicate to the middle-end that
> > > the type is suspect, but care has to be taken by the front-end to
> > > avoid passing these malformed trees into the middle-end during error
> > > recovery. In this case, a var_decl with a poisoned type appears within
> > > a sizeof() expression (wrapped in NOP_EXPR) which causes problems.
> > >
> > > This revision of the patch tests seen_error() to avoid tree traversal
> > > (STRIP_NOPs) in the most common case that an error hasn't occurred.
> > > Both this version (and an earlier revision that didn't test
> > > seen_error) have survived bootstrap and regression testing on 
> > > x86_64-pc-linux-
> > gnu.
> > > As a consolation, this code also contains a minor performance
> > > improvement, by avoiding trying to create (and folding away) a
> > > CEIL_DIV_EXPR in the common case that "char" is a single-byte.  The
> > > current code relies on the middle-end's tree folding to recognize that
> > > CEIL_DIV_EXPR of integer_one_node is a no-op, that can be optimized away.
> > >
> > > Ok for mainline?
> >
> > Where does it end up ICEing?  I see size_binop_loc 

Re: [PATCH 1/1] gcc-14: document P1689R5 scanning output support

2024-04-30 Thread Jonathan Wakely

On 20/11/23 11:22 -0500, Ben Boeckel wrote:

---
htdocs/gcc-14/changes.html | 11 +++
1 file changed, 11 insertions(+)

diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index 7278f753..b506eeb1 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -112,6 +112,17 @@ a work-in-progress.
  

  
+  C++ module scanning for named modules is now available:
+
+  https://wg21.link/P1689R5";>P1689R5, Format for
+  describing dependencies of source files.
+  
+  The -fdeps-format=, -fdeps-file=, and
+  -fdeps=target= flags may be used to generate P1689 output


This should be -fdeps-target= not -fdeps=target=.



+  (the p1689r5 format is the only available format today).


I wish the option was more descriptive than "p1689r5", which nobody is
going to remember (but I assume we don't actually need to specify it
explicitly since it's the only supported format).


+  
+


Do we need a list for this item? It seems a bit weird that the first
list item is just the paper  How about just a single paragraph?

C++ module scanning for named modules is now available, based on the
format described in https://wg21.link/P1689R5";>P1689R5,
Format for describing dependencies of source files. The
-fdeps-format=, -fdeps-file=, and
-fdeps-target= flags may be used to generate dependency
information. In GCC 14 p1689r5 is the only valid argument
for -fdeps-format=.



+  


Runtime Library (libstdc++)
--
2.42.0





Re: [PATCH][Backport][GCC13] match.pd: Only merge truncation with conversion for -fno-signed-zeros

2024-04-30 Thread Richard Biener
On Mon, Apr 29, 2024 at 5:12 PM Joe Ramsay  wrote:
>
> This optimisation does not honour signed zeros, so should not be
> enabled except with -fno-signed-zeros.
>
> Cherry-pick of 7dd3b2b09cbeb6712ec680a0445cb0ad41070423.
>
> Applies cleanly on releases/gcc-13, regression-tested with no new
> failures.
>
> OK for backport to GCC 13? If so, please commit for me as I do not
> have commit rights in GCC.

I've pushed to 12 and 13.

Richard.

> Thanks,
> Joe
>
> gcc/ChangeLog:
>
> * match.pd: Fix truncation pattern for -fno-signed-zeroes
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/no_merge_trunc_signed_zero.c: New test.
> ---
>  gcc/match.pd  |  1 +
>  .../aarch64/no_merge_trunc_signed_zero.c  | 24 +++
>  2 files changed, 25 insertions(+)
>  create mode 100644 
> gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 47e48fa2ca5..dc34e7ead9f 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4188,6 +4188,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  (simplify
> (float (fix_trunc @0))
> (if (!flag_trapping_math
> +   && !HONOR_SIGNED_ZEROS (type)
> && types_match (type, TREE_TYPE (@0))
> && direct_internal_fn_supported_p (IFN_TRUNC, type,
>   OPTIMIZE_FOR_BOTH))
> diff --git a/gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c 
> b/gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c
> new file mode 100644
> index 000..b2c93e55567
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/no_merge_trunc_signed_zero.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-trapping-math -fsigned-zeros" } */
> +
> +#include 
> +
> +float
> +f1 (float x)
> +{
> +  return (int) rintf(x);
> +}
> +
> +double
> +f2 (double x)
> +{
> +  return (long) rint(x);
> +}
> +
> +/* { dg-final { scan-assembler "frintx\\ts\[0-9\]+, s\[0-9\]+" } } */
> +/* { dg-final { scan-assembler "cvtzs\\ts\[0-9\]+, s\[0-9\]+" } } */
> +/* { dg-final { scan-assembler "scvtf\\ts\[0-9\]+, s\[0-9\]+" } } */
> +/* { dg-final { scan-assembler "frintx\\td\[0-9\]+, d\[0-9\]+" } } */
> +/* { dg-final { scan-assembler "cvtzs\\td\[0-9\]+, d\[0-9\]+" } } */
> +/* { dg-final { scan-assembler "scvtf\\td\[0-9\]+, d\[0-9\]+" } } */
> +
> --
> 2.27.0
>


RE: [PATCH v3] DSE: Fix ICE after allow vector type in get_stored_val

2024-04-30 Thread Li, Pan2
Linaro reports one build failure for arm but works well in aarch64.

/home/tcwg-build/workspace/tcwg_gnu_2/abe/snapshots/gcc.git~master/gcc/dse.cc:1951:45:
 error: 'REGMODE_NATURAL_SIZE' was not declared in this scope

Looks only part of backend implemented REGMODE_NATURAL_SIZE, then reference 
this macro here may not be a good idea.

gcc/config/i386/i386.cc:20835:/* Implement REGMODE_NATURAL_SIZE(MODE).  */
gcc/config/i386/i386.h:1050:#define REGMODE_NATURAL_SIZE(MODE) 
ix86_regmode_natural_size (MODE)
gcc/config/aarch64/aarch64.cc:2479:/* Implement REGMODE_NATURAL_SIZE.  */
gcc/config/aarch64/aarch64.h:1505:#define REGMODE_NATURAL_SIZE(MODE) 
aarch64_regmode_natural_size (MODE)
gcc/config/riscv/riscv.h:1212:#define REGMODE_NATURAL_SIZE(MODE) 
riscv_regmode_natural_size (MODE)
gcc/config/riscv/riscv.cc:10241:/* Implement REGMODE_NATURAL_SIZE.  */
gcc/config/sparc/sparc.h:706:#define REGMODE_NATURAL_SIZE(MODE) 
sparc_regmode_natural_size (MODE)

Pan


-Original Message-
From: Li, Pan2  
Sent: Tuesday, April 30, 2024 3:17 PM
To: gcc-patches@gcc.gnu.org
Cc: jeffreya...@gmail.com; juzhe.zh...@rivai.ai; kito.ch...@gmail.com; Liu, 
Hongtao ; richard.guent...@gmail.com; Li, Pan2 

Subject: [PATCH v3] DSE: Fix ICE after allow vector type in get_stored_val

From: Pan Li 

We allowed vector type for get_stored_val when read is less than or
equal to store in previous.  Unfortunately,  the valididate_subreg
treats the vector type's size is less than vector register as
invalid.  Then we will have ICE here.

This patch would like to fix it by filter-out the invalid type size,
and make sure the subreg is valid for both the read_mode and store_mode
before perform the real gen_lowpart.

The below test suites are passed for this patch:

* The x86 bootstrap test.
* The x86 regression test.
* The riscv rv64gcv regression test.
* The riscv rv64gc regression test.
* The aarch64 regression test.

gcc/ChangeLog:

* dse.cc (get_stored_val): Make sure read_mode size is greater
than or equal to the vector register size before gen_lowpart.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr111720-10.c: Adjust asm checker.
* gcc.target/riscv/rvv/base/bug-6.c: New test.

Signed-off-by: Pan Li 
---
 gcc/dse.cc|  4 +++-
 .../gcc.target/riscv/rvv/base/bug-6.c | 22 +++
 .../gcc.target/riscv/rvv/base/pr111720-10.c   |  2 +-
 3 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c

diff --git a/gcc/dse.cc b/gcc/dse.cc
index edc7a1dfecf..258d2ccc299 100644
--- a/gcc/dse.cc
+++ b/gcc/dse.cc
@@ -1946,7 +1946,9 @@ get_stored_val (store_info *store_info, machine_mode 
read_mode,
 copy_rtx (store_info->const_rhs));
   else if (VECTOR_MODE_P (read_mode) && VECTOR_MODE_P (store_mode)
 && known_le (GET_MODE_BITSIZE (read_mode), GET_MODE_BITSIZE (store_mode))
-&& targetm.modes_tieable_p (read_mode, store_mode))
+&& targetm.modes_tieable_p (read_mode, store_mode)
+/* It's invalid in validate_subreg if read_mode size is < reg natural.  */
+&& known_ge (GET_MODE_SIZE (read_mode), REGMODE_NATURAL_SIZE (read_mode)))
 read_reg = gen_lowpart (read_mode, copy_rtx (store_info->rhs));
   else
 read_reg = extract_low_bits (read_mode, store_mode,
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c
new file mode 100644
index 000..5bb00b8f587
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c
@@ -0,0 +1,22 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize" } */
+
+struct A { float x, y; };
+struct B { struct A u; };
+
+extern void bar (struct A *);
+
+float
+f3 (struct B *x, int y)
+{
+  struct A p = {1.0f, 2.0f};
+  struct A *q = &x[y].u;
+
+  __builtin_memcpy (&q->x, &p.x, sizeof (float));
+  __builtin_memcpy (&q->y, &p.y, sizeof (float));
+
+  bar (&p);
+
+  return x[y].u.x + x[y].u.y;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
index 215eb99ce0f..ee6b2ccf7ad 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr111720-10.c
@@ -15,4 +15,4 @@ vbool4_t test () {
 }
 
 /* { dg-final { scan-assembler-not {vle[0-9]+\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } 
} */
-/* { dg-final { scan-assembler-not {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} } 
} */
+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*[0-9]+\(sp\)} 
1 }  } */
-- 
2.34.1



Re: [PATCH] testsuite: gm2: Remove timeout overrides [PR114886]

2024-04-30 Thread Gaius Mulley
Rainer Orth  writes:

> A large number of gm2 tests are timing out even on current Solaris/SPARC
> systems.  As detailed in the PR, the problem is that the gm2 testsuite
> artificially lowers many timeouts way below the DejaGnu default of 300
> seconds, often as short as 10 seconds.  The problem lies both in the
> values (they may be appropriate for some targets, but too low for
> others, especially under high load) and the fact that it uses absolute
> values, overriding e.g. settings from a build-wide site.exp.
>
> Therefore this patch removes all those overrides, restoring the
> defaults.
>
> Tested on sparc-sun-solaris2.11 (where all the previous timeouts are
> gone) and i386-pc-solaris2.11.
>
> Ok for trunk and the gcc-14 branch once GCC 14.1.0 has been released?

yes this looks good to me please apply.  Thanks for the rationale
described in the PR.  As suggested, locally changing site.exp is more
appropriate should the need arise.  The dg-timeout code was added to
speed up testing/development of (a deadlocking) RTco.cc (which has
since been fixed)

regards,
Gaius


Re: [PATCH] testsuite: gm2: Remove timeout overrides [PR114886]

2024-04-30 Thread Rainer Orth
Hi Gaius,

> yes this looks good to me please apply.  Thanks for the rationale

done for trunk.  I guess it's ok to apply to the gcc-14 branch after the
release and some soak time?

> described in the PR.  As suggested, locally changing site.exp is more
> appropriate should the need arise.  The dg-timeout code was added to
> speed up testing/development of (a deadlocking) RTco.cc (which has
> since been fixed)

Sure: while I've used increased global timeouts in the distant past
(IRIX, old and slow SPARC boxes), it certainly works both ways.

Thanks.
Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [PATCH] decay vect tests from run to link for pr95401

2024-04-30 Thread Christophe Lyon
Hi Alexandre,

On Tue, 30 Apr 2024 at 01:31, Alexandre Oliva  wrote:
>
> On Apr 22, 2024, Richard Biener  wrote:
>
> >> Regstrapped on x86_64-linux-gnu and ppc64el-linux-gnu.  Also tested with
> >> gcc-13 on ppc64-vx7r2 and ppc-vx7r2.  Ok to install?
>
> > That makes sense.  OK
>
> >> for  gcc/testsuite/ChangeLog
> >>
> >> * lib/target-supports.exp (check_vect_support_and_set_flags):
> >> Decay to link rather than compile.
>
> Alas, linking may fail because of an incompatible libc, as reported by
> Linaro with a link to their issue GNU-1206 (I'm not posting the link to
> the fully-Javascrippled Jira web page; it shows nothing useful, and I
> can't post feedback there) and to
> https://ci.linaro.org/job/tcwg_gnu_embed_check_gcc--master-thumb_m7_hard_eabi-build/10/artifact/artifacts/00-sumfiles/
> (where I could get useful information)
>
> I'm reverting the patch, and I'll see about some alternate approach that
> can accommodate this scenario after I return from LibrePlanet.
>

Indeed, that's another instance of the tricky multilibs configuration issues.
In this case:
- we configure GCC: --disable-multilib --with-mode=thumb
--with-cpu=cortex-m7 --with-float=hard --target=arm-eabi
(we disable multilibs to save build time)
- we run the tests with
qemu/-mthumb/-march=armv7e-m+fp.dp/-mtune=cortex-m7/-mfloat-abi=hard/-mfpu=auto
which matches the GCC configuration flags,
but the vect.exp tests add -mfpu=neon -mfloat-abi=softfp -march=armv7-a
and link fails because the toolchain does not support softfp libs

HTH

Thanks,

Christophe

> --
> Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
>Free Software Activist   GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive


Re: [PATCH] libgm2: re-generate with autoreconf

2024-04-30 Thread Gaius Mulley
Christophe Lyon  writes:

> On Tue, 30 Apr 2024 at 04:01, Simon Marchi  wrote:
>>
>> I get a diff when running "autoreconf" in this directory.  I think that
>> the current state is erroneous: it appears to have been generated using
>>
>> aclocal -I ../config -I ..
>>
>> even though configure.ac and Makefile.am list the include flag in the
>> reverse order:
>>
>>aclocal -I .. -I ../config
>>
>> Running "autoreconf" uses the latter order, so I think that's the
>> "right" output.
>>
>> No functional difference expected.
>
> Thanks, this matches what I noticed.
> I'm not a maintainer, so I cannot approve, but a minor remark: in GCC
> we still need a ChangeLog entry in the commit message.
>
> Christophe

many thanks for spotting this bug, lgtm,

regards,
Gaius


[pushed] wwwdocs: modula2 update for changes.html, index.html, readings.html and frontends.html

2024-04-30 Thread Gaius Mulley


Pushed the commit c74a573fa888f3970b6b38d57020f0160e49e58a

   frontends.html: Mention modula-2 was merged during gcc-13.
   gcc-14/changes.html: New section heading for modula-2 and populate.
   index.html: Add modula-2 to the list of languages supported by GCC.
   readings.html (Modula 2 information): New section containing PIM2, PIM4
   and ISO standard links.

regards,
Gaius



diff --git a/htdocs/frontends.html b/htdocs/frontends.html
index d47b56b6..2dec80c9 100644
--- a/htdocs/frontends.html
+++ b/htdocs/frontends.html
@@ -43,8 +43,8 @@ has a back end that generates assembler directly, using the 
GCC back end.
 http://www.nongnu.org/gm2/";>GNU Modula-2 implements
 the ISO/IEC 10514-1, PIM2, PIM3 and PIM4 dialects of the language.
 The compiler is operational with GCC 10, GCC 11, and GCC 12 (on
-GNU/Linux x86 systems).  The front end is now in the GCC development
-trunk (GCC 13).  It is mostly written in Modula-2 and includes a
+GNU/Linux x86 systems).  The front end was merged into the GCC tree
+during GCC 13.  It is mostly written in Modula-2 and includes a
 bootstrap tool which translates Modula-2 into C/C++.
 
 Modula-3 (for links see 
 
 
 
+Modula-2
+
+  The automatic dependency generation options: -M,
+-MD, -MF,
+-MMD, -MP, -MQ and
+-MT have been implemented in the compiler.
+  
+  The -Wcase-enum
+and -Wuninit-variable-checking= options have
+been implemented to provide compile time warnings against
+missing case clauses and uninitialized variables respectively.
+  
+
+
 
 libgccjit
 
diff --git a/htdocs/index.html b/htdocs/index.html
index 7eac5eab..d80ef5d7 100644
--- a/htdocs/index.html
+++ b/htdocs/index.html
@@ -19,7 +19,7 @@
 C,
 C++,
 Objective-C, Fortran,
-Ada, Go, and D, as well as libraries for these languages (libstdc++,...).
+Ada, Go, D and Modula-2 as well as libraries for these languages 
(libstdc++,...).
 GCC was originally written as the compiler for the http://www.gnu.org/gnu/thegnuproject.html";>GNU operating system.
 The GNU system was developed to be 100% free software, free in the sense
diff --git a/htdocs/readings.html b/htdocs/readings.html
index ee77d969..0f6032c2 100644
--- a/htdocs/readings.html
+++ b/htdocs/readings.html
@@ -559,6 +559,18 @@ names.
 
 
 
+Modula 2 information
+
+
+  https://www.research-collection.ethz.ch/handle/20.500.11850/68683";>Programming
+  in Modula-2 (Edition 2)
+  https://freepages.modula2.org/report4/modula-2.html";>Programming
+  in Modula-2 (Edition 4)
+  http://sc22wg13.twi.tudelft.nl";>ISO Modula-2 standards
+  (base language, OO and generic language extensions)
+
+
+
 Modula 3 information
 
 


Re: [PATCH] testsuite: gm2: Remove timeout overrides [PR114886]

2024-04-30 Thread Gaius Mulley
Rainer Orth  writes:

> Hi Gaius,
>
>> yes this looks good to me please apply.  Thanks for the rationale
>
> done for trunk.  I guess it's ok to apply to the gcc-14 branch after the
> release and some soak time?

many thanks - and yes certainly also to gcc-14 (after an appropriate
amount of delay),

regards,
Gaius


Re: [PATCH v4 2/3] [RFC] ifcvt: Allow more operations in multiple set if conversion

2024-04-30 Thread Manolis Tsamis
On Thu, Apr 25, 2024 at 2:40 AM Hans-Peter Nilsson  wrote:
>
> On Tue, 23 Apr 2024, Manolis Tsamis wrote:
> > diff --git a/gcc/testsuite/gcc.target/aarch64/ifcvt_multiple_sets_arithm.c 
> > b/gcc/testsuite/gcc.target/aarch64/ifcvt_multiple_sets_arithm.c
> ...
> > +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through 
> > noce_convert_multiple_sets" 6 "ce1" } } */
> > \ No newline at end of file
>
> This and the other new test-case both miss a newline at the end
> of the file.
>
Thanks, I will fix this.
I'm waiting for potential feedback in the rest of the series before
re-submitting this.

Manolis

> brgds, H-P


[PATCH v3 0/4]Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Qing Zhao
Hi,

This is the 3rd version for 
Allow flexible array members in unions and alone in structures [PR53548]

(for your reference, the 1st version is at:
https://gcc.gnu.org/pipermail/gcc-patches/2024-April/649737.html
The 2nd version is at:
https://gcc.gnu.org/pipermail/gcc-patches/2024-April/650019.html)

compared to the 2nd version, the major difference are:

A. Add two testing cases for _bos per Sid's comments;
B. One update to the C FE routine "add_flexible_array_elts_to_size"
   to handle the cases when the declaration is union.
C. One update the the C++ FE routine "layout_var_decl" to handle
   the cases when the declaratin is a union with a flexible array
   member initializer.

All the above new change is included in the new 4th patch.

Review needed:

   C++ FE changes (in Patch 2 and new Patch 4);
   Middle-end changes (in Patch 2);
   New C FE change (in new Patch 4);
   New testing cases for _bos (in new Patch 4);

Approval status:

   All other changes (C FE and documentation and related testing cases)
   have been approved with minor updates.

The patch set includes:
 1. Documentation change.
Allow flexible array members in unions and alone in structures
[PR53548]
 2. C and C++ FE changes to support flexible array members in unions and
   alone in structures.
Adjust testcases for flexible array member in union and alone in
   structure extension.
 3. Add testing cases for flexible array members in unions and alone in
   structures.
 4. Update the C FE routine "add_flexible_array_elts_to_size" C++ FE
   routine "layout_var_decl"  to handle the cases when the DECL is
   union.
Add testing cvases to test the _bos for FAM in union and alone in
   structures.

bootstrapped and regression tested on both x86 and aarch64, no issue.

Okay for GCC15?

thanks.

Qing


[PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Qing Zhao
The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago around 2012
for supporting several practical cases including glibc.

A GCC PR has been opened for such request at that time:

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

However, this PR was closed as WONTFIX around 2015 due to the following reason:

"there is an existing extension that makes the requested functionality possible"
i.e GCC fully supported that the zero-length array can be in a union or alone
in a structure for a long time. (though I didn't see any official documentation
on such extension)

It's reasonable to close PR53548 at that time since zero-length array extension
can be used for such purpose.

However, since GCC13, in order to improve the C/C++ security, we introduced
-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.

Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone in structs
are common code patterns in active use by the Linux kernel (and other projects).

For example, these do not error by default with GCC:

union one {
  int a;
  int b[0];
};

union two {
  int a;
  struct {
struct { } __empty;
int b[];
  };
};

But these do:

union three {
  int a;
  int b[];
};

struct four {
  int b[];
}

Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428

GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.

gcc/ChangeLog:

* doc/extend.texi: Add documentation for Flexible Array Members in
Unions and Flexible Array Members alone in Structures.
---
 gcc/doc/extend.texi | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length:: Zero-length arrays.
 * Empty Structures::Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible 
Array Members.
 * Variable Length:: Arrays whose length is computed at run time.
 * Variadic Macros:: Macros with a variable number of arguments.
 * Escaped Newlines::Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures 
are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 
+@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of
+such union is zero.
+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.
+
 @node Variable Length
 @section Arrays of Variable Length
 @cindex variable-length arrays
-- 
2.31.1



[PATCH v3 2/4] C and C++ FE changes

2024-04-30 Thread Qing Zhao
 to support flexible array members
 in unions and alone in structures. Adjust testcases for flexible array member
 in union and alone in structure extension.

gcc/c/ChangeLog:

* c-decl.cc (finish_struct): Change errors to pedwarns for the cases
flexible array members in union or alone in structures.

gcc/cp/ChangeLog:

* class.cc (diagnose_flexarrays): Change error to pdewarn for the case
flexible array members alone in structures.
* decl.cc (grokdeclarator): Change error to pdewarn for the case
flexible array members in unions.

gcc/ChangeLog:

* stor-layout.cc (place_union_field): Use zero sizes for flexible array
member fields.

gcc/testsuite/ChangeLog:

* c-c++-common/builtin-clear-padding-3.c: Adjust testcase.
* g++.dg/ext/flexary12.C: Likewise.
* g++.dg/ext/flexary19.C: Likewise.
* g++.dg/ext/flexary2.C: Likewise.
* g++.dg/ext/flexary3.C: Likewise.
* g++.dg/ext/flexary36.C: Likewise.
* g++.dg/ext/flexary4.C: Likewise.
* g++.dg/ext/flexary5.C: Likewise.
* g++.dg/ext/flexary8.C: Likewise.
* g++.dg/torture/pr64280.C: Likewise.
* gcc.dg/20050620-1.c: Likewise.
* gcc.dg/940510-1.c: Likewise.
---
 gcc/c/c-decl.cc   | 16 ++
 gcc/cp/class.cc   | 11 ++--
 gcc/cp/decl.cc|  7 ++-
 gcc/stor-layout.cc|  9 +++-
 .../c-c++-common/builtin-clear-padding-3.c| 10 ++--
 gcc/testsuite/g++.dg/ext/flexary12.C  |  6 +--
 gcc/testsuite/g++.dg/ext/flexary19.C  | 42 +++
 gcc/testsuite/g++.dg/ext/flexary2.C   |  2 +-
 gcc/testsuite/g++.dg/ext/flexary3.C   |  2 +-
 gcc/testsuite/g++.dg/ext/flexary36.C  |  2 +-
 gcc/testsuite/g++.dg/ext/flexary4.C   | 54 +--
 gcc/testsuite/g++.dg/ext/flexary5.C   |  4 +-
 gcc/testsuite/g++.dg/ext/flexary8.C   |  8 +--
 gcc/testsuite/g++.dg/torture/pr64280.C|  2 +-
 gcc/testsuite/gcc.dg/20050620-1.c |  2 +-
 gcc/testsuite/gcc.dg/940510-1.c   |  4 +-
 16 files changed, 91 insertions(+), 90 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 345090dae38b..947f3cd589eb 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9471,11 +9471,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
   if (flexible_array_member_type_p (TREE_TYPE (x)))
{
  if (TREE_CODE (t) == UNION_TYPE)
-   {
- error_at (DECL_SOURCE_LOCATION (x),
-   "flexible array member in union");
- TREE_TYPE (x) = error_mark_node;
-   }
+   pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+"flexible array member in union is a GCC extension");
  else if (!is_last_field)
{
  error_at (DECL_SOURCE_LOCATION (x),
@@ -9483,12 +9480,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
  TREE_TYPE (x) = error_mark_node;
}
  else if (!saw_named_field)
-   {
- error_at (DECL_SOURCE_LOCATION (x),
-   "flexible array member in a struct with no named "
-   "members");
- TREE_TYPE (x) = error_mark_node;
-   }
+   pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+"flexible array member in a struct with no named "
+"members is a GCC extension");
}
 
   if (pedantic && TREE_CODE (t) == RECORD_TYPE
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 5f258729940b..0c8afb72550f 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -7624,6 +7624,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
   bool diagd = false;
 
   const char *msg = 0;
+  const char *msg_fam = 0;
 
   if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
 {
@@ -7649,15 +7650,19 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
   if (fmem->after[0])
msg = G_("flexible array member %qD not at end of %q#T");
   else if (!fmem->first)
-   msg = G_("flexible array member %qD in an otherwise empty %q#T");
+   msg_fam = G_("flexible array member %qD in an otherwise"
+" empty %q#T is a GCC extension");
 
-  if (msg)
+  if (msg || msg_fam)
{
  location_t loc = DECL_SOURCE_LOCATION (fmem->array);
  diagd = true;
 
  auto_diagnostic_group d;
- error_at (loc, msg, fmem->array, t);
+ if (msg)
+   error_at (loc, msg, fmem->array, t);
+ else
+   pedwarn (loc, OPT_Wpedantic, msg_fam, fmem->array, t);
 
  /* In the unlikely event that the member following the flexible
 array member is declared in a different class, or the member
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 

[PATCH v3 3/4] Add testing cases for flexible array members in unions and alone in structures.

2024-04-30 Thread Qing Zhao
gcc/testsuite/ChangeLog:

* c-c++-common/fam-in-union-alone-in-struct-1.c: New testcase.
* c-c++-common/fam-in-union-alone-in-struct-2.c: New testcase.
* c-c++-common/fam-in-union-alone-in-struct-3.c: New testcase.
---
 .../fam-in-union-alone-in-struct-1.c  | 52 +++
 .../fam-in-union-alone-in-struct-2.c  | 51 ++
 .../fam-in-union-alone-in-struct-3.c  | 36 +
 3 files changed, 139 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-1.c
 create mode 100644 gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-2.c
 create mode 100644 gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-3.c

diff --git a/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-1.c 
b/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-1.c
new file mode 100644
index ..7d4721aa95ac
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-1.c
@@ -0,0 +1,52 @@
+/* testing the correct usage of flexible array members in unions 
+   and alone in structures.  */
+/* { dg-do run} */
+/* { dg-options "-Wpedantic" } */
+
+union with_fam_1 {
+  int a;
+  int b[];  /* { dg-warning "flexible array member in union is a GCC 
extension" } */
+};
+
+union with_fam_2 {
+  char a;
+  int b[];  /* { dg-warning "flexible array member in union is a GCC 
extension" } */
+};
+
+union with_fam_3 {
+  char a[];  /* { dg-warning "flexible array member in union is a GCC 
extension" } */
+  /* { dg-warning "in an otherwise empty" "" { target c++ } .-1 } */
+  int b[];  /* { dg-warning "flexible array member in union is a GCC 
extension" } */
+};
+
+struct only_fam {
+  int b[];
+  /* { dg-warning "in a struct with no named members" "" { target c } .-1 } */
+  /* { dg-warning "in an otherwise empty" "" { target c++ } .-2 } */
+  /* { dg-warning "forbids flexible array member" "" { target c++ } .-3 } */
+};
+
+struct only_fam_2 {
+  unsigned int : 2;
+  unsigned int : 3;
+  int b[];
+  /* { dg-warning "in a struct with no named members" "" { target c } .-1 } */
+  /* { dg-warning "in an otherwise empty" "" { target c++ } .-2 } */
+  /* { dg-warning "forbids flexible array member" "" { target c++ } .-3 } */
+};
+
+int main ()
+{
+  if (sizeof (union with_fam_1) != sizeof (int))
+__builtin_abort ();
+  if (sizeof (union with_fam_2) != __alignof__ (int))
+__builtin_abort ();
+  if (sizeof (union with_fam_3) != 0)
+__builtin_abort ();
+  if (sizeof (struct only_fam) != 0)
+__builtin_abort ();
+  if (sizeof (struct only_fam_2) != sizeof (int))
+__builtin_abort ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-2.c 
b/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-2.c
new file mode 100644
index ..3743f9e7dac5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-2.c
@@ -0,0 +1,51 @@
+/* testing the correct usage of flexible array members in unions 
+   and alone in structures: initialization  */
+/* { dg-do run} */
+/* { dg-options "-O2" } */
+
+union with_fam_1 {
+  int a;
+  int b[]; 
+} with_fam_1_v = {.b = {1, 2, 3, 4}};
+
+union with_fam_2 {
+  int a;
+  char b[];  
+} with_fam_2_v = {.a = 0x1f2f3f4f};
+
+union with_fam_3 {
+  char a[];  
+  int b[];  
+} with_fam_3_v = {.b = {0x1f2f3f4f, 0x5f6f7f7f}};
+
+struct only_fam {
+  int b[]; 
+} only_fam_v = {{7, 11}};
+
+struct only_fam_2 {
+  unsigned int : 2;
+  unsigned int : 3;
+  int b[]; 
+} only_fam_2_v = {{7, 11}};
+
+int main ()
+{
+  if (with_fam_1_v.b[3] != 4
+  || with_fam_1_v.b[0] != 1)
+__builtin_abort ();
+  if (with_fam_2_v.b[3] != 0x1f
+  || with_fam_2_v.b[0] != 0x4f)
+__builtin_abort ();
+  if (with_fam_3_v.a[0] != 0x4f
+  || with_fam_3_v.a[7] != 0x5f)
+__builtin_abort ();
+  if (only_fam_v.b[0] != 7
+  || only_fam_v.b[1] != 11)
+__builtin_abort ();
+  if (only_fam_2_v.b[0] != 7
+  || only_fam_2_v.b[1] != 11)
+__builtin_abort ();
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-3.c 
b/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-3.c
new file mode 100644
index ..dd36fa01306d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-3.c
@@ -0,0 +1,36 @@
+/* testing the correct usage of flexible array members in unions 
+   and alone in structures.  */
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+union with_fam_1 {
+  int a;
+  int b[];  /* { dg-error "flexible array member in union is a GCC extension" 
} */
+};
+
+union with_fam_2 {
+  char a;
+  int b[];  /* { dg-error "flexible array member in union is a GCC extension" 
} */
+};
+
+union with_fam_3 {
+  char a[];  /* { dg-error "flexible array member in union is a GCC extension" 
} */
+  /* { dg-error "in an otherwise empty" "" { target c++ } .-1 } */
+  int b[];  /* { dg-error "flexible array member in union is a GCC extension" 
} */
+};

[PATCH v3 4/4] Update the C FE routine "add_flexible_array_elts_to_size" C++ FE routine "layout_var_decl" to handle the cases when the DECL is union.

2024-04-30 Thread Qing Zhao
Add testing cases to test the _bos for flexible array members in unions
or alone in structures.

gcc/c/ChangeLog:

* c-decl.cc (add_flexible_array_elts_to_size): Handle the cases
when the DECL is union.

gcc/cp/ChangeLog:

* decl.cc (layout_var_decl): Handle the cases when the DECL is
union with a flexible array member initializer.

gcc/testsuite/ChangeLog:

* c-c++-common/fam-in-union-alone-in-struct-bos-1.c: New test.
* c-c++-common/fam-in-union-alone-in-struct-bos.c: New test.
---
 gcc/c/c-decl.cc   | 32 +++--
 gcc/cp/decl.cc| 33 --
 .../fam-in-union-alone-in-struct-bos-1.c  | 66 +++
 .../fam-in-union-alone-in-struct-bos.c| 45 +
 4 files changed, 162 insertions(+), 14 deletions(-)
 create mode 100644 
gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-bos-1.c
 create mode 100644 
gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-bos.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 947f3cd589eb..59302c5cfb1f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5337,9 +5337,9 @@ zero_length_array_type_p (const_tree type)
 }
 
 /* INIT is a constructor that forms DECL's initializer.  If the final
-   element initializes a flexible array field, add the size of that
-   initializer to DECL's size.  */
-
+   element initializes a flexible array field, adjust the size of the
+   DECL with the initializer based on whether the DECL is a union or
+   a structure.  */
 static void
 add_flexible_array_elts_to_size (tree decl, tree init)
 {
@@ -5348,15 +5348,33 @@ add_flexible_array_elts_to_size (tree decl, tree init)
   if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
 return;
 
+  bool is_decl_type_union = (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
+
   elt = CONSTRUCTOR_ELTS (init)->last ().value;
   type = TREE_TYPE (elt);
   if (flexible_array_member_type_p (type))
 {
   complete_array_type (&type, elt, false);
-  DECL_SIZE (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
-  DECL_SIZE_UNIT (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type));
+  /* For a structure, add the size of the initializer to the DECL's
+size.  */
+  if (!is_decl_type_union)
+   {
+ DECL_SIZE (decl)
+   = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
+ DECL_SIZE_UNIT (decl)
+   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
+ TYPE_SIZE_UNIT (type));
+   }
+  /* For a union, the DECL's size is the maximum of the current size
+and the size of the initializer.  */
+  else
+   {
+ DECL_SIZE (decl)
+   = size_binop (MAX_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
+ DECL_SIZE_UNIT (decl)
+   = size_binop (MAX_EXPR, DECL_SIZE_UNIT (decl),
+ TYPE_SIZE_UNIT (type));
+   }
 }
 }
 
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 9a91c6f80da1..0ea3ef165b66 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -6555,8 +6555,9 @@ layout_var_decl (tree decl)
}
 }
 
-  /* If the final element initializes a flexible array field, add the size of
- that initializer to DECL's size.  */
+  /* If the final element initializes a flexible array field, adjust
+ the size of the DECL with the initializer based on whether the
+ DECL is a union or a structure.  */
   if (type != error_mark_node
   && DECL_INITIAL (decl)
   && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR
@@ -6568,6 +6569,7 @@ layout_var_decl (tree decl)
   && tree_int_cst_equal (DECL_SIZE (decl), TYPE_SIZE (type)))
 {
   constructor_elt &elt = CONSTRUCTOR_ELTS (DECL_INITIAL (decl))->last ();
+  bool is_decl_type_union = (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
   if (elt.index)
{
  tree itype = TREE_TYPE (elt.index);
@@ -6577,11 +6579,28 @@ layout_var_decl (tree decl)
  && TREE_CODE (vtype) == ARRAY_TYPE
  && COMPLETE_TYPE_P (vtype))
{
- DECL_SIZE (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (vtype));
- DECL_SIZE_UNIT (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
- TYPE_SIZE_UNIT (vtype));
+ /* For a structure, add the size of the initializer to the DECL's
+size.  */
+ if (!is_decl_type_union)
+   {
+ DECL_SIZE (decl)
+   = size_binop (PLUS_EXPR, DECL_SIZE (decl),
+ TYPE_SIZE (vtype));
+ DECL_SIZE_UNIT (decl)
+   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
+ TYPE_SIZE_UNIT (vtype));
+   }
+ /* a union, the DECL's size is the maximum of the curren

Re: [PATCH] testsuite: Verify r0-r3 are extended with CMSE

2024-04-30 Thread Richard Earnshaw (lists)
On 27/04/2024 15:13, Torbjörn SVENSSON wrote:
> Add regression test to the existing zero/sign extend tests for CMSE to
> verify that r0, r1, r2 and r3 are properly extended, not just r0.
> 
> Test is done using -O0 to ensure the instructions are in a predictable
> order.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/arm/cmse/extend-param.c: Add regression test.
> 
> Signed-off-by: Torbjörn SVENSSON 
> ---
>  .../gcc.target/arm/cmse/extend-param.c| 20 ++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/testsuite/gcc.target/arm/cmse/extend-param.c 
> b/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
> index 01fac786238..b8b8ecbff56 100644
> --- a/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
> +++ b/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
> @@ -93,4 +93,22 @@ __attribute__((cmse_nonsecure_entry)) char boolSecureFunc 
> (bool index) {
>  return 0;
>return array[index];
>  
> -}
> \ No newline at end of file
> +}
> +
> +/*
> +**__acle_se_boolCharShortEnumSecureFunc:
> +**   ...
> +**   uxtbr0, r0
> +**   uxtbr1, r1
> +**   uxthr2, r2
> +**   uxtbr3, r3
> +**   ...
> +*/
> +__attribute__((cmse_nonsecure_entry,optimize(0))) char 
> boolCharShortEnumSecureFunc (bool a, unsigned char b, unsigned short c, enum 
> offset d) {
> +
> +  size_t index = a + b + c + d;
> +  if (index >= ARRAY_SIZE)
> +return 0;
> +  return array[index];
> +
> +}

Ok, but please can you add '-fshort-enums' to dg-options to ensure this test 
still behaves correctly if run with a different default (I missed that last 
time around).

R.


RE: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.

2024-04-30 Thread Roger Sayle
> On Tue, Apr 30, 2024 at 10:23 AM Roger Sayle 
> wrote:
> > Hi Richard,
> > Thanks for looking into this.
> >
> > It’s not the call to size_binop_loc (for CEIL_DIV_EXPR) that's
> > problematic, but the call to fold_convert_loc (loc, size_type_node, value) 
> > on line
> 4009 of c-common.cc.
> > At this point, value is (NOP_EXPR:sizetype (VAR_DECL:error_mark_node)).
> 
> I see.  Can we catch this when we build (NOP_EXPR:sizetype
> (VAR_DECL:error_mark_node))
> and instead have it "build" error_mark_node?

That's the tricky part.  At the point the NOP_EXPR is built the VAR_DECL's type
is valid.  It's later when this variable gets redefined with a conflicting type 
that
the shared VAR_DECL gets modified, setting its type to error_mark_node.
Mutating this shared node, then potentially introduces error_operand_p at
arbitrary places deep within an expression.  Fortunately, we only have to 
worry about this in the unusual/exceptional case that seen_error() is true.


> > Ultimately, it's the code in match.pd /* Handle cases of two
> > conversions in a row.  */ with the problematic line being (match.pd:4748):
> >   unsigned int inside_prec = element_precision (inside_type);
> >
> > Here inside_type is error_mark_node, and so tree type checking in
> > element_precision throws an internal_error.
> >
> > There doesn’t seem to be a good way to fix this in element_precision,
> > and it's complicated to reorganize the logic in match.pd's "with
> > clause" inside the (ocvt (icvt@1 @0)), but perhaps a (ocvt
> (icvt:non_error_type@1 @0))?
> >
> > The last place/opportunity the front-end could sanitize this operand
> > before passing the dubious tree to the middle-end is
> > c_sizeof_or_alignof_type (which alas doesn't appear in the backtrace due to
> inlining).
> >
> > #5  0x0227b0e9 in internal_error (
> > gmsgid=gmsgid@entry=0x249c7b8 "tree check: expected class %qs,
> > have %qs (%s) in %s, at %s:%d") at ../../gcc/gcc/diagnostic.cc:2232
> > #6  0x0081e32a in tree_class_check_failed (node=0x76c1ef30,
> > cl=cl@entry=tcc_type, file=file@entry=0x2495f3f "../../gcc/gcc/tree.cc",
> > line=line@entry=6795, function=function@entry=0x24961fe
> "element_precision")
> > at ../../gcc/gcc/tree.cc:9005
> > #7  0x0081ef4c in tree_class_check (__t=,
> __class=tcc_type,
> > __f=0x2495f3f "../../gcc/gcc/tree.cc", __l=6795,
> > __g=0x24961fe "element_precision") at ../../gcc/gcc/tree.h:4067
> > #8  element_precision (type=, type@entry=0x76c1ef30)
> > at ../../gcc/gcc/tree.cc:6795
> > #9  0x017f66a4 in generic_simplify_CONVERT_EXPR (loc=201632,
> > code=, type=0x76c3e7e0, _p0=0x76dc95c0)
> > at generic-match-6.cc:3386
> > #10 0x00c1b18c in fold_unary_loc (loc=201632, code=NOP_EXPR,
> > type=0x76c3e7e0, op0=0x76dc95c0) at
> > ../../gcc/gcc/fold-const.cc:9523
> > #11 0x00c1d94a in fold_build1_loc (loc=201632, code=NOP_EXPR,
> > type=0x76c3e7e0, op0=0x76dc95c0) at
> > ../../gcc/gcc/fold-const.cc:14165
> > #12 0x0094068c in c_expr_sizeof_expr (loc=loc@entry=201632,
> expr=...)
> > at ../../gcc/gcc/tree.h:3771
> > #13 0x0097f06c in c_parser_sizeof_expression (parser= out>)
> > at ../../gcc/gcc/c/c-parser.cc:9932
> >
> >
> > I hope this explains what's happening.  The size_binop_loc call is a
> > bit of a red herring that returns the same tree it is given (as
> > TYPE_PRECISION (char_type_node) == BITS_PER_UNIT), so it's the
> > "TYPE_SIZE_UNIT (type)" which needs to be checked for the embedded
> VAR_DECL with a TREE_TYPE of error_mark_node.
> >
> > As Andrew Pinski writes in comment #3, this one is trickier than average.
> >
> > A more comprehensive fix might be to write deep_error_operand_p which
> > does more of a tree traversal checking error_operand_p within the
> > unary and binary operators of an expression tree.
> >
> > Please let me know what you think/recommend.
> > Best regards,
> > Roger
> > --
> >
> > > -Original Message-
> > > From: Richard Biener 
> > > Sent: 30 April 2024 08:38
> > > To: Roger Sayle 
> > > Cc: gcc-patches@gcc.gnu.org
> > > Subject: Re: [C PATCH] PR c/109618: ICE-after-error from error_mark_node.
> > >
> > > On Tue, Apr 30, 2024 at 1:06 AM Roger Sayle
> > > 
> > > wrote:
> > > >
> > > >
> > > > This patch solves another ICE-after-error problem in the C family
> > > > front-ends.  Upon a conflicting type redeclaration, the ambiguous
> > > > type is poisoned with an error_mark_node to indicate to the
> > > > middle-end that the type is suspect, but care has to be taken by
> > > > the front-end to avoid passing these malformed trees into the
> > > > middle-end during error recovery. In this case, a var_decl with a
> > > > poisoned type appears within a sizeof() expression (wrapped in NOP_EXPR)
> which causes problems.
> > > >
> > > > This revision of the patch tests seen_error() to avoid tree
> > > > traversal
> > > > (STRIP_NOPs) in the most common case tha

Re: [PATCH] testsuite: Verify r0-r3 are extended with CMSE

2024-04-30 Thread Torbjorn SVENSSON




On 2024-04-30 17:11, Richard Earnshaw (lists) wrote:

On 27/04/2024 15:13, Torbjörn SVENSSON wrote:

Add regression test to the existing zero/sign extend tests for CMSE to
verify that r0, r1, r2 and r3 are properly extended, not just r0.

Test is done using -O0 to ensure the instructions are in a predictable
order.

gcc/testsuite/ChangeLog:

* gcc.target/arm/cmse/extend-param.c: Add regression test.

Signed-off-by: Torbjörn SVENSSON 
---
  .../gcc.target/arm/cmse/extend-param.c| 20 ++-
  1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/arm/cmse/extend-param.c 
b/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
index 01fac786238..b8b8ecbff56 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
@@ -93,4 +93,22 @@ __attribute__((cmse_nonsecure_entry)) char boolSecureFunc 
(bool index) {
  return 0;
return array[index];
  
-}

\ No newline at end of file
+}
+
+/*
+**__acle_se_boolCharShortEnumSecureFunc:
+** ...
+** uxtbr0, r0
+** uxtbr1, r1
+** uxthr2, r2
+** uxtbr3, r3
+** ...
+*/
+__attribute__((cmse_nonsecure_entry,optimize(0))) char 
boolCharShortEnumSecureFunc (bool a, unsigned char b, unsigned short c, enum 
offset d) {
+
+  size_t index = a + b + c + d;
+  if (index >= ARRAY_SIZE)
+return 0;
+  return array[index];
+
+}


Ok, but please can you add '-fshort-enums' to dg-options to ensure this test 
still behaves correctly if run with a different default (I missed that last 
time around).


Ok, I'll add that to extend-param.c. Do you want me to also add it to 
the extend-return.c test case?


Kind regards,
Torbjörn


[committed] [RISC-V] Improve floor, ceil & related operations for RISC-V

2024-04-30 Thread Jeff Law

This is almost exclusively Jivan's work.  His original post:



https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg336483.html





This patch is primarily meant to improve the code we generate for FP 
rounding such as ceil/floor.  It also addresses some unnecessary sign 
extensions in the same areas.


RISC-V's FP conversions have a bit of undesirable behavior that make 
them non-suitable as-is for ceil/floor and other related functions. 
These deficiencies are addressed in the Zfa extension, but there's no 
reason not to pick up a nice improvement when we can.


Basically we can still use the basic FP conversions for floor/ceil and 
friends when we don't care about inexact exceptions by checking for the 
special cases first, then emitting the conversion when the special cases 
don't apply.  That's still much faster than calling into glibc.


The redundant sign extensions are eliminated using the same trick Jivan 
added last year, just in a few more places ;-)


This eliminates roughly 10% of the dynamic instruction count for 
imagick.  But more importantly it's about a 17% performance improvement 
for that workload within spec.


This has been bootstrapped as well as regression tested in a cross 
environment.  It's also successfully built & run specint/specfp correctly.


Pushing to the trunk and the coordination branch momentarily.


Jeffgcc/
* config/riscv/iterators.md (fix_ops, fix_uns): New iterators.
(RINT, rint_pattern, rint_rm): Remove unused iterators.
* config/riscv/riscv-protos.h (get_fp_rounding_coefficient): Prototype.
* config/riscvriscv-v.cc (get_fp_rounding_coefficient): Externalize.
external linkage.
* config/riscv/riscv.md (UNSPEC_LROUND): Remove.
(fix_trunc2): Replace with ...
(_truncsi2): New expander & associated insn.
(_truncsi2_ext): New insn.
(_truncdi2): Likewise.
(l2): Replace with ...
(lrintsi2): New expander and associated insn.
(lrintsi2_ext), lrintdi2): New insns.
(2): Replace with
(lsi2): New expander and associated insn.
(lsi2_sext): New insn.
(ldi2): Likewise.
(2): New expander.

gcc/testsuite/
* gcc.target/riscv/fix.c: New test.
* gcc.target/riscv/round.c: New test.
* gcc.target/riscv/round_32.c: New test.
* gcc.target/riscv/round_64.c: New test.


diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index a7694137685..75e119e407a 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -196,6 +196,13 @@ (define_code_iterator clz_ctz_pcnt [clz ctz popcount])
 
 (define_code_iterator bitmanip_rotate [rotate rotatert])
 
+;; These code iterators allow the signed and unsigned fix operations to use
+;; the same template.
+(define_code_iterator fix_ops [fix unsigned_fix])
+
+(define_code_attr fix_uns [(fix "fix") (unsigned_fix "fixuns")])
+
+
 ;; ---
 ;; Code Attributes
 ;; ---
@@ -312,11 +319,6 @@ (define_code_attr bitmanip_insn [(smin "min")
 ;; Int Iterators.
 ;; ---
 
-;; Iterator and attributes for floating-point rounding instructions.
-(define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND])
-(define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")])
-(define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")])
-
 ;; Iterator and attributes for quiet comparisons.
 (define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
 (define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET 
"le")])
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 5d46a29d8b7..e5aebf3fc3d 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -711,6 +711,7 @@ bool gather_scatter_valid_offset_p (machine_mode);
 HOST_WIDE_INT estimated_poly_value (poly_int64, unsigned int);
 bool whole_reg_to_reg_move_p (rtx *, machine_mode, int);
 bool splat_to_scalar_move_p (rtx *);
+rtx get_fp_rounding_coefficient (machine_mode);
 }
 
 /* We classify builtin types into two classes:
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 814c5febabe..c9e0feebca6 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -4494,7 +4494,7 @@ vls_mode_valid_p (machine_mode vls_mode)
   All double floating point will be unchanged for ceil if it is
   greater than and equal to 4503599627370496.
  */
-static rtx
+rtx
 get_fp_rounding_coefficient (machine_mode inner_mode)
 {
   REAL_VALUE_TYPE real;
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 455715ab2f7..8f518fdbe5a 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -64,7 +64,6 @@ (define_c_enum "unspec" [
   UNSPEC_ROUNDEVEN
   UN

Re: [PATCH] fixincludes: add AC_CONFIG_MACRO_DIRS to configure.ac

2024-04-30 Thread Simon Marchi
On 4/30/24 4:54 AM, Christophe Lyon wrote:
> On Tue, 30 Apr 2024 at 04:25, Simon Marchi  wrote:
>>
>> Add an "AC_CONFIG_MACRO_DIRS" call in configure.ac, with the same
>> directories as specified in "ACLOCAL_AMFLAGS", in Makefile.in.
>>
>> This makes it possible to re-generate aclocal.m4 using "autoreconf".
> 
> Thanks, this LGTM, although like in your other patch, we need a
> ChangeLog entry in the commit message.
> 
> Christophe

Here is the ChangeLog entry:

fixincludes/ChangeLog:

* configure.ac: Add AC_CONFIG_MACRO_DIRS.
* configure: Re-generate.

I don't have access to the gcc repo, so if/when this patch gets
approved, can you push it on my behalf?

Thanks,

Simon


Re: [PATCH] libgm2: re-generate with autoreconf

2024-04-30 Thread Simon Marchi
On 4/30/24 8:43 AM, Gaius Mulley wrote:
> Christophe Lyon  writes:
> 
>> On Tue, 30 Apr 2024 at 04:01, Simon Marchi  wrote:
>>>
>>> I get a diff when running "autoreconf" in this directory.  I think that
>>> the current state is erroneous: it appears to have been generated using
>>>
>>> aclocal -I ../config -I ..
>>>
>>> even though configure.ac and Makefile.am list the include flag in the
>>> reverse order:
>>>
>>>aclocal -I .. -I ../config
>>>
>>> Running "autoreconf" uses the latter order, so I think that's the
>>> "right" output.
>>>
>>> No functional difference expected.
>>
>> Thanks, this matches what I noticed.
>> I'm not a maintainer, so I cannot approve, but a minor remark: in GCC
>> we still need a ChangeLog entry in the commit message.
>>
>> Christophe
> 
> many thanks for spotting this bug, lgtm,
> 
> regards,
> Gaius

Here is the ChangeLog entry:

libgm2/ChangeLog:

* Makefile.in, aclocal.m4, libm2cor/Makefile.in,
libm2iso/Makefile.in, libm2log/Makefile.in,
libm2min/Makefile.in, libm2pim/Makefile.in: Re-generate.

I don't have access to the gcc repo, so could you please push the patch
on my behalf?

Thanks,

Simon


Re: [PATCH] docs: Update function multiversioning documentation

2024-04-30 Thread Andrew Carlotti
On Fri, Apr 12, 2024 at 05:41:11PM +0100, Richard Sandiford wrote:
> Hi Andrew,
> 
> Thanks for doing this.  I think it improves the organisation of the
> FMV documentation and adds some details that were previously missing.
> 
> I've made some suggestions below, but documentation is subjective
> and I realise that not everyone will agree with them.
> 
> I've also added Sandra to cc: in case she has time to help with this.
> [original patch: 
> https://gcc.gnu.org/pipermail/gcc-patches/2024-April/649071.html]
> 
> Andrew Carlotti  writes:
> > Add target_version attribute to Common Function Attributes and update
> > target and target_clones documentation.  Move shared detail and examples
> > to the Function Multiversioning page.  Add target-specific details to
> > target-specific pages.
> >
> > ---
> >
> > I've built and checked the info and dvi outputs.  Ok for master?
> >
> > gcc/ChangeLog:
> >
> > * doc/extend.texi (Common Function Attributes): Update target
> > and target_clones documentation, and add target_version.
> > (AArch64 Function Attributes): Add ACLE reference and list
> > supported features.
> > (PowerPC Function Attributes): List supported features.
> > (x86 Function Attributes): Mention function multiversioning.
> > (Function Multiversioning): Update, and move shared detail here.
> >
> >
> > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> > index 
> > 7b54a241a7bfde03ce86571be9486b30bcea6200..78cc7ad2903b61a06b618b82ba7ad52ed42d944a
> >  100644
> > --- a/gcc/doc/extend.texi
> > +++ b/gcc/doc/extend.texi
> > @@ -4178,18 +4178,27 @@ and @option{-Wanalyzer-tainted-size}.
> >  Multiple target back ends implement the @code{target} attribute
> >  to specify that a function is to
> >  be compiled with different target options than specified on the
> > -command line.  The original target command-line options are ignored.
> > -One or more strings can be provided as arguments.
> > -Each string consists of one or more comma-separated suffixes to
> > -the @code{-m} prefix jointly forming the name of a machine-dependent
> > -option.  @xref{Submodel Options,,Machine-Dependent Options}.
> > -
> > +command line.  One or more strings can be provided as arguments.
> > +The attribute may override the original target command-line options, or it 
> > may
> > +be combined with them in a target-specific manner.
> 
> It's hard to tell from this what the conditions for "may" are,
> e.g. whether it depends on the arguments, on the back end, or both.
> Could you add a bit more text to clarify (even if it's just a forward
> reference)?

I think it's better just to drop this sentence and leave it to the
target-specific documentation to cover this.

> With that extra text, and perhaps without, I think it's clearer to
> say this after...
> 
> >  The @code{target} attribute can be used for instance to have a function
> >  compiled with a different ISA (instruction set architecture) than the
> > -default.  @samp{#pragma GCC target} can be used to specify target-specific
> > +default.
> 
> ...this.  I.e.:
> 
>   Multiple target back ends implement [...] command-line.  
>   The @code{target} attribute can be used [...] the default.
> 
>   
> 
> > +
> > +@samp{#pragma GCC target} can be used to specify target-specific
> >  options for more than one function.  @xref{Function Specific Option 
> > Pragmas},
> >  for details about the pragma.
> >  
> > +On x86, the @code{target} attribute can also be used to create multiple
> > +versions of a function, compiled with different target-specific options.
> > +@xref{Function Multiversioning} for more details.
> 
> It might be clearer to put this at the end, since the rest of the section
> goes back to talking about the non-FMV usage.  Perhaps the same goes for
> the pragma part.

Agreed - I've reordered this.

> 
> Also, how about saying that, on AArch64, the equivalent functionality
> is provided by the target_version attribute?

After reording, this paragraph immediately precedes the short descriptions of
target_clones and target_version, with the latter explicitly referring to
AArch64.  I don't think another mention of target_version is necessary.

> > +
> > +The options supported by the @code{target} attribute are specific to each
> > +target; refer to @ref{x86 Function Attributes}, @ref{PowerPC Function
> > +Attributes}, @ref{ARM Function Attributes}, @ref{AArch64 Function 
> > Attributes},
> > +@ref{Nios II Function Attributes}, and @ref{S/390 Function Attributes}
> > +for details.
> > +
> >  For instance, on an x86, you could declare one function with the
> >  @code{target("sse4.1,arch=core2")} attribute and another with
> >  @code{target("sse4a,arch=amdfam10")}.  This is equivalent to
> > @@ -4211,39 +4220,18 @@ multiple options is equivalent to separating the 
> > option suffixes with
> >  a comma (@samp{,}) within a single string.  Spaces are not permitted
> >  within the strings.
> >  
> > -The options supported are specific to each targ

[PATCH v2] docs: Update function multiversioning documentation

2024-04-30 Thread Andrew Carlotti
Add target_version attribute to Common Function Attributes and update
target and target_clones documentation.  Move shared detail and examples
to the Function Multiversioning page.  Add target-specific details to
target-specific pages.

---

Changes since v1:
- Various typo fixes.
- Reordered content in 'Function multiversioning' section to put implementation
  details at the end (as suggested in review).
- Dropped links to outdated wiki page, and a couple of other unhelpful
  sentences that the previous version preserved.

I've built and rechecked the info output.  Ok for master?  And is this ok for
the GCC-14 branch too?

gcc/ChangeLog:

* doc/extend.texi (Common Function Attributes): Update target
and target_clones documentation, and add target_version.
(AArch64 Function Attributes): Add ACLE reference and list
supported features.
(PowerPC Function Attributes): List supported features.
(x86 Function Attributes): Mention function multiversioning.
(Function Multiversioning): Update, and move shared detail here.


diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 
e290265d68d33f86a7e7ee9882cc0fd6bed00143..fefac70b5fffc350bf23db74a8fc88fa3bb99bd5
 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4178,17 +4178,16 @@ and @option{-Wanalyzer-tainted-size}.
 Multiple target back ends implement the @code{target} attribute
 to specify that a function is to
 be compiled with different target options than specified on the
-command line.  The original target command-line options are ignored.
-One or more strings can be provided as arguments.
-Each string consists of one or more comma-separated suffixes to
-the @code{-m} prefix jointly forming the name of a machine-dependent
-option.  @xref{Submodel Options,,Machine-Dependent Options}.
-
+command line.  One or more strings can be provided as arguments.
 The @code{target} attribute can be used for instance to have a function
 compiled with a different ISA (instruction set architecture) than the
-default.  @samp{#pragma GCC target} can be used to specify target-specific
-options for more than one function.  @xref{Function Specific Option Pragmas},
-for details about the pragma.
+default.
+
+The options supported by the @code{target} attribute are specific to each
+target; refer to @ref{x86 Function Attributes}, @ref{PowerPC Function
+Attributes}, @ref{ARM Function Attributes}, @ref{AArch64 Function Attributes},
+@ref{Nios II Function Attributes}, and @ref{S/390 Function Attributes}
+for details.
 
 For instance, on an x86, you could declare one function with the
 @code{target("sse4.1,arch=core2")} attribute and another with
@@ -4211,39 +4210,26 @@ multiple options is equivalent to separating the option 
suffixes with
 a comma (@samp{,}) within a single string.  Spaces are not permitted
 within the strings.
 
-The options supported are specific to each target; refer to @ref{x86
-Function Attributes}, @ref{PowerPC Function Attributes},
-@ref{ARM Function Attributes}, @ref{AArch64 Function Attributes},
-@ref{Nios II Function Attributes}, and @ref{S/390 Function Attributes}
-for details.
+@samp{#pragma GCC target} can be used to specify target-specific
+options for more than one function.  @xref{Function Specific Option Pragmas},
+for details about the pragma.
+
+On x86, the @code{target} attribute can also be used to create multiple
+versions of a function, compiled with different target-specific options.
+@xref{Function Multiversioning} for more details.
 
 @cindex @code{target_clones} function attribute
 @item target_clones (@var{options})
 The @code{target_clones} attribute is used to specify that a function
-be cloned into multiple versions compiled with different target options
-than specified on the command line.  The supported options and restrictions
-are the same as for @code{target} attribute.
-
-For instance, on an x86, you could compile a function with
-@code{target_clones("sse4.1,avx")}.  GCC creates two function clones,
-one compiled with @option{-msse4.1} and another with @option{-mavx}.
-
-On a PowerPC, you can compile a function with
-@code{target_clones("cpu=power9,default")}.  GCC will create two
-function clones, one compiled with @option{-mcpu=power9} and another
-with the default options.  GCC must be configured to use GLIBC 2.23 or
-newer in order to use the @code{target_clones} attribute.
-
-It also creates a resolver function (see
-the @code{ifunc} attribute above) that dynamically selects a clone
-suitable for current architecture.  The resolver is created only if there
-is a usage of a function with @code{target_clones} attribute.
-
-Note that any subsequent call of a function without @code{target_clone}
-from a @code{target_clone} caller will not lead to copying
-(target clone) of the called function.
-If you want to enforce such behaviour,
-we recommend declaring the calling function with the @code{flatten} attribute?
+should be cloned into multiple versions compil

[COMMITTED] Fix the build: error message `quote`

2024-04-30 Thread Andrew Pinski
The problem here is the quote mark is for English's
possessiveness rather than a quote but the error message
format detection is too simple so it warns which causes
-Werror to fail.

Committed as obvious after a quick build.

gcc/ChangeLog:

* tree-cfg.cc (verify_gimple_assign): Remove quote
mark to shut up the warning.

Signed-off-by: Andrew Pinski 
---
 gcc/tree-cfg.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 1c5b7df8541..b2d47b72084 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -4842,7 +4842,7 @@ verify_gimple_assign (gassign *stmt)
   tree lhs = gimple_assign_lhs (stmt);
   if (is_gimple_reg (lhs))
{
- error ("nontemporal store's lhs cannot be a gimple register");
+ error ("nontemporal store lhs cannot be a gimple register");
  debug_generic_stmt (lhs);
  return true;
}
-- 
2.43.0



Re: [PATCH] testsuite: Verify r0-r3 are extended with CMSE

2024-04-30 Thread Richard Earnshaw (lists)
On 30/04/2024 16:37, Torbjorn SVENSSON wrote:
> 
> 
> On 2024-04-30 17:11, Richard Earnshaw (lists) wrote:
>> On 27/04/2024 15:13, Torbjörn SVENSSON wrote:
>>> Add regression test to the existing zero/sign extend tests for CMSE to
>>> verify that r0, r1, r2 and r3 are properly extended, not just r0.
>>>
>>> Test is done using -O0 to ensure the instructions are in a predictable
>>> order.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> * gcc.target/arm/cmse/extend-param.c: Add regression test.
>>>
>>> Signed-off-by: Torbjörn SVENSSON 
>>> ---
>>>   .../gcc.target/arm/cmse/extend-param.c    | 20 ++-
>>>   1 file changed, 19 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/extend-param.c 
>>> b/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
>>> index 01fac786238..b8b8ecbff56 100644
>>> --- a/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
>>> @@ -93,4 +93,22 @@ __attribute__((cmse_nonsecure_entry)) char 
>>> boolSecureFunc (bool index) {
>>>   return 0;
>>>     return array[index];
>>>   -}
>>> \ No newline at end of file
>>> +}
>>> +
>>> +/*
>>> +**__acle_se_boolCharShortEnumSecureFunc:
>>> +**    ...
>>> +**    uxtb    r0, r0
>>> +**    uxtb    r1, r1
>>> +**    uxth    r2, r2
>>> +**    uxtb    r3, r3
>>> +**    ...
>>> +*/
>>> +__attribute__((cmse_nonsecure_entry,optimize(0))) char 
>>> boolCharShortEnumSecureFunc (bool a, unsigned char b, unsigned short c, 
>>> enum offset d) {
>>> +
>>> +  size_t index = a + b + c + d;
>>> +  if (index >= ARRAY_SIZE)
>>> +    return 0;
>>> +  return array[index];
>>> +
>>> +}
>>
>> Ok, but please can you add '-fshort-enums' to dg-options to ensure this test 
>> still behaves correctly if run with a different default (I missed that last 
>> time around).
> 
> Ok, I'll add that to extend-param.c. Do you want me to also add it to the 
> extend-return.c test case?
> 
> Kind regards,
> Torbjörn

Yes please, if it has the same issue.

R.


Re: [PATCH 2/3] c++/modules: Propagate using decls from partitions

2024-04-30 Thread Jason Merrill

On 4/30/24 00:59, Nathaniel Shead wrote:

On Sun, Apr 14, 2024 at 01:40:18AM +1000, Nathaniel Shead wrote:

On Fri, Apr 12, 2024 at 01:50:47PM -0400, Jason Merrill wrote:

On 4/11/24 20:40, Nathaniel Shead wrote:

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

The modules code currently neglects to set OVL_USING_P on the dependency
created for a using-decl, which causes it not to remember that the
OVL_EXPORT_P flag had been set on it when emitted from the primary
interface unit. This patch ensures that it occurs.

gcc/cp/ChangeLog:

* module.cc (depset::hash::add_binding_entity): Propagate
OVL_USING_P for using-declarations.

gcc/testsuite/ChangeLog:

* g++.dg/modules/using-15_a.C: New test.
* g++.dg/modules/using-15_b.C: New test.
* g++.dg/modules/using-15_c.C: New test.

Signed-off-by: Nathaniel Shead 
---
   gcc/cp/module.cc  |  4 
   gcc/testsuite/g++.dg/modules/using-15_a.C | 13 +
   gcc/testsuite/g++.dg/modules/using-15_b.C |  5 +
   gcc/testsuite/g++.dg/modules/using-15_c.C |  7 +++
   4 files changed, 29 insertions(+)
   create mode 100644 gcc/testsuite/g++.dg/modules/using-15_a.C
   create mode 100644 gcc/testsuite/g++.dg/modules/using-15_b.C
   create mode 100644 gcc/testsuite/g++.dg/modules/using-15_c.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 9d054c4c792..527c9046c67 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12915,10 +12915,12 @@ depset::hash::add_binding_entity (tree decl, 
WMB_Flags flags, void *data_)
/* Ignore NTTP objects.  */
return false;
+  bool unscoped_enum_const_p = false;
 if (!(flags & WMB_Using) && CP_DECL_CONTEXT (decl) != data->ns)
{
  /* A using that lost its wrapper or an unscoped enum
 constant.  */
+ unscoped_enum_const_p = (TREE_CODE (decl) == CONST_DECL);


How does this interact with C++20 using enum?


Looks like it ignores those (so they still suffer from this error).  But
in general we don't handle usings of non-functions correctly anyway yet
(for the reasons I described in the cover letter); I just added this for
now to prevent regressing some test-cases caused by importing enum
consts wrapped in an OVERLOAD.

Otherwise happy to defer this patch until GCC 15 when I can look at
exploring what needs to be done to handle non-function using-decls
correctly, but I'll need to work out a new testcase for the followup
patch in this series (or just defer that one too, I suppose).


Ping.  Or should I just scrap this patch for now, find a new testcase
for the followup patch, and submit it again once we have a general
solution for using-decls of non-functions?


Please add a FIXME about using enum here and a using enum testcase to 
the appropriate PR; OK for trunk and 14.2 with that change.


Jason



[PATCH] defer test for limits.h existence to runtime [PR80677]

2024-04-30 Thread Helmut Grohne
The definition of LIMITS_H_TEST evaluates its existence in
BUILD_SYSTEM_HEADER_DIR, but we'd actually need it to check a target
version. Hence this check occasionally produces misdetections when build
and target differ. In some cases such as cygming, the header is only
installed after performing the build. Instead of resolving these
situations by guessing, defer the test to the time of use and check for
the header using __has_include_next which will use the correct include
search path.

2024-04-30  Helmut Grohne  

PR bootstrap/80677
* gcc/limitx.h: Only #include syslimits.h when another 
  exists.
* gcc/limity.h: Only #include limits.h when another 
  exists.
* gcc/Makefile.in: Delete LIMITS_H_TEST default and always wrap
  limits.h with limitx.h and limity.h.
* Makefile.tpl: Drop forwarding of LIMITS_H_TEST
* Makefile.in: Regenerate.
* gcc/config/i386/t-cygming: Delete unused LIMITS_H_TEST.
* gcc/config/t-rtems: Likewise.
* gcc/config/t-vxworks: Likewise.
* gcc/config/vms/t-vms: Likewise.

Signed-off-by: Helmut Grohne 
---
 Makefile.in   | 3 +--
 Makefile.tpl  | 3 +--
 gcc/Makefile.in   | 9 +
 gcc/config/i386/t-cygming | 4 
 gcc/config/t-rtems| 2 --
 gcc/config/t-vxworks  | 6 --
 gcc/config/vms/t-vms  | 2 --
 gcc/limitx.h  | 2 +-
 gcc/limity.h  | 2 +-
 9 files changed, 5 insertions(+), 28 deletions(-)

Please Cc me in replies.

"make bootstrap" passes on today's gcc master.

Bootstrapping Debian without this patch produces a broken toolchain that
assumes absent  and thus defines limits inconsistently with
glibc.

diff --git a/Makefile.in b/Makefile.in
index db4fa6c6260..16785a98305 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1069,8 +1069,7 @@ TARGET_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) 
$(EXTRA_TARGET_FLAGS)
 EXTRA_GCC_FLAGS = \
"GCC_FOR_TARGET=$(GCC_FOR_TARGET) $$TFLAGS" \
"GM2_FOR_TARGET=$(GM2_FOR_TARGET) $$TFLAGS" \
-   "`echo 'STMP_FIXPROTO=$(STMP_FIXPROTO)' | sed -e 
s'/[^=][^=]*=$$/XFOO=/'`" \
-   "`echo 'LIMITS_H_TEST=$(LIMITS_H_TEST)' | sed -e 
s'/[^=][^=]*=$$/XFOO=/'`"
+   "`echo 'STMP_FIXPROTO=$(STMP_FIXPROTO)' | sed -e 
s'/[^=][^=]*=$$/XFOO=/'`"
 
 GCC_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) 
$(EXTRA_GCC_FLAGS)
 
diff --git a/Makefile.tpl b/Makefile.tpl
index 1d5813cd569..991d9738016 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -825,8 +825,7 @@ TARGET_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) 
$(EXTRA_TARGET_FLAGS)
 EXTRA_GCC_FLAGS = \
"GCC_FOR_TARGET=$(GCC_FOR_TARGET) $$TFLAGS" \
"GM2_FOR_TARGET=$(GM2_FOR_TARGET) $$TFLAGS" \
-   "`echo 'STMP_FIXPROTO=$(STMP_FIXPROTO)' | sed -e 
s'/[^=][^=]*=$$/XFOO=/'`" \
-   "`echo 'LIMITS_H_TEST=$(LIMITS_H_TEST)' | sed -e 
s'/[^=][^=]*=$$/XFOO=/'`"
+   "`echo 'STMP_FIXPROTO=$(STMP_FIXPROTO)' | sed -e 
s'/[^=][^=]*=$$/XFOO=/'`"
 
 GCC_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) 
$(EXTRA_GCC_FLAGS)
 
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a74761b7ab3..debcc5a6bb0 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -581,9 +581,6 @@ BUILD_SYSTEM_HEADER_DIR = `echo @BUILD_SYSTEM_HEADER_DIR@ | 
sed -e :a -e 's,[^/]
 # Control whether to run fixincludes.
 STMP_FIXINC = @STMP_FIXINC@
 
-# Test to see whether  exists in the system header files.
-LIMITS_H_TEST = [ -f $(BUILD_SYSTEM_HEADER_DIR)/limits.h ]
-
 # Directory for prefix to system directories, for
 # each of $(system_prefix)/usr/include, $(system_prefix)/usr/lib, etc.
 TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT@
@@ -3327,11 +3324,7 @@ stmp-int-hdrs: $(STMP_FIXINC) $(T_GLIMITS_H) 
$(T_STDINT_GCC_H) $(USER_H) fixinc_
  sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
  multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
  include_dir=include$${multi_dir}; \
- if $(LIMITS_H_TEST) ; then \
-   cat $(srcdir)/limitx.h $(T_GLIMITS_H) $(srcdir)/limity.h > 
tmp-xlimits.h; \
- else \
-   cat $(T_GLIMITS_H) > tmp-xlimits.h; \
- fi; \
+ cat $(srcdir)/limitx.h $(T_GLIMITS_H) $(srcdir)/limity.h > 
tmp-xlimits.h; \
  $(mkinstalldirs) $${include_dir}; \
  chmod a+rx $${include_dir} || true; \
  $(SHELL) $(srcdir)/../move-if-change \
diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming
index af01f69acd1..50bf0c149e8 100644
--- a/gcc/config/i386/t-cygming
+++ b/gcc/config/i386/t-cygming
@@ -16,10 +16,6 @@
 # along with GCC; see the file COPYING3.  If not see
 # .
 
-# cygwin and mingw always have a limits.h, but, depending upon how we are
-# doing the build, it may not be installed yet.
-LIMITS_H_TEST = true
-
 winnt.o: $(srcdir)/config/i386/winnt.cc $(CONFIG_H) $(SYSTEM_H) coretypes.h \
   $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
   $(TM_P_H) $(HASH_TABLE_H

Re: [PATCH] c++/modules: Implement P2615 'Meaningful Exports' [PR107688]

2024-04-30 Thread Jason Merrill

On 3/4/24 06:18, Nathaniel Shead wrote:

Bootstrapped and regtested on x86_64-pc-linux-gnu. This should probably
wait for GCC 15 I suppose, but sending it in now in case there are any
comments.


OK for trunk.


-- >8 --

This clarifies which kinds of declarations may and may not be exported
in various contexts. The patch additionally fixes up some small issues
that were clarified by the paper.

Most of the changes are with regards to export-declarations, which are
applied for all standards modes that we support '-fmodules-ts' for.
However there are also a couple of changes made to linkage specifiers
('extern "C"'); I've applied these as since C++20, to line up with when
modules were actually introduced.

PR c++/107688

gcc/cp/ChangeLog:

* name-lookup.cc (push_namespace): Error when exporting
namespace with internal linkage.
* parser.h (struct cp_parser): Add new flag
'in_unbraced_export_declaration_p'.
* parser.cc (cp_debug_parser): Print the new flag.
(cp_parser_new): Initialise the new flag.
(cp_parser_module_export): Set the new flag.
(cp_parser_class_specifier): Clear and restore the new flag.
(cp_parser_import_declaration): Imports can now appear directly
in a linkage specification.
(cp_parser_declaration): Categorise declarations as "name" or
"special"; error on the later in contexts where the former is
required.
(cp_parser_class_head): Error when exporting a partial
specialisation.

gcc/testsuite/ChangeLog:

* g++.dg/modules/contracts-1_a.C: Avoid now-illegal syntax.
* g++.dg/modules/contracts-2_a.C: Likewise.
* g++.dg/modules/contracts-3_a.C: Likewise.
* g++.dg/modules/contracts-4_a.C: Likewise.
* g++.dg/modules/lang-1_c.C: Clarify now-legal syntax.
* g++.dg/template/crash71.C: Update error messages.
* g++.dg/cpp2a/linkage-spec1.C: New test.
* g++.dg/modules/export-3.C: New test.
* g++.dg/modules/export-4_a.C: New test.
* g++.dg/modules/export-4_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/name-lookup.cc|  10 +-
  gcc/cp/parser.cc | 105 +++
  gcc/cp/parser.h  |   6 +-
  gcc/testsuite/g++.dg/cpp2a/linkage-spec1.C   |  22 
  gcc/testsuite/g++.dg/modules/contracts-1_a.C |   2 +-
  gcc/testsuite/g++.dg/modules/contracts-2_a.C |   2 +-
  gcc/testsuite/g++.dg/modules/contracts-3_a.C |   2 +-
  gcc/testsuite/g++.dg/modules/contracts-4_a.C |   2 +-
  gcc/testsuite/g++.dg/modules/export-3.C  |  30 ++
  gcc/testsuite/g++.dg/modules/export-4_a.C|  23 
  gcc/testsuite/g++.dg/modules/export-4_b.C|  13 +++
  gcc/testsuite/g++.dg/modules/lang-1_c.C  |   2 +-
  gcc/testsuite/g++.dg/template/crash71.C  |   4 +-
  13 files changed, 192 insertions(+), 31 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/linkage-spec1.C
  create mode 100644 gcc/testsuite/g++.dg/modules/export-3.C
  create mode 100644 gcc/testsuite/g++.dg/modules/export-4_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/export-4_b.C

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 6444db3f0eb..743102d8393 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -9053,8 +9053,14 @@ push_namespace (tree name, bool make_inline)
  {
/* A public namespace is exported only if explicitly marked, or
 it contains exported entities.  */
-  if (TREE_PUBLIC (ns) && module_exporting_p ())
-   DECL_MODULE_EXPORT_P (ns) = true;
+  if (module_exporting_p ())
+   {
+ if (TREE_PUBLIC (ns))
+   DECL_MODULE_EXPORT_P (ns) = true;
+ else if (!header_module_p ())
+   error_at (input_location,
+ "exporting namespace with internal linkage");
+   }
if (module_purview_p ())
DECL_MODULE_PURVIEW_P (ns) = true;
  
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc

index a310b9e8c07..448392e1bd9 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -560,6 +560,8 @@ cp_debug_parser (FILE *file, cp_parser *parser)
   & THIS_FORBIDDEN));
cp_debug_print_flag (file, "In unbraced linkage specification",
  parser->in_unbraced_linkage_specification_p);
+  cp_debug_print_flag (file, "In unbraced export declaration",
+ parser->in_unbraced_export_declaration_p);
cp_debug_print_flag (file, "Parsing a declarator",
  parser->in_declarator_p);
cp_debug_print_flag (file, "In template argument list",
@@ -4425,6 +4427,9 @@ cp_parser_new (cp_lexer *lexer)
/* We are not processing an `extern "C"' declaration.  */
parser->in_unbraced_linkage_specification_p = false;
  
+  /* We aren't parsing an export-declaration.  */

+  parser->in_unbraced_export_declaration_p = false;
+
   

Re: [PATCH] c++/c-common: Fix convert_vector_to_array_for_subscript for qualified vector types [PR89224]

2024-04-30 Thread Jason Merrill

On 2/20/24 19:06, Andrew Pinski wrote:

After r7-987-gf17a223de829cb, the access for the elements of a vector type 
would lose the qualifiers.
So if we had `constvector[0]`, the type of the element of the array would not 
have const on it.
This was due to a missing build_qualified_type for the inner type of the vector 
when building the array type.
We need to add back the call to build_qualified_type and now the access has the 
correct qualifiers. So the
overloads and even if it is a lvalue or rvalue is correctly done.

Note we correctly now reject the testcase gcc.dg/pr83415.c which was 
incorrectly accepted after r7-987-gf17a223de829cb.

Built and tested for aarch64-linux-gnu.

PR c++/89224

gcc/c-family/ChangeLog:

* c-common.cc (convert_vector_to_array_for_subscript): Call 
build_qualified_type
for the inner type.

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_array_reference): Compare main variants
for the vector/array types instead of the types directly.

gcc/testsuite/ChangeLog:

* g++.dg/torture/vector-subaccess-1.C: New test.
* gcc.dg/pr83415.c: Change warning to error.

Signed-off-by: Andrew Pinski 
---
  gcc/c-family/c-common.cc  |  7 +-
  gcc/cp/constexpr.cc   |  3 ++-
  .../g++.dg/torture/vector-subaccess-1.C   | 23 +++
  gcc/testsuite/gcc.dg/pr83415.c|  2 +-
  4 files changed, 32 insertions(+), 3 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/torture/vector-subaccess-1.C

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e15eff698df..884dd9043f9 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -8936,6 +8936,7 @@ convert_vector_to_array_for_subscript (location_t loc,
if (gnu_vector_type_p (TREE_TYPE (*vecp)))
  {
tree type = TREE_TYPE (*vecp);
+  tree newitype;
  
ret = !lvalue_p (*vecp);
  
@@ -8950,8 +8951,12 @@ convert_vector_to_array_for_subscript (location_t loc,

 for function parameters.  */
c_common_mark_addressable_vec (*vecp);
  
+  /* Make sure qualifiers are copied from the vector type to the new element

+of the array type.  */
+  newitype = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
+
*vecp = build1 (VIEW_CONVERT_EXPR,
- build_array_type_nelts (TREE_TYPE (type),
+ build_array_type_nelts (newitype,
  TYPE_VECTOR_SUBPARTS (type)),
  *vecp);
  }
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index fa346fe01c9..1fe91d16e8e 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -4421,7 +4421,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree 
t,
if (!lval
&& TREE_CODE (ary) == VIEW_CONVERT_EXPR
&& VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
-  && TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0
+  && TYPE_MAIN_VARIANT (TREE_TYPE (t))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0)


Please add parens around the == expression so the formatting is stable.

With that change, OK for trunk and release branches.

Jason



Re: [PATCH] c++/c-common: Fix convert_vector_to_array_for_subscript for qualified vector types [PR89224]

2024-04-30 Thread Andrew Pinski
On Tue, Apr 30, 2024 at 11:54 AM Jason Merrill  wrote:
>
> On 2/20/24 19:06, Andrew Pinski wrote:
> > After r7-987-gf17a223de829cb, the access for the elements of a vector type 
> > would lose the qualifiers.
> > So if we had `constvector[0]`, the type of the element of the array would 
> > not have const on it.
> > This was due to a missing build_qualified_type for the inner type of the 
> > vector when building the array type.
> > We need to add back the call to build_qualified_type and now the access has 
> > the correct qualifiers. So the
> > overloads and even if it is a lvalue or rvalue is correctly done.
> >
> > Note we correctly now reject the testcase gcc.dg/pr83415.c which was 
> > incorrectly accepted after r7-987-gf17a223de829cb.
> >
> > Built and tested for aarch64-linux-gnu.
> >
> >   PR c++/89224
> >
> > gcc/c-family/ChangeLog:
> >
> >   * c-common.cc (convert_vector_to_array_for_subscript): Call 
> > build_qualified_type
> >   for the inner type.
> >
> > gcc/cp/ChangeLog:
> >
> >   * constexpr.cc (cxx_eval_array_reference): Compare main variants
> >   for the vector/array types instead of the types directly.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * g++.dg/torture/vector-subaccess-1.C: New test.
> >   * gcc.dg/pr83415.c: Change warning to error.
> >
> > Signed-off-by: Andrew Pinski 
> > ---
> >   gcc/c-family/c-common.cc  |  7 +-
> >   gcc/cp/constexpr.cc   |  3 ++-
> >   .../g++.dg/torture/vector-subaccess-1.C   | 23 +++
> >   gcc/testsuite/gcc.dg/pr83415.c|  2 +-
> >   4 files changed, 32 insertions(+), 3 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/torture/vector-subaccess-1.C
> >
> > diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> > index e15eff698df..884dd9043f9 100644
> > --- a/gcc/c-family/c-common.cc
> > +++ b/gcc/c-family/c-common.cc
> > @@ -8936,6 +8936,7 @@ convert_vector_to_array_for_subscript (location_t loc,
> > if (gnu_vector_type_p (TREE_TYPE (*vecp)))
> >   {
> > tree type = TREE_TYPE (*vecp);
> > +  tree newitype;
> >
> > ret = !lvalue_p (*vecp);
> >
> > @@ -8950,8 +8951,12 @@ convert_vector_to_array_for_subscript (location_t 
> > loc,
> >for function parameters.  */
> > c_common_mark_addressable_vec (*vecp);
> >
> > +  /* Make sure qualifiers are copied from the vector type to the new 
> > element
> > +  of the array type.  */
> > +  newitype = build_qualified_type (TREE_TYPE (type), TYPE_QUALS 
> > (type));
> > +
> > *vecp = build1 (VIEW_CONVERT_EXPR,
> > -   build_array_type_nelts (TREE_TYPE (type),
> > +   build_array_type_nelts (newitype,
> > TYPE_VECTOR_SUBPARTS (type)),
> > *vecp);
> >   }
> > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> > index fa346fe01c9..1fe91d16e8e 100644
> > --- a/gcc/cp/constexpr.cc
> > +++ b/gcc/cp/constexpr.cc
> > @@ -4421,7 +4421,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, 
> > tree t,
> > if (!lval
> > && TREE_CODE (ary) == VIEW_CONVERT_EXPR
> > && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
> > -  && TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0
> > +  && TYPE_MAIN_VARIANT (TREE_TYPE (t))
> > +   == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 
> > 0)
>
> Please add parens around the == expression so the formatting is stable.
ok, I will make that change.

>
> With that change, OK for trunk and release branches.

For the GCC 14 branch, should I wait until after the release due to
RC1 going out today and I am not sure this counts as a show stopper
issue.

Thanks,
Andrew

>
> Jason
>


Re: [PATCH] c++/c-common: Fix convert_vector_to_array_for_subscript for qualified vector types [PR89224]

2024-04-30 Thread Jason Merrill

On 4/30/24 12:04, Andrew Pinski wrote:

On Tue, Apr 30, 2024 at 11:54 AM Jason Merrill  wrote:


On 2/20/24 19:06, Andrew Pinski wrote:

After r7-987-gf17a223de829cb, the access for the elements of a vector type 
would lose the qualifiers.
So if we had `constvector[0]`, the type of the element of the array would not 
have const on it.
This was due to a missing build_qualified_type for the inner type of the vector 
when building the array type.
We need to add back the call to build_qualified_type and now the access has the 
correct qualifiers. So the
overloads and even if it is a lvalue or rvalue is correctly done.

Note we correctly now reject the testcase gcc.dg/pr83415.c which was 
incorrectly accepted after r7-987-gf17a223de829cb.

Built and tested for aarch64-linux-gnu.

   PR c++/89224

gcc/c-family/ChangeLog:

   * c-common.cc (convert_vector_to_array_for_subscript): Call 
build_qualified_type
   for the inner type.

gcc/cp/ChangeLog:

   * constexpr.cc (cxx_eval_array_reference): Compare main variants
   for the vector/array types instead of the types directly.

gcc/testsuite/ChangeLog:

   * g++.dg/torture/vector-subaccess-1.C: New test.
   * gcc.dg/pr83415.c: Change warning to error.

Signed-off-by: Andrew Pinski 
---
   gcc/c-family/c-common.cc  |  7 +-
   gcc/cp/constexpr.cc   |  3 ++-
   .../g++.dg/torture/vector-subaccess-1.C   | 23 +++
   gcc/testsuite/gcc.dg/pr83415.c|  2 +-
   4 files changed, 32 insertions(+), 3 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/torture/vector-subaccess-1.C

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index e15eff698df..884dd9043f9 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -8936,6 +8936,7 @@ convert_vector_to_array_for_subscript (location_t loc,
 if (gnu_vector_type_p (TREE_TYPE (*vecp)))
   {
 tree type = TREE_TYPE (*vecp);
+  tree newitype;

 ret = !lvalue_p (*vecp);

@@ -8950,8 +8951,12 @@ convert_vector_to_array_for_subscript (location_t loc,
for function parameters.  */
 c_common_mark_addressable_vec (*vecp);

+  /* Make sure qualifiers are copied from the vector type to the new 
element
+  of the array type.  */
+  newitype = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
+
 *vecp = build1 (VIEW_CONVERT_EXPR,
-   build_array_type_nelts (TREE_TYPE (type),
+   build_array_type_nelts (newitype,
 TYPE_VECTOR_SUBPARTS (type)),
 *vecp);
   }
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index fa346fe01c9..1fe91d16e8e 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -4421,7 +4421,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree 
t,
 if (!lval
 && TREE_CODE (ary) == VIEW_CONVERT_EXPR
 && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
-  && TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0
+  && TYPE_MAIN_VARIANT (TREE_TYPE (t))
+   == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0)


Please add parens around the == expression so the formatting is stable.

ok, I will make that change.



With that change, OK for trunk and release branches.


For the GCC 14 branch, should I wait until after the release due to
RC1 going out today and I am not sure this counts as a show stopper
issue.


That's not my call ("all changes to the branch require a RM approval 
now") but I think it can wait for 14.2.


Jason



Re: [PATCH] Fortran: fix issues with class(*) assignment [PR114827]

2024-04-30 Thread Harald Anlauf

Hi Paul,

On 4/30/24 07:50, Paul Richard Thomas wrote:

Hi Harald,

This patch is verging on 'obvious', . once one sees it :-)

Yes, it's good for mainline and all active branches, when available.


thanks for your quick review.

I haven't committed it yet, because I forgot to check what happens with
a class(*) allocatable function result on the r.h.s. of the assignment.
One now gets an ICE with the testcase in your submission

  https://gcc.gnu.org/pipermail/fortran/2024-April/060426.html

on the simple scalar assignment

  y = bar ()

instead of wrong code.  Not very helpful.

I tried the following change on top of the submitted patch:

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 4ba40bfdbd3..cacf3c0dda1 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -11995,7 +11996,11 @@ trans_class_assignment (stmtblock_t *block,
gfc_expr *lhs, gfc_expr *rhs,
   /* Take into account _len of unlimited polymorphic entities.  */
   if (UNLIMITED_POLY (rhs))
{
- tree len = trans_get_upoly_len (block, rhs);
+ tree len;
+ if (rhs->expr_type == EXPR_VARIABLE)
+   len = trans_get_upoly_len (block, rhs);
+ else
+   len = gfc_class_len_get (gfc_get_class_from_expr (tmp));
  len = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
 fold_convert (size_type_node, len),
 size_one_node);

This avoids the ICE, but depending on details of bar() this leads
to different wrong code from before, and

  function bar() result(res)
class(*), allocatable :: res
res = sca
  end function bar

behaves differently from

  function bar()
class(*), allocatable :: bar
bar = sca
  end function bar

The minimal and sort of "safe" fix to avoid a new ICE while keeping
the fix for simple assignments is to replace in the above snippet

   if (UNLIMITED_POLY (rhs))

by

   if (UNLIMITED_POLY (rhs) && rhs->expr_type == EXPR_VARIABLE)

omit the other changes above, and defer a fix for assignment of
function results, as looking at the dump-tree suggests that this
will be a bigger piece of work.  (The .span looks suspicious all
over the place...)

The good thing is: a simple test with array-valued function results
did not immediately break the submitted patch...  ;-)

What do you think?

Thanks,
Harald


Thanks

Paul

PS The fall-out pr114874 is so peculiar that I am dropping everything to
find the source.


On Mon, 29 Apr 2024 at 19:39, Harald Anlauf  wrote:


Dear all,

the attached patch fixes issues with assignments of unlimited polymorphic
entities that were found with the help of valgrind or asan, see PR.
Looking
further into it, it turns out that allocation sizes as well as array spans
could be set incorrectly, leading to wrong results or heap corruption.

The fix is rather straightforward: take into the _len of unlimited
polymorphic entities when it is non-zero to get the correct allocation
sizes and array spans.

The patch has been tested by the reporter, see PR.

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

I would like to backport this to active branches where appropriate,
starting with 14 after it reopens after release.  Is this OK?

Thanks,
Harald








Re: [PATCH] regalloc: Ignore '^' in early costing [PR114766]

2024-04-30 Thread Vladimir Makarov



On 4/29/24 08:59, Wilco Dijkstra wrote:

According to documentation, '^' should only have an effect during reload.
However ira-costs.cc treats it in the same way as '?' during early costing.
As a result using '^' can accidentally disable valid alternatives and cause
significant regressions (see PR114741).  Avoid this by ignoring '^' during
costing.

Passes bootstrap and regress, OK for commit?

gcc:
 PR rtl-optimization/114766
 * ira-costs.cc (record_reg_classes): Ignore '^' during costing.

Sorry, I can not accept this patch.  This constraint is used by other 
targets (as I know rs6000, s390, sh, gcn).  I suspect changing the 
semantics can affect the targets in some undesirable way.


Saying that, I understand that aarch64 needs the new semantics. So I 
think we can add a new hint with the required semantics. There are still 
few undefined characters for the new hint: '~', '-', '/', and '.' (may 
be I missed some),


I propose to use '~' for the new hint. So besides changing code, the 
documentation for '^' needs to clarified and documentation for code '~' 
should be added.




diff --git a/gcc/ira-costs.cc b/gcc/ira-costs.cc
index 
c86c5a16563aeefac9d4fa72839bee8d95409f4b..04d2f21b023f3456ba6f8c16c2418d7313965b2f
 100644
--- a/gcc/ira-costs.cc
+++ b/gcc/ira-costs.cc
@@ -771,10 +771,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
  c = *++p;
  break;
  
-		case '^':

- alt_cost += 2;
- break;
-
case '?':
  alt_cost += 2;
  break;







[PATCH] RISC-V: Add testcase for pr114734

2024-04-30 Thread Patrick O'Neill
gcc/testsuite/ChangeLog:

PR middle-end/114734

* gcc.target/riscv/rvv/autovec/pr114734.c: New test.

Signed-off-by: Patrick O'Neill 
---
Tested on rv64gcv before and after Richard Biener's fix:
4d3a5618de5a949c61605f545f90e81bc502
---
 .../gcc.target/riscv/rvv/autovec/pr114734.c   | 25 +++
 1 file changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr114734.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr114734.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr114734.c
new file mode 100644
index 000..b605d992aa1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr114734.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target riscv_v } */
+/* { dg-options { -march=rv64gcv_zvl256b -mabi=lp64d -fwhole-program -O3 
-mrvv-vector-bits=zvl  } } */
+
+int f[18];
+int g[18];
+int h[18][18][18];
+int a[324];
+long b[18];
+int *i = g;
+int (*j)[18][18] = h;
+int z;
+int main() {
+  for (int m = 0; m < 18; ++m)
+f[m] = 3;
+  for (int m = 0; m < 18; m += 1)
+for (int n = 0; n < 18; n += 3) {
+  a[m * 8 + n] = j[m][m][0] ? i[n] : 0;
+  b[n] = f[n] ? -i[m] : 0;
+}
+  for (long n = 0; n < 8; ++n)
+z = a[n];
+  if (b[15] != 0)
+__builtin_abort();
+}
-- 
2.34.1



Re: [PATCH v15 23/26] c++: Implement __is_invocable built-in trait

2024-04-30 Thread Jason Merrill

On 3/15/24 01:15, Ken Matsui wrote:

Added diagnostics for build_invoke.

Ok for 15?


Thanks, just a few tweaks needed.  Will you have time to make them?  Or 
Patrick?


[...]

diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 98c10e6a8b5..2282ce71c06 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -1928,6 +1928,162 @@ build_trait_object (tree type)
return build_stub_object (type);
  }
  
+/* [func.require] Build an expression of INVOKE(FN_TYPE, ARG_TYPES...).  If the

+   given is not invocable, returns error_mark_node.  */
+
+tree
+build_invoke (tree fn_type, const_tree arg_types, tsubst_flags_t complain)
+{
+  if (error_operand_p (fn_type) || error_operand_p (arg_types))
+return error_mark_node;
+
+  gcc_assert (TYPE_P (fn_type));
+  gcc_assert (TREE_CODE (arg_types) == TREE_VEC);
+
+  /* Access check is required to determine if the given is invocable.  */
+  deferring_access_check_sentinel acs (dk_no_deferred);
+
+  /* INVOKE is an unevaluated context.  */
+  cp_unevaluated cp_uneval_guard;
+
+  bool is_ptrdatamem;
+  bool is_ptrmemfunc;
+  if (TREE_CODE (fn_type) == REFERENCE_TYPE)
+{
+  tree deref_fn_type = TREE_TYPE (fn_type);
+  is_ptrdatamem = TYPE_PTRDATAMEM_P (deref_fn_type);
+  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (deref_fn_type);
+
+  /* Dereference fn_type if it is a pointer to member.  */
+  if (is_ptrdatamem || is_ptrmemfunc)
+   fn_type = deref_fn_type;
+}
+  else
+{
+  is_ptrdatamem = TYPE_PTRDATAMEM_P (fn_type);
+  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (fn_type);
+}
+
+  if (is_ptrdatamem && TREE_VEC_LENGTH (arg_types) != 1)
+{
+  if (complain & tf_error)
+   error ("pointer to data member type %qT can only be invoked with "
+  "one argument", fn_type);
+  return error_mark_node;
+}
+
+  if (is_ptrmemfunc && TREE_VEC_LENGTH (arg_types) == 0)
+{
+  if (complain & tf_error)
+   error ("pointer to member function type %qT must be invoked with "
+  "at least one argument", fn_type);
+  return error_mark_node;
+}
+
+  /* Construct an expression of a pointer to member.  */
+  tree ptrmem_expr;
+  if (is_ptrdatamem || is_ptrmemfunc)
+{
+  tree datum_type = TREE_VEC_ELT (arg_types, 0);
+
+  /* datum must be a class type or a reference/pointer to a class type.  */
+  if (TYPE_REF_P (datum_type) || POINTER_TYPE_P (datum_type))
+{
+ if (!CLASS_TYPE_P (TREE_TYPE (datum_type)))
+   {
+ if (complain & tf_error)
+   error ("datum type %qT of a pointer to member must be a class"


I don't see the term "datum" anywhere in [func.require], let's refer to 
the "first argument" instead.



+  "type or a reference/pointer to a class type",
+  datum_type);
+ return error_mark_node;
+   }
+}
+  else if (!CLASS_TYPE_P (datum_type))
+   {
+ if (complain & tf_error)
+   error ("datum type %qT of a pointer to member must be a class"
+  "type or a reference/pointer to a class type",
+  datum_type);
+ return error_mark_node;
+   }
+
+  bool is_refwrap = false;
+  if (CLASS_TYPE_P (datum_type))
+   {
+ /* 1.2 & 1.5: Handle std::reference_wrapper.  */
+ tree datum_decl = TYPE_NAME (TYPE_MAIN_VARIANT (datum_type));
+ if (decl_in_std_namespace_p (datum_decl))
+   {
+ const_tree name = DECL_NAME (datum_decl);
+ if (name && (id_equal (name, "reference_wrapper")))
+   {
+ /* Retrieve T from std::reference_wrapper,
+i.e., decltype(datum.get()).  */
+ datum_type = TREE_VEC_ELT (TYPE_TI_ARGS (datum_type), 0);
+ is_refwrap = true;
+   }
+   }
+   }
+
+  tree datum_expr = build_trait_object (datum_type);
+  tree fn_expr = build_trait_object (fn_type);
+  ptrmem_expr = build_m_component_ref (datum_expr, fn_expr, complain);


We should check same-or-base before trying this, not after.


+  if (error_operand_p (ptrmem_expr) && !is_refwrap)
+   {
+ tree ptrmem_class_type = TYPE_PTRMEM_CLASS_TYPE (fn_type);
+ const bool ptrmem_is_base_of_datum =
+   (NON_UNION_CLASS_TYPE_P (ptrmem_class_type)
+&& NON_UNION_CLASS_TYPE_P (datum_type)
+&& (same_type_ignoring_top_level_qualifiers_p (ptrmem_class_type,
+   datum_type)
+|| DERIVED_FROM_P (ptrmem_class_type, datum_type)));
+
+ if (!ptrmem_is_base_of_datum)
+   {
+ /* 1.3 & 1.6: Try to dereference datum_expr.  */
+ datum_expr = build_x_indirect_ref (UNKNOWN_LOCATION, datum_expr,
+RO_UNARY_STAR, NULL_TREE,
+complain);
+

Re: [PATCH v14 01/26] c++: Implement __is_const built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::is_const.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __is_const.
* 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/constraint.cc |  3 +++
  gcc/cp/cp-trait.def  |  1 +
  gcc/cp/semantics.cc  |  4 
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
  gcc/testsuite/g++.dg/ext/is_const.C  | 20 
  5 files changed, 31 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 49de3211d4c..f32a1c78d63 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3767,6 +3767,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 394f006f20f..36faed9c0b3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -64,6 +64,7 @@ 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)
  DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
  DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 57840176863..0d08900492b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12446,6 +12446,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_CLASS:
return NON_UNION_CLASS_TYPE_P (type1);
  
+case CPTK_IS_CONST:

+  return CP_TYPE_CONST_P (type1);
+
  case CPTK_IS_CONSTRUCTIBLE:
return is_xible (INIT_EXPR, type1, type2);
  
@@ -12688,6 +12691,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_ARRAY:
  case CPTK_IS_BOUNDED_ARRAY:
  case CPTK_IS_CLASS:
+case CPTK_IS_CONST:
  case CPTK_IS_ENUM:
  case CPTK_IS_FUNCTION:
  case CPTK_IS_MEMBER_FUNCTION_POINTER:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 02b4b4d745d..e3640faeb96 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -71,6 +71,9 @@
  #if !__has_builtin (__is_class)
  # error "__has_builtin (__is_class) failed"
  #endif
+#if !__has_builtin (__is_const)
+# error "__has_builtin (__is_const) failed"
+#endif
  #if !__has_builtin (__is_constructible)
  # error "__has_builtin (__is_constructible) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_const.C 
b/gcc/testsuite/g++.dg/ext/is_const.C
new file mode 100644
index 000..8a0e8df72a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_const.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+using cClassType = const ClassType;
+using vClassType = volatile ClassType;
+using cvClassType = const volatile ClassType;
+
+// Positive tests.
+SA(__is_const(const int));
+SA(__is_const(const volatile int));
+SA(__is_const(cClassType));
+SA(__is_const(cvClassType));
+
+// Negative tests.
+SA(!__is_const(int));
+SA(!__is_const(volatile int));
+SA(!__is_const(ClassType));
+SA(!__is_const(vClassType));




Re: [PATCH v14 03/26] c++: Implement __is_volatile built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::is_volatile.


OK.


gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/constraint.cc |  3 +++
  gcc/cp/cp-trait.def  |  1 +
  gcc/cp/semantics.cc  |  4 
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
  gcc/testsuite/g++.dg/ext/is_volatile.C   | 20 
  5 files changed, 31 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f32a1c78d63..9a7a12629e7 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3861,6 +3861,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 36faed9c0b3..e9347453829 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -92,6 +92,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/semantics.cc b/gcc/cp/semantics.cc
index 0d08900492b..41c25f43d27 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12532,6 +12532,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_UNION:
return type_code1 == UNION_TYPE;
  
+case CPTK_IS_VOLATILE:

+  return CP_TYPE_VOLATILE_P (type1);
+
  case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
  
@@ -12702,6 +12705,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_SAME:
  case CPTK_IS_SCOPED_ENUM:
  case CPTK_IS_UNION:
+case CPTK_IS_VOLATILE:
break;
  
  case CPTK_IS_LAYOUT_COMPATIBLE:

diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index e3640faeb96..b2e2f2f694d 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -158,6 +158,9 @@
  #if !__has_builtin (__is_union)
  # error "__has_builtin (__is_union) failed"
  #endif
+#if !__has_builtin (__is_volatile)
+# error "__has_builtin (__is_volatile) failed"
+#endif
  #if !__has_builtin (__reference_constructs_from_temporary)
  # error "__has_builtin (__reference_constructs_from_temporary) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_volatile.C 
b/gcc/testsuite/g++.dg/ext/is_volatile.C
new file mode 100644
index 000..80a1cfc880d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_volatile.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+using cClassType = const ClassType;
+using vClassType = volatile ClassType;
+using cvClassType = const volatile ClassType;
+
+// Positive tests.
+SA(__is_volatile(volatile int));
+SA(__is_volatile(const volatile int));
+SA(__is_volatile(vClassType));
+SA(__is_volatile(cvClassType));
+
+// Negative tests.
+SA(!__is_volatile(int));
+SA(!__is_volatile(const int));
+SA(!__is_volatile(ClassType));
+SA(!__is_volatile(cClassType));




Re: [PATCH v15 23/26] c++: Implement __is_invocable built-in trait

2024-04-30 Thread Ken Matsui
On Tue, Apr 30, 2024 at 1:50 PM Jason Merrill  wrote:
>
> On 3/15/24 01:15, Ken Matsui wrote:
> > Added diagnostics for build_invoke.
> >
> > Ok for 15?
>
> Thanks, just a few tweaks needed.  Will you have time to make them?  Or
> Patrick?

I believe I will have time later next week.  Thank you so much for your review!

>
> [...]
> > diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
> > index 98c10e6a8b5..2282ce71c06 100644
> > --- a/gcc/cp/method.cc
> > +++ b/gcc/cp/method.cc
> > @@ -1928,6 +1928,162 @@ build_trait_object (tree type)
> > return build_stub_object (type);
> >   }
> >
> > +/* [func.require] Build an expression of INVOKE(FN_TYPE, ARG_TYPES...).  
> > If the
> > +   given is not invocable, returns error_mark_node.  */
> > +
> > +tree
> > +build_invoke (tree fn_type, const_tree arg_types, tsubst_flags_t complain)
> > +{
> > +  if (error_operand_p (fn_type) || error_operand_p (arg_types))
> > +return error_mark_node;
> > +
> > +  gcc_assert (TYPE_P (fn_type));
> > +  gcc_assert (TREE_CODE (arg_types) == TREE_VEC);
> > +
> > +  /* Access check is required to determine if the given is invocable.  */
> > +  deferring_access_check_sentinel acs (dk_no_deferred);
> > +
> > +  /* INVOKE is an unevaluated context.  */
> > +  cp_unevaluated cp_uneval_guard;
> > +
> > +  bool is_ptrdatamem;
> > +  bool is_ptrmemfunc;
> > +  if (TREE_CODE (fn_type) == REFERENCE_TYPE)
> > +{
> > +  tree deref_fn_type = TREE_TYPE (fn_type);
> > +  is_ptrdatamem = TYPE_PTRDATAMEM_P (deref_fn_type);
> > +  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (deref_fn_type);
> > +
> > +  /* Dereference fn_type if it is a pointer to member.  */
> > +  if (is_ptrdatamem || is_ptrmemfunc)
> > + fn_type = deref_fn_type;
> > +}
> > +  else
> > +{
> > +  is_ptrdatamem = TYPE_PTRDATAMEM_P (fn_type);
> > +  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (fn_type);
> > +}
> > +
> > +  if (is_ptrdatamem && TREE_VEC_LENGTH (arg_types) != 1)
> > +{
> > +  if (complain & tf_error)
> > + error ("pointer to data member type %qT can only be invoked with "
> > +"one argument", fn_type);
> > +  return error_mark_node;
> > +}
> > +
> > +  if (is_ptrmemfunc && TREE_VEC_LENGTH (arg_types) == 0)
> > +{
> > +  if (complain & tf_error)
> > + error ("pointer to member function type %qT must be invoked with "
> > +"at least one argument", fn_type);
> > +  return error_mark_node;
> > +}
> > +
> > +  /* Construct an expression of a pointer to member.  */
> > +  tree ptrmem_expr;
> > +  if (is_ptrdatamem || is_ptrmemfunc)
> > +{
> > +  tree datum_type = TREE_VEC_ELT (arg_types, 0);
> > +
> > +  /* datum must be a class type or a reference/pointer to a class 
> > type.  */
> > +  if (TYPE_REF_P (datum_type) || POINTER_TYPE_P (datum_type))
> > +{
> > +   if (!CLASS_TYPE_P (TREE_TYPE (datum_type)))
> > + {
> > +   if (complain & tf_error)
> > + error ("datum type %qT of a pointer to member must be a class"
>
> I don't see the term "datum" anywhere in [func.require], let's refer to
> the "first argument" instead.
>
> > +"type or a reference/pointer to a class type",
> > +datum_type);
> > +   return error_mark_node;
> > + }
> > +}
> > +  else if (!CLASS_TYPE_P (datum_type))
> > + {
> > +   if (complain & tf_error)
> > + error ("datum type %qT of a pointer to member must be a class"
> > +"type or a reference/pointer to a class type",
> > +datum_type);
> > +   return error_mark_node;
> > + }
> > +
> > +  bool is_refwrap = false;
> > +  if (CLASS_TYPE_P (datum_type))
> > + {
> > +   /* 1.2 & 1.5: Handle std::reference_wrapper.  */
> > +   tree datum_decl = TYPE_NAME (TYPE_MAIN_VARIANT (datum_type));
> > +   if (decl_in_std_namespace_p (datum_decl))
> > + {
> > +   const_tree name = DECL_NAME (datum_decl);
> > +   if (name && (id_equal (name, "reference_wrapper")))
> > + {
> > +   /* Retrieve T from std::reference_wrapper,
> > +  i.e., decltype(datum.get()).  */
> > +   datum_type = TREE_VEC_ELT (TYPE_TI_ARGS (datum_type), 0);
> > +   is_refwrap = true;
> > + }
> > + }
> > + }
> > +
> > +  tree datum_expr = build_trait_object (datum_type);
> > +  tree fn_expr = build_trait_object (fn_type);
> > +  ptrmem_expr = build_m_component_ref (datum_expr, fn_expr, complain);
>
> We should check same-or-base before trying this, not after.
>
> > +  if (error_operand_p (ptrmem_expr) && !is_refwrap)
> > + {
> > +   tree ptrmem_class_type = TYPE_PTRMEM_CLASS_TYPE (fn_type);
> > +   const bool ptrmem_is_base_of_datum =
> > + (NON_UNION_CLASS_TYPE_P (ptrmem_class_type)
> > +  && NON_UNION_CLASS_TYPE_P (datum_type)
> > +  && (same_type

Re: [PATCH v14 05/26] c++: Implement __is_pointer built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::is_pointer.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* 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/semantics.cc  |  4 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
  gcc/testsuite/g++.dg/ext/is_pointer.C| 51 
  5 files changed, 62 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 9a7a12629e7..244070d93c2 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3828,6 +3828,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 e9347453829..18e2d0f3480 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
  DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1)
  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/semantics.cc b/gcc/cp/semantics.cc
index 41c25f43d27..9dcdb06191a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12502,6 +12502,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_POD:
return pod_type_p (type1);
  
+case CPTK_IS_POINTER:

+  return TYPE_PTR_P (type1);
+
  case CPTK_IS_POLYMORPHIC:
return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
  
@@ -12701,6 +12704,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_MEMBER_OBJECT_POINTER:
  case CPTK_IS_MEMBER_POINTER:
  case CPTK_IS_OBJECT:
+case CPTK_IS_POINTER:
  case CPTK_IS_REFERENCE:
  case CPTK_IS_SAME:
  case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index b2e2f2f694d..96b7a89e4f1 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -125,6 +125,9 @@
  #if !__has_builtin (__is_pod)
  # error "__has_builtin (__is_pod) failed"
  #endif
+#if !__has_builtin (__is_pointer)
+# error "__has_builtin (__is_pointer) failed"
+#endif
  #if !__has_builtin (__is_polymorphic)
  # error "__has_builtin (__is_polymorphic) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_pointer.C
new file mode 100644
index 000..d6e39565950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(!__is_pointer(int));
+SA(__is_pointer(int*));
+SA(__is_pointer(int**));
+
+SA(__is_pointer(const int*));
+SA(__is_pointer(const int**));
+SA(__is_pointer(int* const));
+SA(__is_pointer(int** const));
+SA(__is_pointer(int* const* const));
+
+SA(__is_pointer(volatile int*));
+SA(__is_pointer(volatile int**));
+SA(__is_pointer(int* volatile));
+SA(__is_pointer(int** volatile));
+SA(__is_pointer(int* volatile* volatile));
+
+SA(__is_pointer(const volatile int*));
+SA(__is_pointer(const volatile int**));
+SA(__is_pointer(const int* volatile));
+SA(__is_pointer(volatile int* const));
+SA(__is_pointer(int* const volatile));
+SA(__is_pointer(const int** volatile));
+SA(__is_pointer(volatile int** const));
+SA(__is_pointer(int** const volatile));
+SA(__is_pointer(int* const* const volatile));
+SA(__is_pointer(int* volatile* const volatile));
+SA(__is_pointer(int* const volatile* const volatile));
+
+SA(!__is_pointer(int&));
+SA(!__is_pointer(const int&));
+SA(!__is_pointer(volatile int&));
+SA(!__is_pointer(const volatile int&));
+
+SA(!__is_pointer(int&&));
+SA(!__is_pointer(const int&&));
+SA(!__is_pointer(volatile int&&));
+SA(!__is_pointer(const volatile int&&));
+
+SA(!__is_pointer(int[3]));
+SA(!__is_pointer(const int[3]));
+SA(!__is_pointer(volatile int[3]));
+SA(!__is_pointer(const volatile int[3]));
+
+SA(!__is_pointer(int(int)));
+SA(__is_pointer(int(*const)(int)));

Re: [PATCH v14 07/26] c++: Implement __is_unbounded_array built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::is_unbounded_array.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* 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/semantics.cc   |  4 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
  gcc/testsuite/g++.dg/ext/is_unbounded_array.C | 37 +++
  5 files changed, 48 insertions(+)
  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 244070d93c2..000df847342 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3861,6 +3861,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 18e2d0f3480..05514a51c21 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -92,6 +92,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/semantics.cc b/gcc/cp/semantics.cc
index 9dcdb06191a..1794e83baa2 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12532,6 +12532,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_TRIVIALLY_COPYABLE:
return trivially_copyable_p (type1);
  
+case CPTK_IS_UNBOUNDED_ARRAY:

+  return array_of_unknown_bound_p (type1);
+
  case CPTK_IS_UNION:
return type_code1 == UNION_TYPE;
  
@@ -12708,6 +12711,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_REFERENCE:
  case CPTK_IS_SAME:
  case CPTK_IS_SCOPED_ENUM:
+case CPTK_IS_UNBOUNDED_ARRAY:
  case CPTK_IS_UNION:
  case CPTK_IS_VOLATILE:
break;
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 96b7a89e4f1..b1430e9bd8b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -158,6 +158,9 @@
  #if !__has_builtin (__is_trivially_copyable)
  # error "__has_builtin (__is_trivially_copyable) failed"
  #endif
+#if !__has_builtin (__is_unbounded_array)
+# error "__has_builtin (__is_unbounded_array) failed"
+#endif
  #if !__has_builtin (__is_union)
  # error "__has_builtin (__is_union) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_unbounded_array.C 
b/gcc/testsuite/g++.dg/ext/is_unbounded_array.C
new file mode 100644
index 000..283a74e1a0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_unbounded_array.C
@@ -0,0 +1,37 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+class ClassType { };
+class IncompleteClass;
+union IncompleteUnion;
+
+SA_TEST_CATEGORY(__is_unbounded_array, int[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, int[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, int[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, int[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, IncompleteClass[2][3], false);
+SA_TEST_CATEGORY(__is_unbou

Re: [PATCH v14 09/26] c++: Implement __add_pointer built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::add_pointer.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __add_pointer.
* semantics.cc (finish_trait_type): Handle CPTK_ADD_POINTER.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/cp-trait.def  |  1 +
  gcc/cp/semantics.cc  |  9 ++
  gcc/testsuite/g++.dg/ext/add_pointer.C   | 39 
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
  4 files changed, 52 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/add_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 05514a51c21..63f879287ce 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
  #define DEFTRAIT_TYPE_DEFAULTED
  #endif
  
+DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)

  DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 1794e83baa2..635441a7a90 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12776,6 +12776,15 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
  
switch (kind)

  {
+case CPTK_ADD_POINTER:
+  if (FUNC_OR_METHOD_TYPE_P (type1)
+ && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type1) != REF_QUAL_NONE))
+   return type1;
+  if (TYPE_REF_P (type1))
+   type1 = TREE_TYPE (type1);
+  return build_pointer_type (type1);
+
  case CPTK_REMOVE_CV:
return cv_unqualified (type1);
  
diff --git a/gcc/testsuite/g++.dg/ext/add_pointer.C b/gcc/testsuite/g++.dg/ext/add_pointer.C

new file mode 100644
index 000..c405cdd0feb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_pointer.C
@@ -0,0 +1,39 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_pointer(int), int*));
+SA(__is_same(__add_pointer(int*), int**));
+SA(__is_same(__add_pointer(const int), const int*));
+SA(__is_same(__add_pointer(int&), int*));
+SA(__is_same(__add_pointer(ClassType*), ClassType**));
+SA(__is_same(__add_pointer(ClassType), ClassType*));
+SA(__is_same(__add_pointer(void), void*));
+SA(__is_same(__add_pointer(const void), const void*));
+SA(__is_same(__add_pointer(volatile void), volatile void*));
+SA(__is_same(__add_pointer(const volatile void), const volatile void*));
+
+void f1();
+using f1_type = decltype(f1);
+using pf1_type = decltype(&f1);
+SA(__is_same(__add_pointer(f1_type), pf1_type));
+
+void f2() noexcept; // PR libstdc++/78361
+using f2_type = decltype(f2);
+using pf2_type = decltype(&f2);
+SA(__is_same(__add_pointer(f2_type), pf2_type));
+
+using fn_type = void();
+using pfn_type = void(*)();
+SA(__is_same(__add_pointer(fn_type), pfn_type));
+
+SA(__is_same(__add_pointer(void() &), void() &));
+SA(__is_same(__add_pointer(void() & noexcept), void() & noexcept));
+SA(__is_same(__add_pointer(void() const), void() const));
+SA(__is_same(__add_pointer(void(...) &), void(...) &));
+SA(__is_same(__add_pointer(void(...) & noexcept), void(...) & noexcept));
+SA(__is_same(__add_pointer(void(...) const), void(...) const));
+
+SA(__is_same(__add_pointer(void() __restrict), void() __restrict));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index b1430e9bd8b..9d861398bae 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
  // { dg-do compile }
  // Verify that __has_builtin gives the correct answer for C++ built-ins.
  
+#if !__has_builtin (__add_pointer)

+# error "__has_builtin (__add_pointer) failed"
+#endif
  #if !__has_builtin (__builtin_addressof)
  # error "__has_builtin (__builtin_addressof) failed"
  #endif




Re: [PATCH v14 13/26] c++: Implement __remove_all_extents built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::remove_all_extents.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_all_extents.
* semantics.cc (finish_trait_type): Handle
CPTK_REMOVE_ALL_EXTENTS.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/cp-trait.def   |  1 +
  gcc/cp/semantics.cc   |  3 +++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +++
  gcc/testsuite/g++.dg/ext/remove_all_extents.C | 16 
  4 files changed, 23 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/remove_all_extents.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 577c96d579b..933c8bcbe68 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -98,6 +98,7 @@ 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_ALL_EXTENTS, "__remove_all_extents", 1)
  DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
  DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
  DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 58696225fc4..078424dac23 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12785,6 +12785,9 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree 
type2,
type1 = TREE_TYPE (type1);
return build_pointer_type (type1);
  
+case CPTK_REMOVE_ALL_EXTENTS:

+  return strip_array_types (type1);
+
  case CPTK_REMOVE_CV:
return cv_unqualified (type1);
  
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C

index 5d5cbe3b019..85b74bd676b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -176,6 +176,9 @@
  #if !__has_builtin (__reference_converts_from_temporary)
  # error "__has_builtin (__reference_converts_from_temporary) failed"
  #endif
+#if !__has_builtin (__remove_all_extents)
+# error "__has_builtin (__remove_all_extents) failed"
+#endif
  #if !__has_builtin (__remove_cv)
  # error "__has_builtin (__remove_cv) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_all_extents.C 
b/gcc/testsuite/g++.dg/ext/remove_all_extents.C
new file mode 100644
index 000..60ade2ade7f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_all_extents.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__remove_all_extents(int), int));
+SA(__is_same(__remove_all_extents(int[2]), int));
+SA(__is_same(__remove_all_extents(int[2][3]), int));
+SA(__is_same(__remove_all_extents(int[][3]), int));
+SA(__is_same(__remove_all_extents(const int[2][3]), const int));
+SA(__is_same(__remove_all_extents(ClassType), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[2]), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[2][3]), ClassType));
+SA(__is_same(__remove_all_extents(ClassType[][3]), ClassType));
+SA(__is_same(__remove_all_extents(const ClassType[2][3]), const ClassType));




Re: [PATCH v14 11/26] c++: Implement __remove_extent built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::remove_extent.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_extent.
* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_EXTENT.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/cp-trait.def  |  1 +
  gcc/cp/semantics.cc  |  5 +
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
  gcc/testsuite/g++.dg/ext/remove_extent.C | 16 
  4 files changed, 25 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/remove_extent.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 63f879287ce..577c96d579b 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -100,6 +100,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_EXTENT, "__remove_extent", 1)
  DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
  DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
  DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 635441a7a90..58696225fc4 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12793,6 +12793,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
type1 = TREE_TYPE (type1);
return cv_unqualified (type1);
  
+case CPTK_REMOVE_EXTENT:

+  if (TREE_CODE (type1) == ARRAY_TYPE)
+   type1 = TREE_TYPE (type1);
+  return type1;
+
  case CPTK_REMOVE_POINTER:
if (TYPE_PTR_P (type1))
type1 = TREE_TYPE (type1);
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 9d861398bae..5d5cbe3b019 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -182,6 +182,9 @@
  #if !__has_builtin (__remove_cvref)
  # error "__has_builtin (__remove_cvref) failed"
  #endif
+#if !__has_builtin (__remove_extent)
+# error "__has_builtin (__remove_extent) failed"
+#endif
  #if !__has_builtin (__remove_pointer)
  # error "__has_builtin (__remove_pointer) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_extent.C 
b/gcc/testsuite/g++.dg/ext/remove_extent.C
new file mode 100644
index 000..6183aca5a48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_extent.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__remove_extent(int), int));
+SA(__is_same(__remove_extent(int[2]), int));
+SA(__is_same(__remove_extent(int[2][3]), int[3]));
+SA(__is_same(__remove_extent(int[][3]), int[3]));
+SA(__is_same(__remove_extent(const int[2]), const int));
+SA(__is_same(__remove_extent(ClassType), ClassType));
+SA(__is_same(__remove_extent(ClassType[2]), ClassType));
+SA(__is_same(__remove_extent(ClassType[2][3]), ClassType[3]));
+SA(__is_same(__remove_extent(ClassType[][3]), ClassType[3]));
+SA(__is_same(__remove_extent(const ClassType[2]), const ClassType));




Re: [PATCH v14 15/26] c++: Implement __add_lvalue_reference built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::add_lvalue_reference.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __add_lvalue_reference.
* semantics.cc (finish_trait_type): Handle
CPTK_ADD_LVALUE_REFERENCE.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/cp-trait.def   |  1 +
  gcc/cp/semantics.cc   |  8 +++
  .../g++.dg/ext/add_lvalue_reference.C | 21 +++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +++
  4 files changed, 33 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/add_lvalue_reference.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 933c8bcbe68..9a27dca4ea3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -48,6 +48,7 @@
  #define DEFTRAIT_TYPE_DEFAULTED
  #endif
  
+DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)

  DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 078424dac23..05f5b62f9df 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12776,6 +12776,14 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
  
switch (kind)

  {
+case CPTK_ADD_LVALUE_REFERENCE:
+  if (VOID_TYPE_P (type1)
+ || (FUNC_OR_METHOD_TYPE_P (type1)
+ && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type1) != REF_QUAL_NONE)))
+   return type1;
+  return cp_build_reference_type (type1, /*rval=*/false);
+
  case CPTK_ADD_POINTER:
if (FUNC_OR_METHOD_TYPE_P (type1)
  && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
diff --git a/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C 
b/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
new file mode 100644
index 000..8fe1e0300e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
@@ -0,0 +1,21 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_lvalue_reference(int), int&));
+SA(__is_same(__add_lvalue_reference(int&), int&));
+SA(__is_same(__add_lvalue_reference(const int), const int&));
+SA(__is_same(__add_lvalue_reference(int*), int*&));
+SA(__is_same(__add_lvalue_reference(ClassType&), ClassType&));
+SA(__is_same(__add_lvalue_reference(ClassType), ClassType&));
+SA(__is_same(__add_lvalue_reference(int(int)), int(&)(int)));
+SA(__is_same(__add_lvalue_reference(int&&), int&));
+SA(__is_same(__add_lvalue_reference(ClassType&&), ClassType&));
+SA(__is_same(__add_lvalue_reference(void), void));
+SA(__is_same(__add_lvalue_reference(const void), const void));
+SA(__is_same(__add_lvalue_reference(bool(int) const), bool(int) const));
+SA(__is_same(__add_lvalue_reference(bool(int) &), bool(int) &));
+SA(__is_same(__add_lvalue_reference(bool(int) const &&), bool(int) const &&));
+SA(__is_same(__add_lvalue_reference(bool(int)), bool(&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 85b74bd676b..3fca9cfabcc 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -2,6 +2,9 @@
  // { dg-do compile }
  // Verify that __has_builtin gives the correct answer for C++ built-ins.
  
+#if !__has_builtin (__add_lvalue_reference)

+# error "__has_builtin (__add_lvalue_reference) failed"
+#endif
  #if !__has_builtin (__add_pointer)
  # error "__has_builtin (__add_pointer) failed"
  #endif




Re: [PATCH v14 17/26] c++: Implement __add_rvalue_reference built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::add_rvalue_reference.

gcc/cp/ChangeLog:

* cp-trait.def: Define __add_rvalue_reference.
* semantics.cc (finish_trait_type): Handle
CPTK_ADD_RVALUE_REFERENCE.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/cp-trait.def   |  1 +
  gcc/cp/semantics.cc   |  8 
  .../g++.dg/ext/add_rvalue_reference.C | 20 +++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +++
  4 files changed, 32 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/add_rvalue_reference.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9a27dca4ea3..173818adf79 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -50,6 +50,7 @@
  
  DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)

  DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
+DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 05f5b62f9df..19d6f87a9ea 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12793,6 +12793,14 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
type1 = TREE_TYPE (type1);
return build_pointer_type (type1);
  
+case CPTK_ADD_RVALUE_REFERENCE:

+  if (VOID_TYPE_P (type1)
+ || (FUNC_OR_METHOD_TYPE_P (type1)
+ && (type_memfn_quals (type1) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type1) != REF_QUAL_NONE)))


Actually, let's factor this bit out of this and the other traits into a 
referenceable_type_p function since it's getting checked so much.



+   return type1;
+  return cp_build_reference_type (type1, /*rval=*/true);
+
  case CPTK_REMOVE_ALL_EXTENTS:
return strip_array_types (type1);
  
diff --git a/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C b/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C

new file mode 100644
index 000..c92fe6bfa17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/add_rvalue_reference.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+
+SA(__is_same(__add_rvalue_reference(int), int&&));
+SA(__is_same(__add_rvalue_reference(int&&), int&&));
+SA(__is_same(__add_rvalue_reference(int&), int&));
+SA(__is_same(__add_rvalue_reference(const int), const int&&));
+SA(__is_same(__add_rvalue_reference(int*), int*&&));
+SA(__is_same(__add_rvalue_reference(ClassType&&), ClassType&&));
+SA(__is_same(__add_rvalue_reference(ClassType), ClassType&&));
+SA(__is_same(__add_rvalue_reference(int(int)), int(&&)(int)));
+SA(__is_same(__add_rvalue_reference(void), void));
+SA(__is_same(__add_rvalue_reference(const void), const void));
+SA(__is_same(__add_rvalue_reference(bool(int) const), bool(int) const));
+SA(__is_same(__add_rvalue_reference(bool(int) &), bool(int) &));
+SA(__is_same(__add_rvalue_reference(bool(int) const &&), bool(int) const &&));
+SA(__is_same(__add_rvalue_reference(bool(int)), bool(&&)(int)));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 3fca9cfabcc..c2503c5d82b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -8,6 +8,9 @@
  #if !__has_builtin (__add_pointer)
  # error "__has_builtin (__add_pointer) failed"
  #endif
+#if !__has_builtin (__add_rvalue_reference)
+# error "__has_builtin (__add_rvalue_reference) failed"
+#endif
  #if !__has_builtin (__builtin_addressof)
  # error "__has_builtin (__builtin_addressof) failed"
  #endif




Re: [PATCH v14 19/26] c++: Implement __decay built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::decay.


OK.


gcc/cp/ChangeLog:

* cp-trait.def: Define __decay.
* semantics.cc (finish_trait_type): Handle CPTK_DECAY.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/cp-trait.def  |  1 +
  gcc/cp/semantics.cc  | 12 
  gcc/testsuite/g++.dg/ext/decay.C | 22 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
  4 files changed, 38 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/decay.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 173818adf79..2d1cb7c227c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -51,6 +51,7 @@
  DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1)
  DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1)
  DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1)
+DEFTRAIT_TYPE (DECAY, "__decay", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1)
  DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 19d6f87a9ea..45dc509855a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12801,6 +12801,18 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
return type1;
return cp_build_reference_type (type1, /*rval=*/true);
  
+case CPTK_DECAY:

+  if (TYPE_REF_P (type1))
+   type1 = TREE_TYPE (type1);
+
+  if (TREE_CODE (type1) == ARRAY_TYPE)
+   return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
+ complain);
+  else if (TREE_CODE (type1) == FUNCTION_TYPE)
+   return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
+  else
+   return cv_unqualified (type1);
+
  case CPTK_REMOVE_ALL_EXTENTS:
return strip_array_types (type1);
  
diff --git a/gcc/testsuite/g++.dg/ext/decay.C b/gcc/testsuite/g++.dg/ext/decay.C

new file mode 100644
index 000..8adedfeefe6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/decay.C
@@ -0,0 +1,22 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+// Positive tests.
+using test1_type = __decay(bool);
+SA(__is_same(test1_type, bool));
+
+// NB: DR 705.
+using test2_type = __decay(const int);
+SA(__is_same(test2_type, int));
+
+using test3_type = __decay(int[4]);
+SA(__is_same(test3_type, __remove_extent(int[4])*));
+
+using fn_type = void ();
+using test4_type = __decay(fn_type);
+SA(__is_same(test4_type, __add_pointer(fn_type)));
+
+using cfn_type = void () const;
+using test5_type = __decay(cfn_type);
+SA(__is_same(test5_type, cfn_type));
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index c2503c5d82b..3aca273aad6 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -11,6 +11,9 @@
  #if !__has_builtin (__add_rvalue_reference)
  # error "__has_builtin (__add_rvalue_reference) failed"
  #endif
+#if !__has_builtin (__decay)
+# error "__has_builtin (__decay) failed"
+#endif
  #if !__has_builtin (__builtin_addressof)
  # error "__has_builtin (__builtin_addressof) failed"
  #endif




Re: [PATCH v14 21/26] c++: Implement __rank built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::rank.


__rank seems too short, maybe __array_rank?

Actually, it occurs to me that perhaps we should have been adding 
__builtin to all of these rather than just __ and the library trait 
name.  I guess it's too late to do that for the GCC 14 traits, but we 
could do it for this group?



gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/constraint.cc |  3 +++
  gcc/cp/cp-trait.def  |  1 +
  gcc/cp/semantics.cc  | 23 ---
  gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
  gcc/testsuite/g++.dg/ext/rank.C  | 24 
  5 files changed, 51 insertions(+), 3 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/ext/rank.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 000df847342..23ea66d9c12 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3870,6 +3870,9 @@ diagnose_trait_expr (tree expr, tree args)
  case CPTK_IS_VOLATILE:
inform (loc, "  %qT is not a volatile type", t1);
break;
+case CPTK_RANK:
+  inform (loc, "  %qT cannot yield a rank", 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 2d1cb7c227c..85056c8140b 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -99,6 +99,7 @@ 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 (RANK, "__rank", 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_ALL_EXTENTS, "__remove_all_extents", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 45dc509855a..7242db75248 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12550,6 +12550,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_DEDUCIBLE:
return type_targs_deducible_from (type1, type2);
  
+/* __rank is handled in finish_trait_expr. */

+case CPTK_RANK:


This should have a gcc_unreachable.


+
  #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
  case CPTK_##CODE:
  #include "cp-trait.def"
@@ -12622,7 +12625,10 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
if (processing_template_decl)
  {
tree trait_expr = make_node (TRAIT_EXPR);
-  TREE_TYPE (trait_expr) = boolean_type_node;
+  if (kind == CPTK_RANK)
+   TREE_TYPE (trait_expr) = size_type_node;
+  else
+   TREE_TYPE (trait_expr) = boolean_type_node;
TRAIT_EXPR_TYPE1 (trait_expr) = type1;
TRAIT_EXPR_TYPE2 (trait_expr) = type2;
TRAIT_EXPR_KIND (trait_expr) = kind;
@@ -12714,6 +12720,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
  case CPTK_IS_UNBOUNDED_ARRAY:
  case CPTK_IS_UNION:
  case CPTK_IS_VOLATILE:
+case CPTK_RANK:
break;
  
  case CPTK_IS_LAYOUT_COMPATIBLE:

@@ -12745,8 +12752,18 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
gcc_unreachable ();
  }
  
-  tree val = (trait_expr_value (kind, type1, type2)

- ? boolean_true_node : boolean_false_node);
+  tree val;
+  if (kind == CPTK_RANK)
+{
+  size_t rank = 0;
+  for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
+   ++rank;
+  val = build_int_cst (size_type_node, rank);
+}
+  else
+val = (trait_expr_value (kind, type1, type2)
+  ? boolean_true_node : boolean_false_node);
+
return maybe_wrap_with_location (val, loc);
  }
  
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C

index 3aca273aad6..7f7b27f7aa7 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -179,6 +179,9 @@
  #if !__has_builtin (__is_volatile)
  # error "__has_builtin (__is_volatile) failed"
  #endif
+#if !__has_builtin (__rank)
+# error "__has_builtin (__rank) failed"
+#endif
  #if !__has_builtin (__reference_constructs_from_temporary)
  # error "__has_builtin (__reference_constructs_from_temporary) failed"
  #endif
diff --git a/gcc/testsuite/g++.d

Re: [PATCH v14 25/26] c++: Implement __is_nothrow_invocable built-in trait

2024-04-30 Thread Jason Merrill

On 2/28/24 11:26, Ken Matsui wrote:

This patch implements built-in trait for std::is_nothrow_invocable.


OK after addressing comments on other traits.


gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
  gcc/cp/constraint.cc  |  6 ++
  gcc/cp/cp-trait.def   |  1 +
  gcc/cp/semantics.cc   |  4 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +
  .../g++.dg/ext/is_nothrow_invocable.C | 62 +++
  5 files changed, 76 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c87b126fdb1..43d4f2102d6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3824,6 +3824,12 @@ diagnose_trait_expr (tree expr, tree args)
  case CPTK_IS_NOTHROW_CONVERTIBLE:
  inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
break;
+case CPTK_IS_NOTHROW_INVOCABLE:
+   if (!t2)
+ inform (loc, "  %qT is not nothrow invocable", t1);
+   else
+ inform (loc, "  %qT is not nothrow invocable by %qE", t1, t2);
+   break;
  case CPTK_IS_OBJECT:
inform (loc, "  %qT is not an object type", t1);
break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 6cb2b55f4ea..a9714921e94 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -84,6 +84,7 @@ 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)
+DEFTRAIT_EXPR (IS_NOTHROW_INVOCABLE, "__is_nothrow_invocable", -1)
  DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1)
  DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
  DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 149c0631d62..dba7b43a109 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12494,6 +12494,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_NOTHROW_CONVERTIBLE:
return is_nothrow_convertible (type1, type2);
  
+case CPTK_IS_NOTHROW_INVOCABLE:

+  return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
+
  case CPTK_IS_OBJECT:
return (type_code1 != FUNCTION_TYPE
  && type_code1 != REFERENCE_TYPE
@@ -12689,6 +12692,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
  case CPTK_IS_NOTHROW_ASSIGNABLE:
  case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
  case CPTK_IS_NOTHROW_CONVERTIBLE:
+case CPTK_IS_NOTHROW_INVOCABLE:
  case CPTK_IS_TRIVIALLY_ASSIGNABLE:
  case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
  case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index d2a7ebdf25c..624d3525f27 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -131,6 +131,9 @@
  #if !__has_builtin (__is_nothrow_convertible)
  # error "__has_builtin (__is_nothrow_convertible) failed"
  #endif
+#if !__has_builtin (__is_nothrow_invocable)
+# error "__has_builtin (__is_nothrow_invocable) failed"
+#endif
  #if !__has_builtin (__is_object)
  # error "__has_builtin (__is_object) failed"
  #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C 
b/gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C
new file mode 100644
index 000..2f9b40e5538
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C
@@ -0,0 +1,62 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+using func_type = void(*)();
+SA( ! __is_nothrow_invocable(func_type) );
+
+#if __cpp_noexcept_function_type
+using func_type_nt = void(*)() noexcept;
+SA(   __is_nothrow_invocable(func_type_nt) );
+#endif
+
+struct X { };
+using mem_type = int X::*;
+
+SA( ! __is_nothrow_invocable(mem_type) );
+SA( ! __is_nothrow_invocable(mem_type, int) );
+SA( ! __is_nothrow_invocable(mem_type, int&) );
+SA(   __is_nothrow_invocable(mem_type, X&) );
+
+using memfun_type = int (X::*)();
+
+SA( ! __is_nothrow_invocable(memfun_type) );
+SA( ! __is_nothrow_invocable(memfun_type, int) );
+SA( ! __is_nothrow_invocable(memfun_type, int&) );
+SA( ! __is_nothrow_invocable(memfun_type, X&) );
+SA( ! __is_nothrow_invocable(memfun_type, X*) );
+
+#if __cpp_noexcept_function_type
+using

Re: [wwwdocs] Porting-to-14: Mention new pragma GCC Target behavior

2024-04-30 Thread Martin Jambor
Hi,

On Thu, Apr 25 2024, Jakub Jelinek wrote:
> On Thu, Apr 25, 2024 at 02:34:22PM +0200, Martin Jambor wrote:
>> when looking at a package build issue with GCC 14, Michal Jireš noted a
>> different behavior of pragma GCC Target.  This snippet tries to describe
>> the gist of the problem.  I have left it in the C section even though it
>> is not really C specific, but could not think of a good name for a new
>> section for it.  Ideas (and any other suggestions for improvements)
>> welcome, of course.
>
> The change was more subtle.
> We used to define/undefine the ISA macros in C in GCC 13 and older as well,
> but only when using integrated preprocessor during compilation,
> so it didn't work that way with -save-temps or separate -E and -S/-c
> steps.
> While in C++ it behaved as if the define/undefines aren't done at all
> (they were done, but after preprocessing/lexing everything, so didn't
> affect anything).
> In GCC 14, it behaves in C++ the same as in C in older versions, and
> additionally they are defined/undefined also when using separate
> preprocessing, in both C and C++.
>

I see, thanks for the correction.

Would the following then perhaps describe the situation accurately?
Note that I have moved the whole thing to C++ section because it seems
porting issues in C because of this are quite unlikely.

Michal, I assume that the file where this issue happened was written in
C++, right?

Martin



diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html
index c825a68e..1e67b0b3 100644
--- a/htdocs/gcc-14/porting_to.html
+++ b/htdocs/gcc-14/porting_to.html
@@ -514,6 +514,51 @@ be included explicitly when compiling with GCC 14:
 
 
 
+Pragma GCC Target now affects preprocessor 
symbols
+
+
+The behavior of pragma GCC Target and specifically how it affects ISA
+macros has changed in GCC 14.  In GCC 13 and older, the GCC
+target pragma defined and undefined corresponding ISA macros in
+C when using integrated preprocessor during compilation but not when
+preprocessor was invoked as a separate step or when using -save-temps.
+In C++ the ISA macro definitions were performed in a way which did not
+have any actual effect.
+
+In GCC 14 C++ behaves like C with integrated preprocessing in earlier
+versions. Moreover, in both languages ISA macros are defined and
+undefined as expected when preprocessing separately from compilation.
+
+
+This can lead to different behavior, especially in C++.  For example,
+functions the C++ snippet below will be (silently) compiled for an
+incorrect instruction set by GCC 14.
+
+
+  #if ! __AVX2__
+  #pragma GCC push_options
+  #pragma GCC target("avx2")
+  #endif
+
+  /* Code to be compiled for AVX2. */
+
+  /* With GCC 14, __AVX2__ here will always be defined and pop_options
+  never called. */
+  #if ! __AVX2__
+  #pragma GCC pop_options
+  #endif
+
+  /* With GCC 14, all following functions will be compiled for AVX2
+  which was not intended. */
+
+
+
+The fix in this case would be to remember
+whether pop_options needs to be performed in a new
+user-defined macro.
+
+
+
 
 
 


[COMMITTED 1/5] Remove wrapper around gimple_range_global.

2024-04-30 Thread Andrew MacLeod
This came up during stage 4 when someone noticed a comment that said 
when legacy EVRP was removed, the wrapper around accessing 
SSA_NAME_RANGES for initial values could be removed.


To be clearer, the original discussion is here: 
https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html


We couldn't prime ranger's initial use of an ssa-name before inlining, 
or we would end up removing builtin_unreachable calls. These conditions 
are no longer present, and its safe to simple always pick up whatever 
the best value we can find.


It even provides a modest speedup with less condition checking on every 
access to a global.


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

Andrew
From f3571462b581e1b57d563268483207bc929de952 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Tue, 20 Feb 2024 12:27:51 -0500
Subject: [PATCH 1/9] Remove wrapper around gimple_range_global.

Now that legacy EVRP has been removed, we can remove the wrapper which
prevented us from using global names before inlining except under
some specific conditions.  See discussion:
 https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html

	* value-query.cc (get_range_global): Rename to gimple_range_global.
	(gimple_range_global): Remove wrapper function.
	(global_range_query::range_of_expr): Call gimple_range_global.
---
 gcc/value-query.cc | 40 +++-
 1 file changed, 7 insertions(+), 33 deletions(-)

diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 052b7511565..e88c8e25789 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -280,11 +280,15 @@ get_ssa_name_ptr_info_nonnull (const_tree name)
 // Update the global range for NAME into the SSA_RANGE_NAME_INFO and
 // Return the legacy global range for NAME if it has one, otherwise
 // return VARYING.
+// See discussion here regarding why there use to be a wrapper function:
+// https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html
+// Legacy EVRP has been removed, leaving just this function.
 
-static void
-get_range_global (vrange &r, tree name, struct function *fun = cfun)
+void
+gimple_range_global (vrange &r, tree name, struct function *fun)
 {
   tree type = TREE_TYPE (name);
+  gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
 
   if (SSA_NAME_IS_DEFAULT_DEF (name))
 {
@@ -332,36 +336,6 @@ get_range_global (vrange &r, tree name, struct function *fun = cfun)
 r.set_varying (type);
 }
 
-// This is where the ranger picks up global info to seed initial
-// requests.  It is a slightly restricted version of
-// get_range_global() above.
-//
-// The reason for the difference is that we can always pick the
-// default definition of an SSA with no adverse effects, but for other
-// SSAs, if we pick things up to early, we may prematurely eliminate
-// builtin_unreachables.
-//
-// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has
-// all of its unreachable calls removed too early.
-//
-// See discussion here:
-// https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html
-
-void
-gimple_range_global (vrange &r, tree name, struct function *fun)
-{
-  tree type = TREE_TYPE (name);
-  gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
-
-  if (SSA_NAME_IS_DEFAULT_DEF (name) || (fun && fun->after_inlining)
-  || is_a (SSA_NAME_DEF_STMT (name)))
-{
-  get_range_global (r, name, fun);
-  return;
-}
-  r.set_varying (type);
-}
-
 // --
 // global_range_query implementation.
 
@@ -373,7 +347,7 @@ global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
   if (!gimple_range_ssa_p (expr))
 return get_tree_range (r, expr, stmt);
 
-  get_range_global (r, expr);
+  gimple_range_global (r, expr);
 
   return true;
 }
-- 
2.41.0



[COMMITTED 3/5] Invoke range_of_stmt on ssa_names with no context.

2024-04-30 Thread Andrew MacLeod
If range_of_expr is called on an ssa-name with no context, ranger just 
grabs whatever the global value is.


It was pointed out we can do better than this.  If the name is in the 
IL, there is no reason for ranger to not try to fold the statement and 
see if we get a better result for it.   It removes an unnecessary 
penalty when there is no statement given for context.


This requires a tiny bit more work, sometimes for no benefit. However, 
the slowdown is also marginal.


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

Andrew
From cca3c4f2e7075fe613ac1cd67a3e1743faf33505 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Wed, 13 Mar 2024 14:13:28 -0400
Subject: [PATCH 3/9] Invoke range_of_stmt on ssa_names with no context.

Evalaute ssa-names when range_of_expr is called with no context statement
by calling range_of_stmt to get an initial value.

	* gimple-range.cc (gimple_ranger::range_of_expr): Call range_of_stmt
	when there is no context stmt.
---
 gcc/gimple-range.cc | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 4d3b1ce8588..3966cfbd14c 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -102,7 +102,15 @@ gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
   if (!stmt)
 {
   Value_Range tmp (TREE_TYPE (expr));
-  m_cache.get_global_range (r, expr);
+  // If there is no global range for EXPR yet, try to evaluate it.
+  // This call sets R to a global range regardless.
+  if (!m_cache.get_global_range (r, expr))
+	{
+	  gimple *s = SSA_NAME_DEF_STMT (expr);
+	  // Calculate a range for S if it is safe to do so.
+	  if (s && gimple_bb (s) && gimple_get_lhs (s) == expr)
+	return range_of_stmt (r, s);
+	}
   // Pick up implied context information from the on-entry cache
   // if current_bb is set.  Do not attempt any new calculations.
   if (current_bb && m_cache.block_range (tmp, current_bb, expr, false))
-- 
2.41.0



[COMMITTED 4/5] - Add range_on_entry/exit to value_query API.

2024-04-30 Thread Andrew MacLeod
It was also requested that I make range_on_entry() and range_on_exit () 
part of the fomal API for a range_query.  These are now provided along 
with the orignal range_of_expr (), range_of_stmt (), and range_on_edge 
().  The routines were already there, just not published for consumption 
in the API.


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

Andrew
From 4b955ac10f3d978a9be491d9c528da005895 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Wed, 13 Mar 2024 14:18:48 -0400
Subject: [PATCH 4/9] Add range_on_entry/exit to value_query API.

Add range_on_entry and range_on_exit to the value_query API.  These will
also work with generic trees like range_of_expr does.

	* gimple-range.cc (gimple_ranger::range_on_entry): Adjust for new
	API and support non-SSA expressions.
	(gimple_ranger::range_on_exit): Ditto.
	* gimple-range.h (range_on_entry, range_on_exit): Adjust API.
	* value-query.cc (range_query::range_on_entry): New.
	(range_query::range_on_exit): New.
	(range_query::value_on_entry): New.
	(range_query::value_on_exit): New.
	(range_query::invoke_range_of_expr): New.
	(range_query::get_tree_range): Allow stmt, on_entry or on_exit
	range queries.
	SSA_NAMES should invoke range_of_expr if possible.
	* value-query.h (class range_query): Adjust prototypes.
---
 gcc/gimple-range.cc |  14 ---
 gcc/gimple-range.h  |   4 +-
 gcc/value-query.cc  | 100 
 gcc/value-query.h   |   9 +++-
 4 files changed, 112 insertions(+), 15 deletions(-)

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 3966cfbd14c..e75e2e17dc3 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -152,11 +152,13 @@ gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
 
 // Return the range of NAME on entry to block BB in R.
 
-void
+bool
 gimple_ranger::range_on_entry (vrange &r, basic_block bb, tree name)
 {
+  if (!gimple_range_ssa_p (name))
+return get_tree_range (r, name, NULL, bb, NULL);
+
   Value_Range entry_range (TREE_TYPE (name));
-  gcc_checking_assert (gimple_range_ssa_p (name));
 
   unsigned idx;
   if ((idx = tracer.header ("range_on_entry (")))
@@ -174,16 +176,17 @@ gimple_ranger::range_on_entry (vrange &r, basic_block bb, tree name)
 
   if (idx)
 tracer.trailer (idx, "range_on_entry", true, name, r);
+  return true;
 }
 
 // Calculate the range for NAME at the end of block BB and return it in R.
 // Return false if no range can be calculated.
 
-void
+bool
 gimple_ranger::range_on_exit (vrange &r, basic_block bb, tree name)
 {
-  // on-exit from the exit block?
-  gcc_checking_assert (gimple_range_ssa_p (name));
+  if (!gimple_range_ssa_p (name))
+return get_tree_range (r, name, NULL, NULL, bb);
 
   unsigned idx;
   if ((idx = tracer.header ("range_on_exit (")))
@@ -208,6 +211,7 @@ gimple_ranger::range_on_exit (vrange &r, basic_block bb, tree name)
   
   if (idx)
 tracer.trailer (idx, "range_on_exit", true, name, r);
+  return true;
 }
 
 // Calculate a range for NAME on edge E and return it in R.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 8739ab6a2ef..167b54b2a37 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -52,8 +52,8 @@ public:
   virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
   virtual bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
   virtual bool range_on_edge (vrange &r, edge e, tree name) override;
-  void range_on_entry (vrange &r, basic_block bb, tree name);
-  void range_on_exit (vrange &r, basic_block bb, tree name);
+  virtual bool range_on_entry (vrange &r, basic_block bb, tree name) override;
+  virtual bool range_on_exit (vrange &r, basic_block bb, tree name) override;
   void export_global_ranges ();
   inline gori_compute &gori ()  { return m_cache.m_gori; }
   virtual void dump (FILE *f) override;
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index e88c8e25789..c2ab745a466 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -41,6 +41,18 @@ range_query::range_on_edge (vrange &r, edge, tree expr)
   return range_of_expr (r, expr);
 }
 
+bool
+range_query::range_on_entry (vrange &r, basic_block, tree expr)
+{
+  return range_of_expr (r, expr);
+}
+
+bool
+range_query::range_on_exit (vrange &r, basic_block, tree expr)
+{
+  return range_of_expr (r, expr);
+}
+
 bool
 range_query::range_of_stmt (vrange &r, gimple *stmt, tree name)
 {
@@ -54,6 +66,9 @@ range_query::range_of_stmt (vrange &r, gimple *stmt, tree name)
   return false;
 }
 
+// If the range of expr EXPR at STMT is a single value, return it.
+// Otherwise return NULL_TREE.
+
 tree
 range_query::value_of_expr (tree expr, gimple *stmt)
 {
@@ -76,6 +91,9 @@ range_query::value_of_expr (tree expr, gimple *stmt)
   return NULL_TREE;
 }
 
+// If the range on edge E for EXPR is a single value, return it.
+// Otherwise return NULL_TREE.
+
 tree
 range_query::value_on_edge (edge e, tree expr)
 {
@@ -94,9 +112,11 @@ range_query::value_on_edg

[COMMITTED 2/5] Fix ranger when called from SCEV.

2024-04-30 Thread Andrew MacLeod
Also during stage 3/4, we discovered that it is unsafe to call ranger 
from within SCEV.  This is because ranger uses SCEV to resolve PHIS, and 
we can end up in a bad loop under the right conditions.


The fix is for ranger's cache to NOT try to pre-evaluate PHIs (which is 
kind of waste anyway since they rarely resolve based on known incoming 
ranges to anything interesting).


Combined with this, it is now safe to make filling the block cache 
re-entrant (which can also happen if called from SCEV).


Turns out not wasting time pre-evaluating PHIs was also a time win.. so 
this patch also provides some modest speedups.


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

Andrew


From 83e95c10ed822270e39cb8da8c09f607ad65abbd Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Wed, 13 Mar 2024 14:10:41 -0400
Subject: [PATCH 2/9] Fix ranger when called from SCEV.

Do not pre-evaluate PHIs in the cache, and allow fill_block_cache to
be re-entrant.  This allows SCEV to call into ranger with a context
and not produce cycles or loops.

	* gimple-range-cache.cc (ranger_cache::get_global_range): Do not
	pre-evaluate PHI nodes from the cache.
	(ranger_cache::fill_block_cache): Make re-entrant.
---
 gcc/gimple-range-cache.cc | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index a33b7a73872..72ac2552311 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1047,7 +1047,9 @@ ranger_cache::get_global_range (vrange &r, tree name, bool ¤t_p)
   if (r.varying_p () && !cfun->after_inlining)
 	{
 	  gimple *s = SSA_NAME_DEF_STMT (name);
-	  if (gimple_get_lhs (s) == name)
+	  // Do not process PHIs as SCEV may be in use and it can
+	  // spawn cyclic lookups.
+	  if (gimple_get_lhs (s) == name && !is_a (s))
 	{
 	  if (!fold_range (r, s, get_global_range_query ()))
 		gimple_range_global (r, name);
@@ -1413,7 +1415,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 
   // At this point we shouldn't be looking at the def, entry block.
   gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun));
-  gcc_checking_assert (m_workback.length () == 0);
+  unsigned start_length = m_workback.length ();
 
   // If the block cache is set, then we've already visited this block.
   if (m_on_entry.bb_range_p (name, bb))
@@ -1500,7 +1502,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
 	}
 
   m_on_entry.set_bb_range (name, bb, block_result);
-  gcc_checking_assert (m_workback.length () == 0);
+  gcc_checking_assert (m_workback.length () == start_length);
   return;
 }
 
@@ -1512,7 +1514,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
   m_on_entry.set_bb_range (name, bb, undefined);
   gcc_checking_assert (m_update->empty_p ());
 
-  while (m_workback.length () > 0)
+  while (m_workback.length () > start_length)
 {
   basic_block node = m_workback.pop ();
   if (DEBUG_RANGE_CACHE)
-- 
2.41.0



[COMMITTED 5/5] Remove incorrect asserts.

2024-04-30 Thread Andrew MacLeod
while working on some new range-op enhancements, I found a couple of 
developing asserts that no longer apply.  This removed them.


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

Andrew
From a89de3a24d2312438848e513a0b02b480d52c81e Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Tue, 13 Feb 2024 10:07:11 -0500
Subject: [PATCH 5/9] Remove incorrect asserts.

Gimple_range_op handles builtin functions, and a couple of asserts that
are in place are incorrect in this context, so just remove them.

	* gimple-range-op.cc (gimple_range_op_handler::calc_op1): Don't
	assert that here are less than 3 operands.
	(gimple_range_op_handler::maybe_builtin_call): Simply return if
	there is no type for the function call.
---
 gcc/gimple-range-op.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 9c50c00549e..587de186db2 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -178,7 +178,6 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s)
 bool
 gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
 {
-  gcc_checking_assert (gimple_num_ops (m_stmt) < 3);
   // Give up on empty ranges.
   if (lhs_range.undefined_p ())
 return false;
@@ -1213,7 +1212,8 @@ gimple_range_op_handler::maybe_builtin_call ()
   if (func == CFN_LAST)
 return;
   tree type = gimple_range_type (call);
-  gcc_checking_assert (type);
+  if (!type)
+return;
   if (!Value_Range::supports_type_p (type))
 return;
 
-- 
2.41.0



Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Jason Merrill

On 4/30/24 07:58, Qing Zhao wrote:

The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago around 2012
for supporting several practical cases including glibc.

A GCC PR has been opened for such request at that time:

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

However, this PR was closed as WONTFIX around 2015 due to the following reason:

"there is an existing extension that makes the requested functionality possible"
i.e GCC fully supported that the zero-length array can be in a union or alone
in a structure for a long time. (though I didn't see any official documentation
on such extension)

It's reasonable to close PR53548 at that time since zero-length array extension
can be used for such purpose.

However, since GCC13, in order to improve the C/C++ security, we introduced
-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.

Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone in structs
are common code patterns in active use by the Linux kernel (and other projects).

For example, these do not error by default with GCC:

union one {
   int a;
   int b[0];
};

union two {
   int a;
   struct {
 struct { } __empty;
 int b[];
   };
};

But these do:

union three {
   int a;
   int b[];
};

struct four {
   int b[];
}

Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428

GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.

gcc/ChangeLog:

* doc/extend.texi: Add documentation for Flexible Array Members in
Unions and Flexible Array Members alone in Structures.
---
  gcc/doc/extend.texi | 34 ++
  1 file changed, 34 insertions(+)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
  * Named Address Spaces::Named address spaces.
  * Zero Length:: Zero-length arrays.
  * Empty Structures::Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible 
Array Members.
  * Variable Length:: Arrays whose length is computed at run time.
  * Variadic Macros:: Macros with a variable number of arguments.
  * Escaped Newlines::Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures 
are part
  of the language.  G++ treats empty structures as if they had a single
  member of type @code{char}.
  
+@node Flexible Array Members in Unions

+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of


"If the only member of a union is a flexible array member"


+such union is zero.


"such a union"


+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.


"The size of such a structure is zero"


+
  @node Variable Length
  @section Arrays of Variable Length
  @cindex variable-length arrays




Re: [PATCH v3 4/4] Update the C FE routine "add_flexible_array_elts_to_size" C++ FE routine "layout_var_decl" to handle the cases when the DECL is union.

2024-04-30 Thread Jason Merrill

On 4/30/24 07:58, Qing Zhao wrote:

Add testing cases to test the _bos for flexible array members in unions
or alone in structures.

gcc/c/ChangeLog:

* c-decl.cc (add_flexible_array_elts_to_size): Handle the cases
when the DECL is union.

gcc/cp/ChangeLog:

* decl.cc (layout_var_decl): Handle the cases when the DECL is
union with a flexible array member initializer.

gcc/testsuite/ChangeLog:

* c-c++-common/fam-in-union-alone-in-struct-bos-1.c: New test.
* c-c++-common/fam-in-union-alone-in-struct-bos.c: New test.
---
  gcc/c/c-decl.cc   | 32 +++--
  gcc/cp/decl.cc| 33 --
  .../fam-in-union-alone-in-struct-bos-1.c  | 66 +++
  .../fam-in-union-alone-in-struct-bos.c| 45 +
  4 files changed, 162 insertions(+), 14 deletions(-)
  create mode 100644 
gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-bos-1.c
  create mode 100644 
gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-bos.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 947f3cd589eb..59302c5cfb1f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5337,9 +5337,9 @@ zero_length_array_type_p (const_tree type)
  }
  
  /* INIT is a constructor that forms DECL's initializer.  If the final

-   element initializes a flexible array field, add the size of that
-   initializer to DECL's size.  */
-
+   element initializes a flexible array field, adjust the size of the
+   DECL with the initializer based on whether the DECL is a union or
+   a structure.  */
  static void
  add_flexible_array_elts_to_size (tree decl, tree init)
  {
@@ -5348,15 +5348,33 @@ add_flexible_array_elts_to_size (tree decl, tree init)
if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
  return;
  
+  bool is_decl_type_union = (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);


In both C and C++ front-ends, I don't see any reason for this variable 
to be declared outside the if, since it's only used inside it.


It's not clear to me that it's needed at all since it's only used once, 
but if you prefer to have it, please move it inside the if.



+
elt = CONSTRUCTOR_ELTS (init)->last ().value;
type = TREE_TYPE (elt);
if (flexible_array_member_type_p (type))
  {
complete_array_type (&type, elt, false);
-  DECL_SIZE (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
-  DECL_SIZE_UNIT (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type));
+  /* For a structure, add the size of the initializer to the DECL's
+size.  */
+  if (!is_decl_type_union)
+   {
+ DECL_SIZE (decl)
+   = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
+ DECL_SIZE_UNIT (decl)
+   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
+ TYPE_SIZE_UNIT (type));
+   }
+  /* For a union, the DECL's size is the maximum of the current size
+and the size of the initializer.  */
+  else
+   {
+ DECL_SIZE (decl)
+   = size_binop (MAX_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
+ DECL_SIZE_UNIT (decl)
+   = size_binop (MAX_EXPR, DECL_SIZE_UNIT (decl),
+ TYPE_SIZE_UNIT (type));
+   }
  }
  }
  
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 9a91c6f80da1..0ea3ef165b66 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -6555,8 +6555,9 @@ layout_var_decl (tree decl)
}
  }
  
-  /* If the final element initializes a flexible array field, add the size of

- that initializer to DECL's size.  */
+  /* If the final element initializes a flexible array field, adjust
+ the size of the DECL with the initializer based on whether the
+ DECL is a union or a structure.  */
if (type != error_mark_node
&& DECL_INITIAL (decl)
&& TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR
@@ -6568,6 +6569,7 @@ layout_var_decl (tree decl)
&& tree_int_cst_equal (DECL_SIZE (decl), TYPE_SIZE (type)))
  {
constructor_elt &elt = CONSTRUCTOR_ELTS (DECL_INITIAL (decl))->last ();
+  bool is_decl_type_union = (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
if (elt.index)
{
  tree itype = TREE_TYPE (elt.index);
@@ -6577,11 +6579,28 @@ layout_var_decl (tree decl)
  && TREE_CODE (vtype) == ARRAY_TYPE
  && COMPLETE_TYPE_P (vtype))
{
- DECL_SIZE (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (vtype));
- DECL_SIZE_UNIT (decl)
-   = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
- TYPE_SIZE_UNIT (vtype));
+ /* For a structure, add the size of the initializer to the DECL's
+size.  */
+ if (!is_decl_type_union)
+   {
+ DECL_SIZE (decl)
+   = siz

Re: [wwwdocs] Porting-to-14: Mention new pragma GCC Target behavior

2024-04-30 Thread Jakub Jelinek
On Tue, Apr 30, 2024 at 11:12:30PM +0200, Martin Jambor wrote:
> Would the following then perhaps describe the situation accurately?
> Note that I have moved the whole thing to C++ section because it seems
> porting issues in C because of this are quite unlikely.
> 
> Michal, I assume that the file where this issue happened was written in
> C++, right?
> 
> Martin
> 
> 
> 
> diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html
> index c825a68e..1e67b0b3 100644
> --- a/htdocs/gcc-14/porting_to.html
> +++ b/htdocs/gcc-14/porting_to.html
> @@ -514,6 +514,51 @@ be included explicitly when compiling with GCC 14:
>  
>  
>  
> +Pragma GCC Target now affects preprocessor 
> symbols

I'd use lowercase Target here
> +
> +
> +The behavior of pragma GCC Target and specifically how it affects ISA

And here as well, perhaps even #pragma GCC target.

Otherwise LGTM.

> +macros has changed in GCC 14.  In GCC 13 and older, the GCC
> +target pragma defined and undefined corresponding ISA macros in
> +C when using integrated preprocessor during compilation but not when
> +preprocessor was invoked as a separate step or when using -save-temps.
> +In C++ the ISA macro definitions were performed in a way which did not
> +have any actual effect.
> +
> +In GCC 14 C++ behaves like C with integrated preprocessing in earlier
> +versions. Moreover, in both languages ISA macros are defined and
> +undefined as expected when preprocessing separately from compilation.
> +
> +
> +This can lead to different behavior, especially in C++.  For example,
> +functions the C++ snippet below will be (silently) compiled for an
> +incorrect instruction set by GCC 14.
> +
> +
> +  #if ! __AVX2__
> +  #pragma GCC push_options
> +  #pragma GCC target("avx2")
> +  #endif
> +
> +  /* Code to be compiled for AVX2. */
> +
> +  /* With GCC 14, __AVX2__ here will always be defined and pop_options
> +  never called. */
> +  #if ! __AVX2__
> +  #pragma GCC pop_options
> +  #endif
> +
> +  /* With GCC 14, all following functions will be compiled for AVX2
> +  which was not intended. */
> +
> +
> +
> +The fix in this case would be to remember
> +whether pop_options needs to be performed in a new
> +user-defined macro.
> +
> +
> +
>  
>  
>  

Jakub



Re: [PATCH v3 4/4] Update the C FE routine "add_flexible_array_elts_to_size" C++ FE routine "layout_var_decl" to handle the cases when the DECL is union.

2024-04-30 Thread Qing Zhao


On Apr 30, 2024, at 15:29, Jason Merrill  wrote:

On 4/30/24 07:58, Qing Zhao wrote:
Add testing cases to test the _bos for flexible array members in unions
or alone in structures.
gcc/c/ChangeLog:
* c-decl.cc (add_flexible_array_elts_to_size): Handle the cases
when the DECL is union.
gcc/cp/ChangeLog:
* decl.cc (layout_var_decl): Handle the cases when the DECL is
union with a flexible array member initializer.
gcc/testsuite/ChangeLog:
* c-c++-common/fam-in-union-alone-in-struct-bos-1.c: New test.
* c-c++-common/fam-in-union-alone-in-struct-bos.c: New test.
---
 gcc/c/c-decl.cc   | 32 +++--
 gcc/cp/decl.cc| 33 --
 .../fam-in-union-alone-in-struct-bos-1.c  | 66 +++
 .../fam-in-union-alone-in-struct-bos.c| 45 +
 4 files changed, 162 insertions(+), 14 deletions(-)
 create mode 100644 
gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-bos-1.c
 create mode 100644 
gcc/testsuite/c-c++-common/fam-in-union-alone-in-struct-bos.c
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 947f3cd589eb..59302c5cfb1f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5337,9 +5337,9 @@ zero_length_array_type_p (const_tree type)
 }
   /* INIT is a constructor that forms DECL's initializer.  If the final
-   element initializes a flexible array field, add the size of that
-   initializer to DECL's size.  */
-
+   element initializes a flexible array field, adjust the size of the
+   DECL with the initializer based on whether the DECL is a union or
+   a structure.  */
 static void
 add_flexible_array_elts_to_size (tree decl, tree init)
 {
@@ -5348,15 +5348,33 @@ add_flexible_array_elts_to_size (tree decl, tree init)
   if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
 return;
 +  bool is_decl_type_union = (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);

In both C and C++ front-ends, I don't see any reason for this variable to be 
declared outside the if, since it's only used inside it.

It's not clear to me that it's needed at all since it's only used once, but if 
you prefer to have it, please move it inside the if.

Okay, will do that.

thanks.

Qing

+
   elt = CONSTRUCTOR_ELTS (init)->last ().value;
   type = TREE_TYPE (elt);
   if (flexible_array_member_type_p (type))
 {
   complete_array_type (&type, elt, false);
-  DECL_SIZE (decl)
- = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
-  DECL_SIZE_UNIT (decl)
- = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type));
+  /* For a structure, add the size of the initializer to the DECL's
+  size.  */
+  if (!is_decl_type_union)
+ {
+   DECL_SIZE (decl)
+ = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
+   DECL_SIZE_UNIT (decl)
+ = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
+   TYPE_SIZE_UNIT (type));
+ }
+  /* For a union, the DECL's size is the maximum of the current size
+  and the size of the initializer.  */
+  else
+ {
+   DECL_SIZE (decl)
+ = size_binop (MAX_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
+   DECL_SIZE_UNIT (decl)
+ = size_binop (MAX_EXPR, DECL_SIZE_UNIT (decl),
+   TYPE_SIZE_UNIT (type));
+ }
 }
 }

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 9a91c6f80da1..0ea3ef165b66 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -6555,8 +6555,9 @@ layout_var_decl (tree decl)
  }
 }
 -  /* If the final element initializes a flexible array field, add the size of
- that initializer to DECL's size.  */
+  /* If the final element initializes a flexible array field, adjust
+ the size of the DECL with the initializer based on whether the
+ DECL is a union or a structure.  */
   if (type != error_mark_node
   && DECL_INITIAL (decl)
   && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR
@@ -6568,6 +6569,7 @@ layout_var_decl (tree decl)
   && tree_int_cst_equal (DECL_SIZE (decl), TYPE_SIZE (type)))
 {
   constructor_elt &elt = CONSTRUCTOR_ELTS (DECL_INITIAL (decl))->last ();
+  bool is_decl_type_union = (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
   if (elt.index)
  {
tree itype = TREE_TYPE (elt.index);
@@ -6577,11 +6579,28 @@ layout_var_decl (tree decl)
&& TREE_CODE (vtype) == ARRAY_TYPE
&& COMPLETE_TYPE_P (vtype))
  {
-   DECL_SIZE (decl)
- = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (vtype));
-   DECL_SIZE_UNIT (decl)
- = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
-   TYPE_SIZE_UNIT (vtype));
+   /* For a structure, add the size of the initializer to the DECL's
+  size.  */
+   if (!is_decl_type_union)
+ {
+   DECL_SIZE (decl)
+ = size_binop (PLUS_EXPR, DECL_SIZE (decl),
+   TYPE_SIZE (vtype));
+   DECL_SIZE_UNIT (decl)
+ = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
+   TYPE_SIZE_UNIT (vtype));
+ }
+   /* a union, the DECL's size is the maximum of the current size
+  and the size of the initializer.  */
+   else
+ {
+   DECL_SIZE (

Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Qing Zhao


On Apr 30, 2024, at 15:27, Jason Merrill  wrote:

On 4/30/24 07:58, Qing Zhao wrote:
The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago around 2012
for supporting several practical cases including glibc.
A GCC PR has been opened for such request at that time:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
However, this PR was closed as WONTFIX around 2015 due to the following reason:
"there is an existing extension that makes the requested functionality possible"
i.e GCC fully supported that the zero-length array can be in a union or alone
in a structure for a long time. (though I didn't see any official documentation
on such extension)
It's reasonable to close PR53548 at that time since zero-length array extension
can be used for such purpose.
However, since GCC13, in order to improve the C/C++ security, we introduced
-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.
Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone in structs
are common code patterns in active use by the Linux kernel (and other projects).
For example, these do not error by default with GCC:
union one {
  int a;
  int b[0];
};
union two {
  int a;
  struct {
struct { } __empty;
int b[];
  };
};
But these do:
union three {
  int a;
  int b[];
};
struct four {
  int b[];
}
Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428
GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.
gcc/ChangeLog:
* doc/extend.texi: Add documentation for Flexible Array Members in
Unions and Flexible Array Members alone in Structures.
---
 gcc/doc/extend.texi | 34 ++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length:: Zero-length arrays.
 * Empty Structures::Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible 
Array Members.
 * Variable Length:: Arrays whose length is computed at run time.
 * Variadic Macros:: Macros with a variable number of arguments.
 * Escaped Newlines::Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures 
are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of

It’s for the following case:

union with_fam_3 {
  char a[];
  int b[];
}

And also include:  (the only member of a union is a flexible array member as 
you mentioned below)

union with_fam_1 {
  char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:

"If the only member of a union is a flexible array member”


+such union is zero.

"such a union"

Okay.


+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.

"The size of such a structure is zero"

Okay.

thanks.

Qing

+
 @node Variable Length
 @section Arrays of Variable Length
 @cindex variable-length arrays



Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Qing Zhao


On Apr 30, 2024, at 15:45, Qing Zhao  wrote:



 gcc/doc/extend.texi | 34 ++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length:: Zero-length arrays.
 * Empty Structures::Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible 
Array Members.
 * Variable Length:: Arrays whose length is computed at run time.
 * Variadic Macros:: Macros with a variable number of arguments.
 * Escaped Newlines::Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures 
are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of

It’s for the following case:

union with_fam_3 {
  char a[];
  int b[];
}

And also include:  (the only member of a union is a flexible array member as 
you mentioned below)

union with_fam_1 {
  char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:

"If the only member of a union is a flexible array member”

How about the following wording?

"If every member of a union is flexible array member, the size of”

Qing


+such union is zero.

"such a union"

Okay.


+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.

"The size of such a structure is zero"

Okay.

thanks.

Qing

+
 @node Variable Length
 @section Arrays of Variable Length
 @cindex variable-length arrays



Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Jason Merrill

On 4/30/24 14:45, Qing Zhao wrote:




On Apr 30, 2024, at 15:27, Jason Merrill  wrote:

On 4/30/24 07:58, Qing Zhao wrote:

The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago 
around 2012

for supporting several practical cases including glibc.
A GCC PR has been opened for such request at that time:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
However, this PR was closed as WONTFIX around 2015 due to the 
following reason:
"there is an existing extension that makes the requested 
functionality possible"
i.e GCC fully supported that the zero-length array can be in a union 
or alone
in a structure for a long time. (though I didn't see any official 
documentation

on such extension)
It's reasonable to close PR53548 at that time since zero-length array 
extension

can be used for such purpose.
However, since GCC13, in order to improve the C/C++ security, we 
introduced

-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.
Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone in 
structs
are common code patterns in active use by the Linux kernel (and other 
projects).

For example, these do not error by default with GCC:
union one {
  int a;
  int b[0];
};
union two {
  int a;
  struct {
struct { } __empty;
int b[];
  };
};
But these do:
union three {
  int a;
  int b[];
};
struct four {
  int b[];
}
Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428
GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.
gcc/ChangeLog:
* doc/extend.texi: Add documentation for Flexible Array Members in
Unions and Flexible Array Members alone in Structures.
---
 gcc/doc/extend.texi | 34 ++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length:: Zero-length arrays.
 * Empty Structures::    Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array 
Members.
+* Flexible Array Members alone in Structures::  Structures with only 
Flexible Array Members.

 * Variable Length:: Arrays whose length is computed at run time.
 * Variadic Macros:: Macros with a variable number of arguments.
 * Escaped Newlines::    Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty 
structures are part

 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of


It’s for the following case:

union with_fam_3 {
   char a[];
   int b[];
}

And also include:  (the only member of a union is a flexible array 
member as you mentioned below)


union with_fam_1 {
   char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:


"If the only member of a union is a flexible array member”


Makes sense, but then it should be "members" both times rather than 
"members" and then "member".


Jason



Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Jason Merrill

On 4/30/24 14:49, Qing Zhao wrote:




On Apr 30, 2024, at 15:45, Qing Zhao  wrote:




 gcc/doc/extend.texi | 34 ++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length:: Zero-length arrays.
 * Empty Structures::    Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array 
Members.
+* Flexible Array Members alone in Structures::  Structures with 
only Flexible Array Members.

 * Variable Length:: Arrays whose length is computed at run time.
 * Variadic Macros:: Macros with a variable number of arguments.
 * Escaped Newlines::    Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty 
structures are part

 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of


It’s for the following case:

union with_fam_3 {
  char a[];
  int b[];
}

And also include:  (the only member of a union is a flexible array 
member as you mentioned below)


union with_fam_1 {
  char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:


"If the only member of a union is a flexible array member”


How about the following wording?

"If every member of a union is flexible array member, the size of”


"is a flexible array member", sure.

Jason



Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Qing Zhao


> On Apr 30, 2024, at 15:52, Jason Merrill  wrote:
> 
> On 4/30/24 14:49, Qing Zhao wrote:
>>> On Apr 30, 2024, at 15:45, Qing Zhao  wrote:
>>> 
>>> 
>>> 
>  gcc/doc/extend.texi | 34 ++
>  1 file changed, 34 insertions(+)
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 7b54a241a7bf..cba98c8aadd7 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
>  * Named Address Spaces::Named address spaces.
>  * Zero Length:: Zero-length arrays.
>  * Empty Structures::Structures with no members.
> +* Flexible Array Members in Unions::  Unions with Flexible Array Members.
> +* Flexible Array Members alone in Structures::  Structures with only 
> Flexible Array Members.
>  * Variable Length:: Arrays whose length is computed at run time.
>  * Variadic Macros:: Macros with a variable number of arguments.
>  * Escaped Newlines::Slightly looser rules for escaped newlines.
> @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty 
> structures are part
>  of the language.  G++ treats empty structures as if they had a single
>  member of type @code{char}.
>  +@node Flexible Array Members in Unions
> +@section Unions with Flexible Array Members
> +@cindex unions with flexible array members
> +@cindex unions with FAMs
> +
> +GCC permits a C99 flexible array member (FAM) to be in a union:
> +
> +@smallexample
> +union with_fam @{
> +  int a;
> +  int b[];
> +@};
> +@end smallexample
> +
> +If all the members of a union are flexible array member, the size of
>>> 
>>> It’s for the following case:
>>> 
>>> union with_fam_3 {
>>>   char a[];
>>>   int b[];
>>> }
>>> 
>>> And also include:  (the only member of a union is a flexible array member 
>>> as you mentioned below)
>>> 
>>> union with_fam_1 {
>>>   char a[];
>>> }
>>> 
>>> So, I think the original sentence:
>>> 
>>> “If all the members of a union are flexible array member, the size of”
>>> 
>>> Should be better than the below:
 
 "If the only member of a union is a flexible array member”
>> How about the following wording?
>> "If every member of a union is flexible array member, the size of”
> 
> "is a flexible array member", sure.

Okay, will update the doc.

Thanks a lot.

Qing
> 
> Jason
> 



Re: [PATCH] RISC-V: Add testcase for pr114734

2024-04-30 Thread Jeff Law




On 4/30/24 2:36 PM, Patrick O'Neill wrote:

gcc/testsuite/ChangeLog:

PR middle-end/114734

* gcc.target/riscv/rvv/autovec/pr114734.c: New test.

OK
jeff



Re: [PATCH v3 1/4] Allow flexible array members in unions and alone in structures [PR53548]

2024-04-30 Thread Kees Cook
On Tue, Apr 30, 2024 at 05:51:20PM -0400, Jason Merrill wrote:
> On 4/30/24 14:45, Qing Zhao wrote:
> > 
> > 
> > > On Apr 30, 2024, at 15:27, Jason Merrill  wrote:
> > > 
> > > On 4/30/24 07:58, Qing Zhao wrote:
> > > > The request for GCC to accept that the C99 flexible array member can be
> > > > in a union or alone in a structure has been made a long time ago
> > > > around 2012
> > > > for supporting several practical cases including glibc.
> > > > A GCC PR has been opened for such request at that time:
> > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
> > > > However, this PR was closed as WONTFIX around 2015 due to the
> > > > following reason:
> > > > "there is an existing extension that makes the requested
> > > > functionality possible"
> > > > i.e GCC fully supported that the zero-length array can be in a
> > > > union or alone
> > > > in a structure for a long time. (though I didn't see any
> > > > official documentation
> > > > on such extension)
> > > > It's reasonable to close PR53548 at that time since zero-length
> > > > array extension
> > > > can be used for such purpose.
> > > > However, since GCC13, in order to improve the C/C++ security, we
> > > > introduced
> > > > -fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
> > > > usages from C/C++ source code. As a result, zero-length arrays 
> > > > eventually
> > > > will be replaced by C99 flexiable array member completely.
> > > > Therefore, GCC needs to explicitly allow such extensions directly for 
> > > > C99
> > > > flexible arrays, since flexable array member in unions or alone
> > > > in structs
> > > > are common code patterns in active use by the Linux kernel (and
> > > > other projects).
> > > > For example, these do not error by default with GCC:
> > > > union one {
> > > >   int a;
> > > >   int b[0];
> > > > };
> > > > union two {
> > > >   int a;
> > > >   struct {
> > > > struct { } __empty;
> > > > int b[];
> > > >   };
> > > > };
> > > > But these do:
> > > > union three {
> > > >   int a;
> > > >   int b[];
> > > > };
> > > > struct four {
> > > >   int b[];
> > > > }
> > > > Clang has supported such extensions since March, 2024
> > > > https://github.com/llvm/llvm-project/pull/84428
> > > > GCC should also support such extensions. This will allow for
> > > > a seamless transition for code bases away from zero-length arrays 
> > > > without
> > > > losing existing code patterns.
> > > > gcc/ChangeLog:
> > > > * doc/extend.texi: Add documentation for Flexible Array Members in
> > > > Unions and Flexible Array Members alone in Structures.
> > > > ---
> > > >  gcc/doc/extend.texi | 34 ++
> > > >  1 file changed, 34 insertions(+)
> > > > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> > > > index 7b54a241a7bf..cba98c8aadd7 100644
> > > > --- a/gcc/doc/extend.texi
> > > > +++ b/gcc/doc/extend.texi
> > > > @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
> > > >  * Named Address Spaces::Named address spaces.
> > > >  * Zero Length:: Zero-length arrays.
> > > >  * Empty Structures::    Structures with no members.
> > > > +* Flexible Array Members in Unions::  Unions with Flexible
> > > > Array Members.
> > > > +* Flexible Array Members alone in Structures::  Structures with
> > > > only Flexible Array Members.
> > > >  * Variable Length:: Arrays whose length is computed at run time.
> > > >  * Variadic Macros:: Macros with a variable number of arguments.
> > > >  * Escaped Newlines::    Slightly looser rules for escaped newlines.
> > > > @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++,
> > > > empty structures are part
> > > >  of the language.  G++ treats empty structures as if they had a single
> > > >  member of type @code{char}.
> > > >  +@node Flexible Array Members in Unions
> > > > +@section Unions with Flexible Array Members
> > > > +@cindex unions with flexible array members
> > > > +@cindex unions with FAMs
> > > > +
> > > > +GCC permits a C99 flexible array member (FAM) to be in a union:
> > > > +
> > > > +@smallexample
> > > > +union with_fam @{
> > > > +  int a;
> > > > +  int b[];
> > > > +@};
> > > > +@end smallexample
> > > > +
> > > > +If all the members of a union are flexible array member, the size of
> > 
> > It’s for the following case:
> > 
> > union with_fam_3 {
> >    char a[];
> >    int b[];
> > }
> > 
> > And also include:  (the only member of a union is a flexible array
> > member as you mentioned below)
> > 
> > union with_fam_1 {
> >    char a[];
> > }
> > 
> > So, I think the original sentence:
> > 
> > “If all the members of a union are flexible array member, the size of”
> > 
> > Should be better than the below:
> > > 
> > > "If the only member of a union is a flexible array member”
> 
> Makes sense, but then it should be "members" both times rather than
> "members" and then "member".

"If every member of a union is a flexible array, the size ..." ?

-- 
Kees Cook


[PATCH] aarch64: Add vector popcount besides QImode [PR113859]

2024-04-30 Thread Pengxuan Zheng
This patch improves GCC’s vectorization of __builtin_popcount for aarch64 target
by adding popcount patterns for vector modes besides QImode, i.e., HImode,
SImode and DImode.

With this patch, we now generate the following for HImode:
  cnt v1.16b, v.16b
  uaddlp  v2.8h, v1.16b

For SImode, we generate:
  cnt v1.16b, v.16b
  uaddlp  v2.8h, v1.16b
  uaddlp  v3.4s, v2.8h

For V2DI, we generate:
  cnt v1.16b, v.16b
  uaddlp  v2.8h, v1.16b
  uaddlp  v3.4s, v2.8h
  uaddlp  v4.2d, v3.4s

gcc/ChangeLog:

PR target/113859
* config/aarch64/aarch64-simd.md (popcount2): New define_expand.

gcc/testsuite/ChangeLog:

PR target/113859
* gcc.target/aarch64/popcnt-vec.c: New test.

Signed-off-by: Pengxuan Zheng 
---
 gcc/config/aarch64/aarch64-simd.md| 40 
 gcc/testsuite/gcc.target/aarch64/popcnt-vec.c | 48 +++
 2 files changed, 88 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/popcnt-vec.c

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index f8bb973a278..093c32ee8ff 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3540,6 +3540,46 @@ (define_insn "popcount2"
   [(set_attr "type" "neon_cnt")]
 )
 
+(define_expand "popcount2"
+  [(set (match_operand:VQN 0 "register_operand" "=w")
+(popcount:VQN (match_operand:VQN 1 "register_operand" "w")))]
+  "TARGET_SIMD"
+  {
+rtx v = gen_reg_rtx (V16QImode);
+rtx v1 = gen_reg_rtx (V16QImode);
+emit_move_insn (v, gen_lowpart (V16QImode, operands[1]));
+emit_insn (gen_popcountv16qi2 (v1, v));
+if (mode == V8HImode)
+  {
+/* For V8HI, we generate:
+cnt v1.16b, v.16b
+uaddlp  v2.8h, v1.16b */
+emit_insn (gen_aarch64_uaddlpv16qi (operands[0], v1));
+DONE;
+  }
+rtx v2 = gen_reg_rtx (V8HImode);
+emit_insn (gen_aarch64_uaddlpv16qi (v2, v1));
+if (mode == V4SImode)
+  {
+/* For V4SI, we generate:
+cnt v1.16b, v.16b
+uaddlp  v2.8h, v1.16b
+uaddlp  v3.4s, v2.8h */
+emit_insn (gen_aarch64_uaddlpv8hi (operands[0], v2));
+DONE;
+  }
+/* For V2DI, we generate:
+cnt v1.16b, v.16b
+uaddlp  v2.8h, v1.16b
+uaddlp  v3.4s, v2.8h
+uaddlp  v4.2d, v3.4s */
+rtx v3 = gen_reg_rtx (V4SImode);
+emit_insn (gen_aarch64_uaddlpv8hi (v3, v2));
+emit_insn (gen_aarch64_uaddlpv4si (operands[0], v3));
+DONE;
+  }
+)
+
 ;; 'across lanes' max and min ops.
 
 ;; Template for outputting a scalar, so we can create __builtins which can be
diff --git a/gcc/testsuite/gcc.target/aarch64/popcnt-vec.c 
b/gcc/testsuite/gcc.target/aarch64/popcnt-vec.c
new file mode 100644
index 000..4c9a1b95990
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/popcnt-vec.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* This function should produce cnt v.16b. */
+void
+bar (unsigned char *__restrict b, unsigned char *__restrict d)
+{
+  for (int i = 0; i < 1024; i++)
+d[i] = __builtin_popcount (b[i]);
+}
+
+/* This function should produce cnt v.16b and uaddlp (Add Long Pairwise). */
+void
+bar1 (unsigned short *__restrict b, unsigned short *__restrict d)
+{
+  for (int i = 0; i < 1024; i++)
+d[i] = __builtin_popcount (b[i]);
+}
+
+/* This function should produce cnt v.16b and 2 uaddlp (Add Long Pairwise). */
+void
+bar2 (unsigned int *__restrict b, unsigned int *__restrict d)
+{
+  for (int i = 0; i < 1024; i++)
+d[i] = __builtin_popcount (b[i]);
+}
+
+/* This function should produce cnt v.16b and 3 uaddlp (Add Long Pairwise). */
+void
+bar3 (unsigned long long *__restrict b, unsigned long long *__restrict d)
+{
+  for (int i = 0; i < 1024; i++)
+d[i] = __builtin_popcountll (b[i]);
+}
+
+/* SLP
+ This function should produce cnt v.16b and 3 uaddlp (Add Long Pairwise). */
+void
+bar4 (unsigned long long *__restrict b, unsigned long long *__restrict d)
+{
+  d[0] = __builtin_popcountll (b[0]);
+  d[1] = __builtin_popcountll (b[1]);
+}
+
+/* { dg-final { scan-assembler-not {\tbl\tpopcount} } } */
+/* { dg-final { scan-assembler-times {cnt\t} 5 } } */
+/* { dg-final { scan-assembler-times {uaddlp\t} 9 } } */
+/* { dg-final { scan-assembler-times {ldr\tq} 5 } } */
-- 
2.17.1



[PATCH] MATCH: Add some more value_replacement simplifications (a != 0 ? expr : 0) to match

2024-04-30 Thread Andrew Pinski
This adds a few more of what is currently done in phiopt's value_replacement
to match. I noticed this when I was hooking up phiopt's value_replacement
code to use match and disabling the old code. But this can be done
independently from the hooking up phiopt's value_replacement as phiopt
is already hooked up for simplified versions already.

/* a != 0 ? a / b : 0  -> a / b iff b is nonzero. */
/* a != 0 ? a * b : 0 -> a * b */
/* a != 0 ? a & b : 0 -> a & b */

We prefer the `cond ? a : 0` forms to allow optimization of `a * cond` which
uses that form.

Bootstrapped and tested on x86_64-linux-gnu with no regressions.

PR treee-optimization/114894

gcc/ChangeLog:

* match.pd (`a != 0 ? a / b : 0`): New pattern.
(`a != 0 ? a * b : 0`): New pattern.
(`a != 0 ? a & b : 0`): New pattern.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/phi-opt-value-5.c: New test.

Signed-off-by: Andrew Pinski 
---
 gcc/match.pd  | 18 +
 .../gcc.dg/tree-ssa/phi-opt-value-5.c | 39 +++
 2 files changed, 57 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-5.c

diff --git a/gcc/match.pd b/gcc/match.pd
index d401e7503e6..03a03c31233 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4290,6 +4290,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cond (eq @0 integer_all_onesp) @1 (op:c@2 @1 @0))
@2))
 
+/* a != 0 ? a / b : 0  -> a / b iff b is nonzero. */
+(for op (trunc_div ceil_div floor_div round_div exact_div)
+ (simplify
+  (cond (ne @0 integer_zerop) (op@2 @3 @1) integer_zerop )
+   (if (bitwise_equal_p (@0, @3)
+&& tree_expr_nonzero_p (@1))
+@2)))
+
+/* Note we prefer the != case here
+   as (a != 0) * (a * b) will generate that version. */
+/* a != 0 ? a * b : 0 -> a * b */
+/* a != 0 ? a & b : 0 -> a & b */
+(for op (mult bit_and)
+ (simplify
+  (cond (ne @0 integer_zerop) (op:c@2 @1 @3) integer_zerop)
+  (if (bitwise_equal_p (@0, @3))
+   @2)))
+
 /* Simplifications of shift and rotates.  */
 
 (for rotate (lrotate rrotate)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-5.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-5.c
new file mode 100644
index 000..8062eb19b11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-5.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* PR treee-optimization/114894 */
+/* Phi-OPT should be able to optimize these without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-phiopt3 
-fdump-tree-optimized -fno-tree-sink" } */
+
+int fmul1(int a, int b)
+{
+  int c = a * b;
+  if (a != 0)
+return c;
+  return 0;
+}
+
+
+int fand1(int a, int b)
+{
+  int c = a & b;
+  if (a != 0)
+return c;
+  return 0;
+}
+
+
+void g(int);
+
+int fdiv1(int a, int b)
+{
+  int d = b|1;
+  g(d);
+  int c = a / d;
+  return a != 0 ? c : 0;
+}
+
+/* fdiv1 requires until later than phiopt2 to be able to detect that
+   d is non-zero. to be able to remove the conditional.  */
+/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "goto" "phiopt3" } } */
+/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */
+
-- 
2.43.0



Re: [RFA][RISC-V] Improve constant synthesis for constants with 2 bits set

2024-04-30 Thread Andrew Waterman
On Tue, Apr 30, 2024 at 8:54 PM Jeff Law  wrote:
>
>
> In doing some preparation work for using zbkb's pack instructions for
> constant synthesis I figured it would be wise to get a sense of how well
> our constant synthesis is actually working and address any clear issues.
>
> So the first glaring inefficiency is in our handling of constants with a
> small number of bits set.  Let's start with just two bits set.   There
> are 2016 distinct constants in that space (rv64).  With Zbs enabled the
> absolute worst we should ever do is two instructions (bseti+bseti).  Yet
> we have 503 cases where we're generating 3+ instructions when there's
> just two bits set in the constant.  A constant like 0x80001000
> generates 4 instructions!
>
> This patch adds bseti (and indirectly binvi if we needed it) as a first
> class citizen for constant synthesis.  There's two components to this
> change.
>
> First, we can't generate an IOR with a constant like (1 << 45) as an
> operand.  The IOR/XOR define_insn is in riscv.md.  The constant argument
> for those patterns must match an arith_operand which means its not
> really usable for generating bseti directly in the cases we care about
> (at least one of the bits will be in the 32..63 range and thus won't
> match arith_operand).
>
> We have a few things we could do.  One would be to extend the existing
> pattern to incorporate bseti cases.  But I suspect folks like the
> separation of the base architecture (riscv.md) from the Zb* extensions
> (bitmanip.md).  We could also try to generate the RTL for bseti
> directly, bypassing gen_fmt_ee (which forces undesirable constants into
> registers based on the predicate of the appropriate define_insn).
> Neither of these seemed particularly appealing to me.
>
> So what I've done instead is to make ior/xor a define_expand and have
> the expander allow a wider set of constant operands when Zbs is enabled.
>   That allows us to keep the bulk of Zb* support inside bitmanip.md and
> continue to use gen_fmt_ee in the constant synthesis paths.

Seems like a clean solution to me.

>
> Note the code generation in this case is designed to first set as many
> bits as we can with lui, then with addi since those can both set
> multiple bits at a time.  If there are any residual bits left to set we
> can emit bseti instructions up to the current cost ceiling.
>
> This results in fixing all of the 503 2-bit set cases where we emitted
> too many instructions.  It also significantly helps other scenarios with
> more bits set.
>
> The testcase I'm including verifies the number of instructions we
> generate for the full set of 2016 possible cases.  Obviously this won't
> be possible as we increase the number of bits (there are something like
> 48k cases with just 3 bits set).
>
> Build and regression tested on rv64gc.  OK for the trunk?
>
>
> THanks,
> Jeff
>


[PATCH] c++/modules: Fix dangling pointer with imported_temploid_friends

2024-04-30 Thread Nathaniel Shead
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk (and
later 14.2)?  I don't think making it a GTY root is necessary but I felt
perhaps better to be safe than sorry.

Potentially another approach would be to use DECL_UID instead like how
entity_map does; would that be preferable?

-- >8 --

I got notified by Linaro CI and by checking testresults that there seems
to be some occasional failures in tpl-friend-4_b.C on some architectures
and standards modes since r15-59-gb5f6a56940e708.  I haven't been able
to reproduce but looking at the backtrace I suspect the issue is that
we're adding to the 'imported_temploid_friend' map a decl that is
ultimately discarded, which then has its address reused by a later decl
causing a failure in the assert in 'set_originating_module'.

This patch attempts to fix the issue in two ways: by ensuring that we
only store the decl if we know it's a new decl (and hence won't be
discarded), and by making the imported_temploid_friends map a GTY root
so that even if the decl does get discarded later the address isn't
reused.

gcc/cp/ChangeLog:

* module.cc (imported_temploid_friends): Mark GTY, and...
(init_modules): ...allocate from GGC.
(trees_in::decl_value): Only write to imported_temploid_friends
for new decls.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/module.cc | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 5b8ff5bc483..37d38bb9654 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -2731,7 +2731,7 @@ static keyed_map_t *keyed_table;
need to be attached to the same module as the temploid.  This maps
these decls to the temploid they are instantiated them, as there is
no other easy way to get this information.  */
-static hash_map *imported_temploid_friends;
+static GTY(()) hash_map *imported_temploid_friends;
 
 //
 /* Tree streaming.   The tree streaming is very specific to the tree
@@ -8327,7 +8327,8 @@ trees_in::decl_value ()
   if (TREE_CODE (inner) == FUNCTION_DECL
   || TREE_CODE (inner) == TYPE_DECL)
 if (tree owner = tree_node ())
-  imported_temploid_friends->put (decl, owner);
+  if (is_new)
+   imported_temploid_friends->put (decl, owner);
 
   /* Regular typedefs will have a NULL TREE_TYPE at this point.  */
   unsigned tdef_flags = 0;
@@ -20523,7 +20524,7 @@ init_modules (cpp_reader *reader)
   entity_map = new entity_map_t (EXPERIMENT (1, 400));
   vec_safe_reserve (entity_ary, EXPERIMENT (1, 400));
   imported_temploid_friends
-   = new hash_map (EXPERIMENT (1, 400));
+   = hash_map::create_ggc (EXPERIMENT (1, 400));
 }
 
 #if CHECKING_P
-- 
2.43.2



Re: [PATCH] s390: testsuite: Fix zero_bits_compound-1.c

2024-04-30 Thread Andreas Krebbel
On 4/30/24 10:32, Stefan Schulze Frielinghaus wrote:
> Starting with r12-2731-g96146e61cd7aee we do not generate code like
> 
> _5 = (unsigned int) c_2(D);
> i_6 = _5 << 8;
> _7 = _5 << 20;
> i_8 = i_6 | _7;
> 
> anymore but instead
> 
> _5 = (unsigned int) c_2(D);
> _3 = _5 * 1048832;
> 
> which leads finally to slightly different assembly code where we
> previously ended up for z10 or newer with
> 
> lr  %r1,%r2
> sll %r1,8
> rosbg   %r1,%r2,32,43,20
> llgfr   %r2,%r1
> br  %r14
> 
> and now
> 
> lr  %r1,%r2
> sll %r1,12
> ar  %r2,%r1
> risbg   %r2,%r2,35,128+55,8
> br  %r14
> 
> The zero-extend materializes via risbg for which the pattern contains an
> "and" which is why the test fails.  Thus, instead of scanning for RTL
> expressions rather scan for assembler instructions for s390.
> ---
>  Ok for mainline?

Ok. Thanks!

Andreas

> 
>  gcc/testsuite/gcc.dg/zero_bits_compound-1.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/zero_bits_compound-1.c 
> b/gcc/testsuite/gcc.dg/zero_bits_compound-1.c
> index e71594911b2..f1e267e0fb0 100644
> --- a/gcc/testsuite/gcc.dg/zero_bits_compound-1.c
> +++ b/gcc/testsuite/gcc.dg/zero_bits_compound-1.c
> @@ -39,4 +39,5 @@ unsigned long bar (unsigned char c)
>  }
>  
>  /* Check that no pattern containing an AND expression was used.  */
> -/* { dg-final { scan-assembler-not "\\(and:" } } */
> +/* { dg-final { scan-assembler-not "\\(and:" { target { ! { s390*-*-* } } } 
> } } */
> +/* { dg-final { scan-assembler-not "\\tng?rk?\\t" { target { s390*-*-* } } } 
> } */



  1   2   >