Re: c: tree: target: C2x (...) function prototypes and va_start relaxation

2022-11-03 Thread Xi Ruoyao via Gcc-patches
On Fri, 2022-10-21 at 22:15 +, Joseph Myers wrote:

> * config/loongarch/loongarch.cc
> (loongarch_setup_incoming_varargs): Likewise.

Hi,

One test fails on loongarch64-linux-gnu:

FAIL: gcc.dg/c2x-stdarg-4.c execution test

I've not got time to debug the issue yet.

-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH v3] LoongArch: Optimize immediate load.

2022-11-03 Thread Lulu Cheng



在 2022/11/4 上午10:56, Xi Ruoyao 写道:

On Fri, 2022-11-04 at 10:33 +0800, Lulu Cheng wrote:

在 2022/11/4 上午10:22, Xi Ruoyao 写道:

On Tue, 2022-11-01 at 20:04 +0800, Lulu Cheng wrote:

gcc/ChangeLog:

  * config/loongarch/constraints.md (x): New constraint.
  * config/loongarch/loongarch.cc (struct loongarch_address_info):
  Adds a method to load the immediate 32 to 64 bit field.
  (struct loongarch_integer_op): Define a new member curr_value,
  that records the value of the number stored in the destination
  register immediately after the current instruction has run.
  (LARCH_MAX_INTEGER_OPS): Define this macro as 3.
  (LU32I_B): Move to the loongarch.h.
  (LU52I_B): Likewise.
  (loongarch_build_integer): Adds a method to load the immediate
  32 to 63 bits.
  (loongarch_move_integer): Likewise.

We need to mention "call set_unique_reg_note" here because it seems the
key to resolve the issue.

During debugging, I found the problem because the source register and
destination register of the lu32i.d instruction are the same. As a
result, during loop2_invariant pass, the destination register of
lu32i.d is used twice, so the instructions after this instruction will
not be brought out of the loop. Therefore, I combined lu32i.d and
lu52i.d into one template, which avoids the situation that the same
register is used twice. It is not split into two instructions until
loop2_invariant has been optimized. So I don't think
"set_unique_reg_note" plays a decisive role in this optimization.

It's better to mention this logic in the commit message then, to prevent
others from misunderstandings like mine.

Again the code change LGTM and I've tested it with --with-build-
config=bootstrap-ubsan.


Ok, I'll describe this logic.

Thanks!


Otherwise LGTM.


  (loongarch_print_operand_reloc): Modifying comment information.
  * config/loongarch/loongarch.h (LU32I_B): Move from loongarch.cc.
  (LU52I_B): Likewise.
  (HWIT_UC_0x): New macro.
  (HI32_OPERAND): New macro.
  * config/loongarch/loongarch.md (load_hi32): New template.
  * config/loongarch/predicates.md (const_hi32_operand): Determines
  whether the value is an immediate number that has a value of only
  the higher 32 bits.
  (hi32_mask_operand): Immediately counts the mask of 32 to 61 bits.




Re: [PATCH v3] LoongArch: Optimize immediate load.

2022-11-03 Thread Xi Ruoyao via Gcc-patches
On Fri, 2022-11-04 at 10:33 +0800, Lulu Cheng wrote:
> 
> 在 2022/11/4 上午10:22, Xi Ruoyao 写道:
> > On Tue, 2022-11-01 at 20:04 +0800, Lulu Cheng wrote:
> > > gcc/ChangeLog:
> > > 
> > >  * config/loongarch/constraints.md (x): New constraint.
> > >  * config/loongarch/loongarch.cc (struct loongarch_address_info):
> > >  Adds a method to load the immediate 32 to 64 bit field.
> > >  (struct loongarch_integer_op): Define a new member curr_value,
> > >  that records the value of the number stored in the destination
> > >  register immediately after the current instruction has run.
> > >  (LARCH_MAX_INTEGER_OPS): Define this macro as 3.
> > >  (LU32I_B): Move to the loongarch.h.
> > >  (LU52I_B): Likewise.
> > >  (loongarch_build_integer): Adds a method to load the immediate
> > >  32 to 63 bits.
> > >  (loongarch_move_integer): Likewise.
> > We need to mention "call set_unique_reg_note" here because it seems the
> > key to resolve the issue.
> 
> During debugging, I found the problem because the source register and 
> destination register of the lu32i.d instruction are the same. As a
> result, during loop2_invariant pass, the destination register of
> lu32i.d is used twice, so the instructions after this instruction will
> not be brought out of the loop. Therefore, I combined lu32i.d and
> lu52i.d into one template, which avoids the situation that the same
> register is used twice. It is not split into two instructions until
> loop2_invariant has been optimized. So I don't think
> "set_unique_reg_note" plays a decisive role in this optimization.

It's better to mention this logic in the commit message then, to prevent
others from misunderstandings like mine.

Again the code change LGTM and I've tested it with --with-build-
config=bootstrap-ubsan.

> > 
> > Otherwise LGTM.
> > 
> > >  (loongarch_print_operand_reloc): Modifying comment information.
> > >  * config/loongarch/loongarch.h (LU32I_B): Move from loongarch.cc.
> > >  (LU52I_B): Likewise.
> > >  (HWIT_UC_0x): New macro.
> > >  (HI32_OPERAND): New macro.
> > >  * config/loongarch/loongarch.md (load_hi32): New template.
> > >  * config/loongarch/predicates.md (const_hi32_operand): Determines
> > >  whether the value is an immediate number that has a value of only
> > >  the higher 32 bits.
> > >  (hi32_mask_operand): Immediately counts the mask of 32 to 61 
> > > bits.
> 

-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH v3] LoongArch: Optimize immediate load.

2022-11-03 Thread Lulu Cheng



在 2022/11/4 上午10:22, Xi Ruoyao 写道:

On Tue, 2022-11-01 at 20:04 +0800, Lulu Cheng wrote:

gcc/ChangeLog:

 * config/loongarch/constraints.md (x): New constraint.
 * config/loongarch/loongarch.cc (struct loongarch_address_info):
 Adds a method to load the immediate 32 to 64 bit field.
 (struct loongarch_integer_op): Define a new member curr_value,
 that records the value of the number stored in the destination
 register immediately after the current instruction has run.
 (LARCH_MAX_INTEGER_OPS): Define this macro as 3.
 (LU32I_B): Move to the loongarch.h.
 (LU52I_B): Likewise.
 (loongarch_build_integer): Adds a method to load the immediate
 32 to 63 bits.
 (loongarch_move_integer): Likewise.

We need to mention "call set_unique_reg_note" here because it seems the
key to resolve the issue.


During debugging, I found the problem because the source register and 
destination


register of the lu32i.d instruction are the same. As a result, during 
loop2_invariant pass,


the destination register of lu32i.d is used twice, so the instructions 
after this instruction


will not be brought out of the loop.

Therefore, I combined lu32i.d and lu52i.d into one template, which 
avoids the situation


that the same register is used twice. It is not split into two 
instructions until loop2_invariant has


been optimized. So I don't think "set_unique_reg_note" plays a decisive 
role in this optimization.




Otherwise LGTM.


 (loongarch_print_operand_reloc): Modifying comment information.
 * config/loongarch/loongarch.h (LU32I_B): Move from loongarch.cc.
 (LU52I_B): Likewise.
 (HWIT_UC_0x): New macro.
 (HI32_OPERAND): New macro.
 * config/loongarch/loongarch.md (load_hi32): New template.
 * config/loongarch/predicates.md (const_hi32_operand): Determines
 whether the value is an immediate number that has a value of only
 the higher 32 bits.
 (hi32_mask_operand): Immediately counts the mask of 32 to 61 bits.




Re: [PATCH v3] LoongArch: Optimize immediate load.

2022-11-03 Thread Xi Ruoyao via Gcc-patches
On Tue, 2022-11-01 at 20:04 +0800, Lulu Cheng wrote:
> gcc/ChangeLog:
> 
> * config/loongarch/constraints.md (x): New constraint.
> * config/loongarch/loongarch.cc (struct loongarch_address_info):
> Adds a method to load the immediate 32 to 64 bit field.
> (struct loongarch_integer_op): Define a new member curr_value,
> that records the value of the number stored in the destination
> register immediately after the current instruction has run.
> (LARCH_MAX_INTEGER_OPS): Define this macro as 3.
> (LU32I_B): Move to the loongarch.h.
> (LU52I_B): Likewise.
> (loongarch_build_integer): Adds a method to load the immediate
> 32 to 63 bits.
> (loongarch_move_integer): Likewise.

We need to mention "call set_unique_reg_note" here because it seems the
key to resolve the issue.

Otherwise LGTM.

> (loongarch_print_operand_reloc): Modifying comment information.
> * config/loongarch/loongarch.h (LU32I_B): Move from loongarch.cc.
> (LU52I_B): Likewise.
> (HWIT_UC_0x): New macro.
> (HI32_OPERAND): New macro.
> * config/loongarch/loongarch.md (load_hi32): New template.
> * config/loongarch/predicates.md (const_hi32_operand): Determines
> whether the value is an immediate number that has a value of only
> the higher 32 bits.
> (hi32_mask_operand): Immediately counts the mask of 32 to 61 bits.

-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH v3] RISC-V modified add3 for large stack frame optimization [PR105733]

2022-11-03 Thread Kito Cheng via Gcc-patches
I would like to see some benchmark results instead of just a simple
case, to make sure everything is alright, the add pattern is used
literally anywhere, my most worry is the clobber might bring some
negative impact like cause register pressure estimation get higher,
and then result worse code gen.

Dynamic instruction count is good enough and no cycle count or
complete spec score.

On Thu, Nov 3, 2022 at 5:57 PM Kevin Lee  wrote:
>
> This is the identical patch with 
> https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604814.html, but with 
> the correct plaintext format.
>
> >The loop still seems a bit odd which may point to further improvements
> >that could be made to this patch.  Consider this fragment of the loop:
>
> Thank you for the review Jeff! I am currently looking into this issue
> in a different patch. I'll come back with some improvement.
>
> gcc/ChangeLog:
>Jim Wilson 
>Michael Collison 
>Kevin Lee 
>
> * config/riscv/predicates.md (const_lui_operand): New Predicate.
> (add_operand): Ditto.
> (reg_or_const_int_operand): Ditto.
> * config/riscv/riscv-protos.h (riscv_eliminable_reg): New
>function.
> * config/riscv/riscv-selftests.cc (calculate_x_in_sequence):
>Consider Parallel insns.
> * config/riscv/riscv.cc (riscv_eliminable_reg): New function.
> (riscv_adjust_libcall_cfi_prologue): Use gen_rtx_SET and
>gen_rtx_fmt_ee instead of gen_add3_insn.
> (riscv_adjust_libcall_cfi_epilogue): Ditto.
> * config/riscv/riscv.md (addsi3): Remove.
> (add3): New instruction for large stack frame
>optimization.
> (add3_internal): Ditto.
> (adddi3): Remove.
> (add3_internal2): New instruction for insns generated in
>the prologue and epilogue pass.
> ---
>  gcc/config/riscv/predicates.md  | 13 +
>  gcc/config/riscv/riscv-protos.h |  1 +
>  gcc/config/riscv/riscv-selftests.cc |  3 ++
>  gcc/config/riscv/riscv.cc   | 20 +--
>  gcc/config/riscv/riscv.md   | 84 -
>  5 files changed, 104 insertions(+), 17 deletions(-)
>
> diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> index c2ff41bb0fd..3149f7227ac 100644
> --- a/gcc/config/riscv/predicates.md
> +++ b/gcc/config/riscv/predicates.md
> @@ -35,6 +35,14 @@
>(ior (match_operand 0 "arith_operand")
> (match_operand 0 "lui_operand")))
>
> +(define_predicate "const_lui_operand"
> +  (and (match_code "const_int")
> +   (match_test "(INTVAL (op) & 0xFFF) == 0 && INTVAL (op) != 0")))
> +
> +(define_predicate "add_operand"
> +  (ior (match_operand 0 "arith_operand")
> +   (match_operand 0 "const_lui_operand")))
> +
>  (define_predicate "const_csr_operand"
>(and (match_code "const_int")
> (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
> @@ -59,6 +67,11 @@
>(ior (match_operand 0 "const_0_operand")
> (match_operand 0 "register_operand")))
>
> +;; For use in adds, when adding to an eliminable register.
> +(define_predicate "reg_or_const_int_operand"
> +  (ior (match_code "const_int")
> +   (match_operand 0 "register_operand")))
> +
>  ;; Only use branch-on-bit sequences when the mask is not an ANDI immediate.
>  (define_predicate "branch_on_bit_operand"
>(and (match_code "const_int")
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index 5a718bb62b4..9348ac71956 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -63,6 +63,7 @@ extern void riscv_expand_conditional_move (rtx, rtx, rtx, 
> rtx_code, rtx, rtx);
>  extern rtx riscv_legitimize_call_address (rtx);
>  extern void riscv_set_return_address (rtx, rtx);
>  extern bool riscv_expand_block_move (rtx, rtx, rtx);
> +extern bool riscv_eliminable_reg (rtx);
>  extern rtx riscv_return_addr (int, rtx);
>  extern poly_int64 riscv_initial_elimination_offset (int, int);
>  extern void riscv_expand_prologue (void);
> diff --git a/gcc/config/riscv/riscv-selftests.cc 
> b/gcc/config/riscv/riscv-selftests.cc
> index 636874ebc0f..50457db708e 100644
> --- a/gcc/config/riscv/riscv-selftests.cc
> +++ b/gcc/config/riscv/riscv-selftests.cc
> @@ -116,6 +116,9 @@ calculate_x_in_sequence (rtx reg)
>rtx pat = PATTERN (insn);
>rtx dest = SET_DEST (pat);
>
> +  if (GET_CODE (pat) == PARALLEL)
> +   dest = SET_DEST (XVECEXP (pat, 0, 0));
> +
>if (GET_CODE (pat) == CLOBBER)
> continue;
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 32f9ef9ade9..de9344b37a3 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -4686,6 +4686,16 @@ riscv_initial_elimination_offset (int from, int to)
>return src - dest;
>  }
>
> +/* Return true if X is a register that will be eliminated later on.  */
> +bool
> +riscv_eliminable_reg (rtx x)
> +{
> +  return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM
> +  

[PATCH v3] RISC-V modified add3 for large stack frame optimization [PR105733]

2022-11-03 Thread Kevin Lee
This is the identical patch with 
https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604814.html, but with 
the correct plaintext format. 

>The loop still seems a bit odd which may point to further improvements 
>that could be made to this patch.  Consider this fragment of the loop:

Thank you for the review Jeff! I am currently looking into this issue
in a different patch. I'll come back with some improvement.
 
gcc/ChangeLog:
   Jim Wilson 
   Michael Collison 
   Kevin Lee 
   
* config/riscv/predicates.md (const_lui_operand): New Predicate.
(add_operand): Ditto.
(reg_or_const_int_operand): Ditto.
* config/riscv/riscv-protos.h (riscv_eliminable_reg): New 
   function.
* config/riscv/riscv-selftests.cc (calculate_x_in_sequence):
   Consider Parallel insns.
* config/riscv/riscv.cc (riscv_eliminable_reg): New function.
(riscv_adjust_libcall_cfi_prologue): Use gen_rtx_SET and
   gen_rtx_fmt_ee instead of gen_add3_insn.
(riscv_adjust_libcall_cfi_epilogue): Ditto.
* config/riscv/riscv.md (addsi3): Remove.
(add3): New instruction for large stack frame
   optimization.
(add3_internal): Ditto.
(adddi3): Remove.
(add3_internal2): New instruction for insns generated in
   the prologue and epilogue pass.
---
 gcc/config/riscv/predicates.md  | 13 +
 gcc/config/riscv/riscv-protos.h |  1 +
 gcc/config/riscv/riscv-selftests.cc |  3 ++
 gcc/config/riscv/riscv.cc   | 20 +--
 gcc/config/riscv/riscv.md   | 84 -
 5 files changed, 104 insertions(+), 17 deletions(-)

diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index c2ff41bb0fd..3149f7227ac 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -35,6 +35,14 @@
   (ior (match_operand 0 "arith_operand")
(match_operand 0 "lui_operand")))
 
+(define_predicate "const_lui_operand"
+  (and (match_code "const_int")
+   (match_test "(INTVAL (op) & 0xFFF) == 0 && INTVAL (op) != 0")))
+
+(define_predicate "add_operand"
+  (ior (match_operand 0 "arith_operand")
+   (match_operand 0 "const_lui_operand")))
+
 (define_predicate "const_csr_operand"
   (and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 31)")))
@@ -59,6 +67,11 @@
   (ior (match_operand 0 "const_0_operand")
(match_operand 0 "register_operand")))
 
+;; For use in adds, when adding to an eliminable register.
+(define_predicate "reg_or_const_int_operand"
+  (ior (match_code "const_int")
+   (match_operand 0 "register_operand")))
+
 ;; Only use branch-on-bit sequences when the mask is not an ANDI immediate.
 (define_predicate "branch_on_bit_operand"
   (and (match_code "const_int")
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 5a718bb62b4..9348ac71956 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -63,6 +63,7 @@ extern void riscv_expand_conditional_move (rtx, rtx, rtx, 
rtx_code, rtx, rtx);
 extern rtx riscv_legitimize_call_address (rtx);
 extern void riscv_set_return_address (rtx, rtx);
 extern bool riscv_expand_block_move (rtx, rtx, rtx);
+extern bool riscv_eliminable_reg (rtx);
 extern rtx riscv_return_addr (int, rtx);
 extern poly_int64 riscv_initial_elimination_offset (int, int);
 extern void riscv_expand_prologue (void);
diff --git a/gcc/config/riscv/riscv-selftests.cc 
b/gcc/config/riscv/riscv-selftests.cc
index 636874ebc0f..50457db708e 100644
--- a/gcc/config/riscv/riscv-selftests.cc
+++ b/gcc/config/riscv/riscv-selftests.cc
@@ -116,6 +116,9 @@ calculate_x_in_sequence (rtx reg)
   rtx pat = PATTERN (insn);
   rtx dest = SET_DEST (pat);
 
+  if (GET_CODE (pat) == PARALLEL)
+   dest = SET_DEST (XVECEXP (pat, 0, 0));
+
   if (GET_CODE (pat) == CLOBBER)
continue;
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 32f9ef9ade9..de9344b37a3 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4686,6 +4686,16 @@ riscv_initial_elimination_offset (int from, int to)
   return src - dest;
 }
 
+/* Return true if X is a register that will be eliminated later on.  */
+bool
+riscv_eliminable_reg (rtx x)
+{
+  return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM
+  || REGNO (x) == ARG_POINTER_REGNUM
+  || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
+  && REGNO (x) <= LAST_VIRTUAL_REGISTER));
+}
+
 /* Implement RETURN_ADDR_RTX.  We do not support moving back to a
previous frame.  */
 
@@ -4887,8 +4897,9 @@ riscv_adjust_libcall_cfi_prologue ()
   }
 
   /* Debug info for adjust sp.  */
-  adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
-stack_pointer_rtx, GEN_INT (-saved_size));
+  adjust_sp_rtx = gen_rtx_SET (stack_pointer_rtx,
+   gen_rtx_fmt_ee (PLUS, GET_MODE 

[PATCH] Optimize VEC_PERM_EXPR with same permutation index and operation [PR98167]

2022-11-03 Thread Hongyu Wang via Gcc-patches
Hi,

This is a follow-up patch for PR98167

The sequence
 c1 = VEC_PERM_EXPR (a, a, mask)
 c2 = VEC_PERM_EXPR (b, b, mask)
 c3 = c1 op c2
can be optimized to
 c = a op b
 c3 = VEC_PERM_EXPR (c, c, mask)
for all integer vector operation, and float operation with
full permutation.

Bootstrapped & regrtested on x86_64-pc-linux-gnu.

Ok for trunk?

gcc/ChangeLog:

PR target/98167
* match.pd: New perm + vector op patterns for int and fp vector.

gcc/testsuite/ChangeLog:

PR target/98167
* gcc.target/i386/pr98167.c: New test.
---
 gcc/match.pd| 49 +
 gcc/testsuite/gcc.target/i386/pr98167.c | 44 ++
 2 files changed, 93 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr98167.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 194ba8f5188..b85ad34f609 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -8189,3 +8189,52 @@ and,
  (bit_and (negate @0) integer_onep@1)
  (if (!TYPE_OVERFLOW_SANITIZED (type))
   (bit_and @0 @1)))
+
+/* Optimize
+   c1 = VEC_PERM_EXPR (a, a, mask)
+   c2 = VEC_PERM_EXPR (b, b, mask)
+   c3 = c1 op c2
+   -->
+   c = a op b
+   c3 = VEC_PERM_EXPR (c, c, mask)
+   For all integer non-div operations.  */
+(for op (plus minus mult bit_and bit_ior bit_xor
+lshift rshift)
+ (simplify
+  (op (vec_perm @0 @0 VECTOR_CST@2) (vec_perm @1 @1 VECTOR_CST@2))
+(if (VECTOR_INTEGER_TYPE_P (type))
+ (vec_perm (op @0 @1) (op @0 @1) @2
+
+/* Similar for float arithmetic when permutation constant covers
+   all vector elements.  */
+(for op (plus minus mult)
+ (simplify
+  (op (vec_perm @0 @0 VECTOR_CST@2) (vec_perm @1 @1 VECTOR_CST@2))
+(if (VECTOR_FLOAT_TYPE_P (type))
+ (with
+  {
+   tree perm_cst = @2;
+   vec_perm_builder builder;
+   bool full_perm_p = false;
+   if (tree_to_vec_perm_builder (, perm_cst))
+ {
+   /* Create a vec_perm_indices for the integer vector.  */
+   int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
+   vec_perm_indices sel (builder, 1, nelts);
+
+   /* Check if perm indices covers all vector elements.  */
+   int count = 0, i, j;
+   for (i = 0; i < nelts; i++)
+ for (j = 0; j < nelts; j++)
+   {
+ if (sel[j].to_constant () == i)
+   {
+ count++;
+ break;
+   }
+   }
+   full_perm_p = count == nelts;
+ }
+   }
+   (if (full_perm_p)
+   (vec_perm (op @0 @1) (op @0 @1) @2))
diff --git a/gcc/testsuite/gcc.target/i386/pr98167.c 
b/gcc/testsuite/gcc.target/i386/pr98167.c
new file mode 100644
index 000..40e0ac11332
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98167.c
@@ -0,0 +1,44 @@
+/* PR target/98167 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx2" } */
+
+/* { dg-final { scan-assembler-times "vpshufd\t" 8 } } */
+/* { dg-final { scan-assembler-times "vpermilps\t" 3 } } */
+
+#define VEC_PERM_4 \
+  2, 3, 1, 0
+#define VEC_PERM_8 \
+  4, 5, 6, 7, 3, 2, 1, 0
+#define VEC_PERM_16 \
+  8, 9, 10, 11, 12, 13, 14, 15, 7, 6, 5, 4, 3, 2, 1, 0
+
+#define TYPE_PERM_OP(type, size, op, name) \
+  typedef type v##size##s##type __attribute__ ((vector_size(4*size))); \
+  v##size##s##type type##foo##size##i_##name (v##size##s##type a, \
+ v##size##s##type b) \
+  { \
+v##size##s##type a1 = __builtin_shufflevector (a, a, \
+  VEC_PERM_##size); \
+v##size##s##type b1 = __builtin_shufflevector (b, b, \
+  VEC_PERM_##size); \
+return a1 op b1; \
+  }
+
+#define INT_PERMS(op, name) \
+  TYPE_PERM_OP (int, 4, op, name) \
+
+#define FP_PERMS(op, name) \
+  TYPE_PERM_OP (float, 4, op, name) \
+
+INT_PERMS (+, add)
+INT_PERMS (-, sub)
+INT_PERMS (*, mul)
+INT_PERMS (|, ior)
+INT_PERMS (^, xor)
+INT_PERMS (&, and)
+INT_PERMS (<<, shl)
+INT_PERMS (>>, shr)
+FP_PERMS (+, add)
+FP_PERMS (-, sub)
+FP_PERMS (*, mul)
+
-- 
2.18.1



Re: [PATCH RFA] input: add get_source_text_between

2022-11-03 Thread David Malcolm via Gcc-patches
On Thu, 2022-11-03 at 15:59 -0400, Jason Merrill via Gcc-patches wrote:
> Tested x86_64-pc-linux-gnu, OK for trunk?
> 
> -- >8 --
> 
> The c++-contracts branch uses this to retrieve the source form of the
> contract predicate, to be returned by contract_violation::comment().
> 
> gcc/ChangeLog:
> 
> * input.cc (get_source_text_between): New fn.
> * input.h (get_source_text_between): Declare.
> ---
>  gcc/input.h  |  1 +
>  gcc/input.cc | 76
> 
>  2 files changed, 77 insertions(+)
> 
> diff --git a/gcc/input.h b/gcc/input.h
> index 11c571d076f..f18769950b5 100644
> --- a/gcc/input.h
> +++ b/gcc/input.h
> @@ -111,6 +111,7 @@ class char_span
>  };
>  
>  extern char_span location_get_source_line (const char *file_path,
> int line);
> +extern char *get_source_text_between (location_t, location_t);
>  
>  extern bool location_missing_trailing_newline (const char
> *file_path);
>  
> diff --git a/gcc/input.cc b/gcc/input.cc
> index a28abfac5ac..9b36356338a 100644
> --- a/gcc/input.cc
> +++ b/gcc/input.cc
> @@ -949,6 +949,82 @@ location_get_source_line (const char *file_path,
> int line)
>    return char_span (buffer, len);
>  }
>  
> +/* Return a copy of the source text between two locations.  The
> caller is
> +   responsible for freeing the return value.  */
> +
> +char *
> +get_source_text_between (location_t start, location_t end)
> +{
> +  expanded_location expstart =
> +    expand_location_to_spelling_point (start,
> LOCATION_ASPECT_START);
> +  expanded_location expend =
> +    expand_location_to_spelling_point (end, LOCATION_ASPECT_FINISH);
> +
> +  /* If the locations are in different files or the end comes before
> the
> + start, abort and return nothing.  */

I don't like the use of the term "abort" here, as it suggests to me the
use of abort(3).  Maybe "bail out" instead?


> +  if (!expstart.file || !expend.file)
> +    return NULL;
> +  if (strcmp (expstart.file, expend.file) != 0)
> +    return NULL;
> +  if (expstart.line > expend.line)
> +    return NULL;
> +  if (expstart.line == expend.line
> +  && expstart.column > expend.column)
> +    return NULL;

We occasionally use the convention that
  (column == 0)
means "the whole line".  Probably should detect that case and bail out
early for it.


> +
> +  /* For a single line we need to trim both edges.  */
> +  if (expstart.line == expend.line)
> +    {
> +  char_span line = location_get_source_line (expstart.file,
> expstart.line);
> +  if (line.length () < 1)
> +   return NULL;
> +  int s = expstart.column - 1;
> +  int l = expend.column - s;

Can we please avoid lower-case L "ell" for variable names, as it looks
so similar to the numeral for one.  "len" would be more descriptive
here.


> +  if (line.length () < (size_t)expend.column)
> +   return NULL;
> +  return line.subspan (s, l).xstrdup ();
> +    }
> +
> +  struct obstack buf_obstack;
> +  obstack_init (_obstack);
> +
> +  /* Loop through all lines in the range and append each to buf; may
> trim
> + parts of the start and end lines off depending on column
> values.  */
> +  for (int l = expstart.line; l <= expend.line; ++l)

Again, please let's not have a var named "l".  Maybe "iter_line" as
that's what is being done?

> +    {
> +  char_span line = location_get_source_line (expstart.file, l);
> +  if (line.length () < 1 && (l != expstart.line && l !=
> expend.line))

...especially as I *think* the first comparison is against numeral one,
whereas comparisons two and three are against lower-case ell, but I'm
having to squint at the font in my email client to be sure :-/

> +   continue;
> +
> +  /* For the first line in the range, only start at
> expstart.column */
> +  if (l == expstart.line)
> +   {
> + if (expstart.column == 0)
> +   return NULL;
> + if (line.length () < (size_t)expstart.column - 1)
> +   return NULL;
> + line = line.subspan (expstart.column - 1,
> +  line.length() - expstart.column + 1);
> +   }
> +  /* For the last line, don't go past expend.column */
> +  else if (l == expend.line)
> +   {
> + if (line.length () < (size_t)expend.column)
> +   return NULL;
> + line = line.subspan (0, expend.column);
> +   }
> +
> +  obstack_grow (_obstack, line.get_buffer (), line.length
> ());

Is this accumulating the trailing newline characters into the
buf_obstack?  I *think* it is, but it seems worth a comment for each of
the three cases (first line, intermediate line, last line).

> +    }
> +
> +  /* NUL-terminate and finish the buf obstack.  */
> +  obstack_1grow (_obstack, 0);
> +  const char *buf = (const char *) obstack_finish (_obstack);
> +
> +  /* TODO should we collapse/trim newlines and runs of spaces?  */
> +  return xstrdup (buf);
> +}
> +

Do you have test coverage for this from the DejaGnu side?  If not, you
could 

Re: [PATCH] cgraph_node: Remove redundant section clearing

2022-11-03 Thread Jeff Law via Gcc-patches



On 11/3/22 14:47, Bernhard Reutner-Fischer via Gcc-patches wrote:

Ok for trunk if testing passes?

gcc/ChangeLog:

* cgraph.cc (cgraph_node::make_local): Remove redundant set_section.
* multiple_target.cc (create_dispatcher_calls): Likewise.


OK after testing passes.

jeff




RFH: attr target_clones default assembler name ignored?

2022-11-03 Thread Bernhard Reutner-Fischer via Gcc-patches
Hi!

I encounter a problem/pilot error when using the target_clones
attribute.

The symptom is that the default clone is not renamed in the output and
thus conflicts with the (proper) global name which is used for the
ifunc:

$ nl -ba < /tmp/cc3jBX3x.s | grep sub1
12  .type   __m_MOD_sub1, @function
13  __m_MOD_sub1:
35  .size   __m_MOD_sub1, .-__m_MOD_sub1
...
87  __m_MOD_sub1.resolver:
95  movl$__m_MOD_sub1.avx, %eax
   104  movl$__m_MOD_sub1, %eax
   105  movl$__m_MOD_sub1.sse, %edx
   110  .size   __m_MOD_sub1.resolver, .-__m_MOD_sub1.resolver
   111  .globl  __m_MOD_sub1
   112  .type   __m_MOD_sub1, @gnu_indirect_function
   113  .set__m_MOD_sub1,__m_MOD_sub1.resolver

I think that line 13 and 104 should talk about __m_MOD_sub1.default.

AFAICT the target_clones attr is built well.
gcc/multiple_target.cc:expand_target_clones() adds the required
attr "target" "default"
and properly does:
(gdb) p old_name
$6 = 0x76dfc090 "__m_MOD_sub1"
(gdb) call debug_tree ( DECL_ASSEMBLER_NAME (decl) )
 
(gdb) n
301   && DECL_RTL_SET_P (decl))
(gdb) n
300   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
(gdb) n
304   SET_DECL_ASSEMBLER_NAME (decl, name);
(gdb) n
305   if (alias)
(gdb) call debug_tree ( DECL_ASSEMBLER_NAME (decl) )
 

So if that would have been used for real, all would be fine i think.

But still, that name is somehow not used, see fnname:
#0  assemble_start_function (decl=, 
fnname=fnname@entry=0x76dfc090 "__m_MOD_sub1") at 
../../../src/gcc-13.mine/gcc/varasm.cc:1979
#1  0x00bec182 in rest_of_handle_final () at 
../../../src/gcc-13.mine/gcc/final.cc:4238
#2  (anonymous namespace)::pass_final::execute (this=) at 
../../../src/gcc-13.mine/gcc/final.cc:4320
#3  0x00e9da3b in execute_one_pass (pass=) at ../../../src/gcc-13.mine/gcc/passes.cc:2644
#4  0x00e9e300 in execute_pass_list_1 (pass=) at ../../../src/gcc-13.mine/gcc/passes.cc:2744
#5  0x00e9e312 in execute_pass_list_1 (pass=) at ../../../src/gcc-13.mine/gcc/passes.cc:2745
#6  0x00e9e312 in execute_pass_list_1 (pass=) at ../../../src/gcc-13.mine/gcc/passes.cc:2745
#7  0x00e9e339 in execute_pass_list (fn=0x76dfe000, pass=) at ../../../src/gcc-13.mine/gcc/passes.cc:2755
#8  0x00aef806 in cgraph_node::expand (this=) at ../../../src/gcc-13.mine/gcc/context.h:48
#9  cgraph_node::expand (this=) at 
../../../src/gcc-13.mine/gcc/cgraphunit.cc:1787

I'm attaching the testcase, to be compiled with:
$ ./gfortran -B. -o /tmp/out.o -c 
/scratch/src/gcc-13.mine/gcc/testsuite/gfortran.dg/attr_target_clones-1.f90 -O1 
-fdump-tree-optimized
/tmp/ccQU3Vkf.s: Assembler messages:
/tmp/ccQU3Vkf.s:113: Error: symbol `__m_MOD_sub1' is already defined
respectively
$ ./gfortran -B. -o /tmp/out.s -S 
/scratch/src/gcc-13.mine/gcc/testsuite/gfortran.dg/attr_target_clones-1.f90 -O1 
-fdump-tree-optimized
and a git diff, which is not to be mistaken for a patch.

I'd be grateful for help to understand why/who chooses to pick an unpleasant
name, and, primarily, how to avoid that problem.

Thoughts or hints?
TIA!
PS: Should i have rather asked on gcc-help?
! { dg-do compile }
! { dg-options "-O1 -fdump-tree-optimized" }
!
! Test __attribute__ ((target_clones ("foo", "bar")))
!
module m
  implicit none
!!GCC$ ATTRIBUTES target_clones("avx2", "sse2","default") :: sub2
contains
  subroutine sub1()
!GCC$ ATTRIBUTES target_clones("avx", "sse","default") :: sub1
print *, 4321
  end
!  subroutine sub2()
!print *, 2345
!  end
end module m
! { dg-final { scan-tree-dump-times {void * __m_MOD_sub1.resolver ()} 
"optimized" 1 } }
! { dg-final { scan-tree-dump-times {void __m_MOD_sub1.avx ()} "optimized" 1 } }
! { dg-final { scan-tree-dump-times {void __m_MOD_sub1.sse ()} "optimized" 1 } }
! { dg-final { scan-tree-dump-times {void __m_MOD_sub1.default ()} "optimized" 
1 } }
! { dg-final { scan-tree-dump-not {void sub1 ()} "optimized" } }

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 0f9b2ced4c2..ca70b79db57 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "options.h"
 #include "tree.h"
+#include "fold-const.h"
 #include "gfortran.h"
 #include "stringpool.h"
 #include "match.h"
@@ -35,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #define gfc_get_data_variable() XCNEW (gfc_data_variable)
 #define gfc_get_data_value() XCNEW (gfc_data_value)
 #define gfc_get_data() XCNEW (gfc_data)
-
+#pragma GCC optimize("O0")
 
 static bool set_binding_label (const char **, const char *, int);
 
@@ -11709,6 +11710,92 @@ gfc_match_final_decl (void)
   return MATCH_YES;
 }
 
+/* Internal helper to parse attribute argument list.
+   If REQUIRE_STRING is true, then require a string.
+   If ALLOW_MULTIPLE is true, allow more than one arg.
+   If 

Re: [PATCH] Enable shrink wrapping for the RISC-V target.

2022-11-03 Thread Jeff Law



On 11/2/22 18:26, Palmer Dabbelt wrote:



I also tried to remove that restriction but it looks like it can't
work because we can't create
pseudo-registers during shrink wrapping and shrink wrapping can't 
work either.


I believe this means that shrink wrapping cannot interfere with a long
stack frame
so there is nothing to test against in this case?


It'd be marginally better to have such a test case to ensure we don't
shrink wrap it -- that would ensure that someone doesn't accidentally
introduce shrink wrapping with large offsets.   Just a bit of future
proofing.


If there's passing test cases that fail with that check removed then 
it's probably good enough, though I think in this case just having a 
comment there saying why the short-stack check is necessary should be 
fine.


I can live with this.

jeff



Re: [PATCH, v2] Fortran: ordering of hidden procedure arguments [PR107441]

2022-11-03 Thread Harald Anlauf via Gcc-patches

Am 03.11.22 um 11:06 schrieb Mikael Morin:

Le 02/11/2022 à 22:19, Harald Anlauf via Fortran a écrit :

Am 02.11.22 um 18:20 schrieb Mikael Morin:

Unfortunately no, the coarray case works, but the other problem remains.
The type problem is not visible in the definition of S, it is in the
declaration of S's prototype in P.

S is defined as:

void s (character(kind=1)[1:_c] & restrict c, integer(kind=4) o,
logical(kind=1) _o, integer(kind=8) _c)
{
...
}

but P has:

void p ()
{
   static void s (character(kind=1)[1:] & restrict, integer(kind=4),
integer(kind=8), logical(kind=1));
   void (*) (character(kind=1)[1:] & restrict, integer(kind=4),
integer(kind=8), logical(kind=1)) pp;

   pp = s;
...
}


Right, now I see it too.  Simplified case:

program p
   call s ("abcd")
contains
   subroutine s(c, o)
 character(*) :: c
 integer, optional, value :: o
   end subroutine s
end

I do see what needs to be done in gfc_get_function_type, which seems
in fact very simple.  But I get really lost in create_function_arglist
when trying to get the typelist right.

One thing is I really don't understand how the (hidden_)typelist is
managed here.  How does that macro TREE_CHAIN work?  Can we somehow
chain two typelists the same way we chain arguments?


TREE_CHAIN is just a linked list "next" pointer like there is in the
fortran frontend a "next" pointer in gfc_ref or gfc_actual_arglist
structures.
Yes, we can chain typelists; the implementation of chainon in tree.cc is
just TREE_CHAIN appending under the hood.


(Failing that, I tried to split the loop over the dummy arguments in
create_function_arglist into two passes, one for the optional+value
variant, and one for the rest.  It turned out to be a bad idea...)


Not necessarily a bad idea, but one has to be careful to keep linked
lists synchronized with argument walking.

The most simple, I think, is to move the hidden_typelist advancement for
optional, value presence arguments from the main loop to a preliminary
loop.

I hope it helps.



I've spent some time not only staring at create_function_arglist,
but trying several variations handling the declared hidden parms,
and applying the necessary adjustments to gfc_get_function_type.
(Managing linked trees is not the issue, just understanding them.)
I've been unable to get the declarations in sync, and would need
help how to debug the mess I've created.  Dropping my patch for
the time being.




[PATCH] Plug memory leak in attribute target_clones

2022-11-03 Thread Bernhard Reutner-Fischer via Gcc-patches
It looks like there was some memory leak in the handling
of attribute target_clones, introduced in 5928bc2ec06d .

Ok for trunk if testing passes?

gcc/ChangeLog:

* multiple_target.cc (expand_target_clones): Free memory.

Signed-off-by: Bernhard Reutner-Fischer 
---
 gcc/multiple_target.cc | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 67866a7c963..77e0f21dd05 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -390,19 +390,23 @@ expand_target_clones (struct cgraph_node *node, bool 
definition)
   for (i = 0; i < attrnum; i++)
 {
   char *attr = attrs[i];
-  char *suffix = XNEWVEC (char, strlen (attr) + 1);
 
-  create_new_asm_name (attr, suffix);
   /* Create new target clone.  */
   tree attributes = make_attribute ("target", attr,
DECL_ATTRIBUTES (node->decl));
 
+  char *suffix = XNEWVEC (char, strlen (attr) + 1);
+  create_new_asm_name (attr, suffix);
   cgraph_node *new_node = create_target_clone (node, definition, suffix,
   attributes);
+  XDELETEVEC (suffix);
   if (new_node == NULL)
-   return false;
+   {
+ XDELETEVEC (attrs);
+ XDELETEVEC (attr_str);
+ return false;
+   }
   new_node->local = false;
-  XDELETEVEC (suffix);
 
   decl2_v = new_node->function_version ();
   if (decl2_v != NULL)
-- 
2.38.1



[PATCH] cgraph_node: Remove redundant section clearing

2022-11-03 Thread Bernhard Reutner-Fischer via Gcc-patches
Ok for trunk if testing passes?

gcc/ChangeLog:

* cgraph.cc (cgraph_node::make_local): Remove redundant set_section.
* multiple_target.cc (create_dispatcher_calls): Likewise.

Signed-off-by: Bernhard Reutner-Fischer 
---
 gcc/cgraph.cc  | 1 -
 gcc/multiple_target.cc | 1 -
 2 files changed, 2 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 8d6ed38efa2..36afa6f33f6 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2488,15 +2488,14 @@ cgraph_node::make_local (cgraph_node *node, void *)
 {
   node->make_decl_local ();
   node->set_section (NULL);
   node->set_comdat_group (NULL);
   node->externally_visible = false;
   node->forced_by_abi = false;
   node->local = true;
-  node->set_section (NULL);
   node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
   || node->resolution == 
LDPR_PREVAILING_DEF_IRONLY_EXP)
   && !flag_incremental_link);
   node->resolution = LDPR_PREVAILING_DEF_IRONLY;
   gcc_assert (node->get_availability () == AVAIL_LOCAL);
 }
   return false;
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 3e2d26882c8..67866a7c963 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -174,15 +174,14 @@ create_dispatcher_calls (struct cgraph_node *node)
   /* FIXME: copy of cgraph_node::make_local that should be cleaned up
in next stage1.  */
   node->make_decl_local ();
   node->set_section (NULL);
   node->set_comdat_group (NULL);
   node->externally_visible = false;
   node->forced_by_abi = false;
-  node->set_section (NULL);
 
   DECL_ARTIFICIAL (node->decl) = 1;
   node->force_output = true;
 }
 }
 
 /* Create string with attributes separated by comma.
-- 
2.38.1



Re: [PATCH] diagnostics: Allow FEs to keep customizations for middle end [PR101551, PR106274]

2022-11-03 Thread Lewis Hyatt via Gcc-patches
On Fri, Oct 28, 2022 at 10:28:21AM +0200, Richard Biener wrote:
> Yes, the idea was also to free up memory but then that part never
> really materialized - the idea was to always run free-lang-data, not
> just when later outputting LTO bytecode.  The reason is probably
> mainly the diagnostic regressions you observe.
> 
> Maybe a better strathegy than your patch would be to work towards
> that goal but reduce the number of "freeings", instead adjusting the
> LTO streamer to properly ignore frontend specific bits where clearing
> conflicts with the intent to preserve accurate diagnostics throughout
> the compilation.
> 
> If you see bits that when not freed would fix some of the observed
> issues we can see to replicate the freeing in the LTO output machinery.
> 
> Richard.

Thanks again for the suggestions. I took a look and it seems pretty doable to
just stop resetting all the diagnostics hooks in free-lang-data. Once that's
done, the only problematic part that I have been able to identify is here in
ipa-free-lang-data.c around line 674:


  /* We need to keep field decls associated with their trees. Otherwise tree
 merging may merge some fields and keep others disjoint which in turn will
 not do well with TREE_CHAIN pointers linking them.

 Also do not drop containing types for virtual methods and tables because
 these are needed by devirtualization.
 C++ destructors are special because C++ frontends sometimes produces
 virtual destructor as an alias of non-virtual destructor.  In
 devirutalization code we always walk through aliases and we need
 context to be preserved too.  See PR89335  */
  if (TREE_CODE (decl) != FIELD_DECL
  && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
  || (!DECL_VIRTUAL_P (decl)
  && (TREE_CODE (decl) != FUNCTION_DECL
  || !DECL_CXX_DESTRUCTOR_P (decl)
DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl));


The C++ implementations of the decl_printable_name langhook and the diagnostic
starter callback do not work as-is when the DECL_CONTEXT for class member
functions disappears.  So I did have a patch that changes the C++
implementations to work in this case, but attached here is a new one along the
lines of what you suggested, rather changing the above part of free-lang-data
so it doesn't activate as often. The patch is pretty complete (other than
missing a commit message) and bootstrap + regtest all languages looks good
with no regressions. I tried the same with BUILD_CONFIG=bootstrap-lto as well,
and that also looked good when it eventually finished. I added testcases for
several frontends to verify that the diagnostics still work with -flto. I am
not sure what are the implications for LTO itself, of changing this part of
the pass, so I would have to ask you to weigh in on that aspect please. Thanks!

-Lewis
[PATCH] middle-end: Preserve frontend diagnostics in free-lang-data [PR101551, 
PR106274]

gcc/ChangeLog:

PR lto/106274
PR middle-end/101551
* ipa-free-lang-data.cc (free_lang_data_in_decl): Preserve
DECL_CONTEXT for class member functions.
(free_lang_data): Do not reset frontend diagnostics customizations.

gcc/testsuite/ChangeLog:

PR lto/106274
PR middle-end/101551
* c-c++-common/diag-after-fld-1.c: New test.
* g++.dg/diag-after-fld-1.C: New test.
* g++.dg/diag-after-fld-2.C: New test.
* gfortran.dg/allocatable_uninitialized_2.f90: New test.
* objc.dg/diag-after-fld-1.m: New test.

diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc
index ccdbf849c25..391b7689639 100644
--- a/gcc/ipa-free-lang-data.cc
+++ b/gcc/ipa-free-lang-data.cc
@@ -682,10 +682,8 @@ free_lang_data_in_decl (tree decl, class free_lang_data_d 
*fld)
  devirutalization code we always walk through aliases and we need
  context to be preserved too.  See PR89335  */
   if (TREE_CODE (decl) != FIELD_DECL
-  && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
-  || (!DECL_VIRTUAL_P (decl)
- && (TREE_CODE (decl) != FUNCTION_DECL
- || !DECL_CXX_DESTRUCTOR_P (decl)
+  && TREE_CODE (decl) != VAR_DECL
+  && TREE_CODE (decl) != FUNCTION_DECL)
 DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl));
 }
 
@@ -1115,7 +1113,6 @@ free_lang_data (void)
   /* Reset some langhooks.  Do not reset types_compatible_p, it may
  still be used indirectly via the get_alias_set langhook.  */
   lang_hooks.dwarf_name = lhd_dwarf_name;
-  lang_hooks.decl_printable_name = gimple_decl_printable_name;
   lang_hooks.gimplify_expr = lhd_gimplify_expr;
   lang_hooks.overwrite_decl_assembler_name = lhd_overwrite_decl_assembler_name;
   lang_hooks.print_xnode = lhd_print_tree_nothing;
@@ -1141,9 +1138,6 @@ free_lang_data (void)
  make sure we never call decl_assembler_name on local symbols and
  devise a 

[PATCH RFA] input: add get_source_text_between

2022-11-03 Thread Jason Merrill via Gcc-patches
Tested x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

The c++-contracts branch uses this to retrieve the source form of the
contract predicate, to be returned by contract_violation::comment().

gcc/ChangeLog:

* input.cc (get_source_text_between): New fn.
* input.h (get_source_text_between): Declare.
---
 gcc/input.h  |  1 +
 gcc/input.cc | 76 
 2 files changed, 77 insertions(+)

diff --git a/gcc/input.h b/gcc/input.h
index 11c571d076f..f18769950b5 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -111,6 +111,7 @@ class char_span
 };
 
 extern char_span location_get_source_line (const char *file_path, int line);
+extern char *get_source_text_between (location_t, location_t);
 
 extern bool location_missing_trailing_newline (const char *file_path);
 
diff --git a/gcc/input.cc b/gcc/input.cc
index a28abfac5ac..9b36356338a 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -949,6 +949,82 @@ location_get_source_line (const char *file_path, int line)
   return char_span (buffer, len);
 }
 
+/* Return a copy of the source text between two locations.  The caller is
+   responsible for freeing the return value.  */
+
+char *
+get_source_text_between (location_t start, location_t end)
+{
+  expanded_location expstart =
+expand_location_to_spelling_point (start, LOCATION_ASPECT_START);
+  expanded_location expend =
+expand_location_to_spelling_point (end, LOCATION_ASPECT_FINISH);
+
+  /* If the locations are in different files or the end comes before the
+ start, abort and return nothing.  */
+  if (!expstart.file || !expend.file)
+return NULL;
+  if (strcmp (expstart.file, expend.file) != 0)
+return NULL;
+  if (expstart.line > expend.line)
+return NULL;
+  if (expstart.line == expend.line
+  && expstart.column > expend.column)
+return NULL;
+
+  /* For a single line we need to trim both edges.  */
+  if (expstart.line == expend.line)
+{
+  char_span line = location_get_source_line (expstart.file, expstart.line);
+  if (line.length () < 1)
+   return NULL;
+  int s = expstart.column - 1;
+  int l = expend.column - s;
+  if (line.length () < (size_t)expend.column)
+   return NULL;
+  return line.subspan (s, l).xstrdup ();
+}
+
+  struct obstack buf_obstack;
+  obstack_init (_obstack);
+
+  /* Loop through all lines in the range and append each to buf; may trim
+ parts of the start and end lines off depending on column values.  */
+  for (int l = expstart.line; l <= expend.line; ++l)
+{
+  char_span line = location_get_source_line (expstart.file, l);
+  if (line.length () < 1 && (l != expstart.line && l != expend.line))
+   continue;
+
+  /* For the first line in the range, only start at expstart.column */
+  if (l == expstart.line)
+   {
+ if (expstart.column == 0)
+   return NULL;
+ if (line.length () < (size_t)expstart.column - 1)
+   return NULL;
+ line = line.subspan (expstart.column - 1,
+  line.length() - expstart.column + 1);
+   }
+  /* For the last line, don't go past expend.column */
+  else if (l == expend.line)
+   {
+ if (line.length () < (size_t)expend.column)
+   return NULL;
+ line = line.subspan (0, expend.column);
+   }
+
+  obstack_grow (_obstack, line.get_buffer (), line.length ());
+}
+
+  /* NUL-terminate and finish the buf obstack.  */
+  obstack_1grow (_obstack, 0);
+  const char *buf = (const char *) obstack_finish (_obstack);
+
+  /* TODO should we collapse/trim newlines and runs of spaces?  */
+  return xstrdup (buf);
+}
+
 /* Determine if FILE_PATH missing a trailing newline on its final line.
Only valid to call once all of the file has been loaded, by
requesting a line number beyond the end of the file.  */

base-commit: a4cd2389276a30c39034a83d640ce68fa407bac1
prerequisite-patch-id: 329bc16a88dc9a3b13cd3fcecb3678826cc592dc
prerequisite-patch-id: 49e922c10f6da687d9da3f6a0fd20f324bd352d6
-- 
2.31.1



[PATCH RFA] libstdc++: add experimental Contracts support

2022-11-03 Thread Jason Merrill via Gcc-patches
Tested x86_64-pc-linux-gnu.  OK for trunk?

-- >8 --

This patch adds the library support for the experimental C++ Contracts
implementation.  This now consists only of a default definition of the
violation handler, which users can override through defining their own
version.  To avoid ABI stability problems with libstdc++.so this is added to
a separate -lstdc++exp static library, which the driver knows to add when it
sees -fcontracts.

libstdc++-v3/ChangeLog:

* acinclude.m4 (glibcxx_SUBDIRS): Add src/experimental.
* include/Makefile.am (experimental_headers): Add contract.
* include/Makefile.in: Regenerate.
* src/Makefile.am (SUBDIRS): Add experimental.
* src/Makefile.in: Regenerate.
* configure: Regenerate.
* src/experimental/contract.cc: New file.
* src/experimental/Makefile.am: New file.
* src/experimental/Makefile.in: New file.
* include/experimental/contract: New file.
---
 libstdc++-v3/src/experimental/contract.cc  |  41 ++
 libstdc++-v3/acinclude.m4  |   2 +-
 libstdc++-v3/include/Makefile.am   |   1 +
 libstdc++-v3/include/Makefile.in   |   1 +
 libstdc++-v3/src/Makefile.am   |   3 +-
 libstdc++-v3/src/Makefile.in   |   6 +-
 libstdc++-v3/src/experimental/Makefile.am  |  96 +++
 libstdc++-v3/src/experimental/Makefile.in  | 796 +
 libstdc++-v3/include/experimental/contract |  84 +++
 9 files changed, 1026 insertions(+), 4 deletions(-)
 create mode 100644 libstdc++-v3/src/experimental/contract.cc
 create mode 100644 libstdc++-v3/src/experimental/Makefile.am
 create mode 100644 libstdc++-v3/src/experimental/Makefile.in
 create mode 100644 libstdc++-v3/include/experimental/contract

diff --git a/libstdc++-v3/src/experimental/contract.cc 
b/libstdc++-v3/src/experimental/contract.cc
new file mode 100644
index 000..b9b72cd7df0
--- /dev/null
+++ b/libstdc++-v3/src/experimental/contract.cc
@@ -0,0 +1,41 @@
+// -*- C++ -*- std::experimental::contract_violation and friends
+// Copyright (C) 1994-2022 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// GCC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// .
+
+#include 
+#include 
+
+__attribute__ ((weak)) void
+handle_contract_violation (const std::experimental::contract_violation 
)
+{
+  std::cerr << "default std::handle_contract_violation called: " << std::endl
+<< " " << violation.file_name()
+<< " " << violation.line_number()
+<< " " << violation.function_name()
+<< " " << violation.comment()
+<< " " << violation.assertion_level()
+<< " " << violation.assertion_role()
+<< " " << (int)violation.continuation_mode()
+<< std::endl;
+}
+
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 6f672924a73..baf01913a90 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -49,7 +49,7 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [
   # Keep these sync'd with the list in Makefile.am.  The first provides an
   # expandable list at autoconf time; the second provides an expandable list
   # (i.e., shell variable) at configure time.
-  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 
src/c++17 src/c++20 src/filesystem src/libbacktrace doc po testsuite python])
+  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 
src/c++17 src/c++20 src/filesystem src/libbacktrace src/experimental doc po 
testsuite python])
   SUBDIRS='glibcxx_SUBDIRS'
 
   # These need to be absolute paths, yet at the same time need to
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 96137a6621a..a6f9912cb9b 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -769,6 +769,7 @@ experimental_headers = \
${experimental_srcdir}/array \
${experimental_srcdir}/buffer \
${experimental_srcdir}/chrono \
+   ${experimental_srcdir}/contract \
${experimental_srcdir}/deque \
${experimental_srcdir}/executor \
${experimental_srcdir}/forward_list \
diff 

[COMMITTED] Add testcases resolved with ranger as VRP1.

2022-11-03 Thread Andrew MacLeod via Gcc-patches

Turning ranger on by default for the VRP1 pass fixed 3 outstanding PRs:

93917, 66, and 102650.   Adding testcases for those PRs.

Andrew
From 863f50c84be7302ba14ce650838e3fd475b0cd56 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Thu, 3 Nov 2022 13:07:33 -0400
Subject: [PATCH] Add testcases resolved with ranger as VRP1.

	gcc/testsuite/
	* g++.dg/pr99966.C: New.
	* gcc.dg/pr93917.c: New.
	* gcc.dg/pr102650.c: New.
---
 gcc/testsuite/g++.dg/pr99966.C  | 23 +++
 gcc/testsuite/gcc.dg/pr102650.c | 20 
 gcc/testsuite/gcc.dg/pr93917.c  | 20 
 3 files changed, 63 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/pr99966.C
 create mode 100644 gcc/testsuite/gcc.dg/pr102650.c
 create mode 100644 gcc/testsuite/gcc.dg/pr93917.c

diff --git a/gcc/testsuite/g++.dg/pr99966.C b/gcc/testsuite/g++.dg/pr99966.C
new file mode 100644
index 000..4d689822b87
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr99966.C
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-options "-O2 -fdump-tree-vrp1" }
+
+// Test we can remove a range bound after the assert.
+
+#include 
+#include 
+#include 
+#include 
+
+uint64_t f(std::vector& data, size_t start, size_t end){
+assert(start < end && start < data.size() && end <= data.size());
+
+
+uint64_t total = 0;
+for (size_t i = start; i < end; i++) {
+total += data.at(i);
+}
+return total;
+}
+
+/* { dg-final { scan-tree-dump-not "throw" "vrp1"} } */
diff --git a/gcc/testsuite/gcc.dg/pr102650.c b/gcc/testsuite/gcc.dg/pr102650.c
new file mode 100644
index 000..16ae840260f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr102650.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-vrp1" } */
+
+static int a = 2, b, c, d;
+void foo(void);
+int main() {
+short e;
+int f = -1;
+if (b)
+c = 0;
+c || (f = 2);
+for (; d < 1; d++)
+e = f + a;
+if (!e)
+foo();
+return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "vrp1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/pr93917.c b/gcc/testsuite/gcc.dg/pr93917.c
new file mode 100644
index 000..41d27fb9a8f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93917.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+void f3(int n);
+
+void f1(int n)
+{
+  if(n<0)
+__builtin_unreachable();
+  f3(n);
+}
+
+void f2(int*n)
+{
+  if(*n<0)
+__builtin_unreachable();
+  f3 (*n);
+}
+
+/* { dg-final { scan-tree-dump-times "Global Exported" 2 "vrp1" } } */
-- 
2.37.3



[pushed] c++: change -fconcepts to mean C++20 concepts

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

-- >8 --

It was always weird that -fconcepts in C++17 mode meant the same thing as
-fconcepts-ts in C++20 mode; this patch harmonizes the flags so that for TS
concepts you always need to write -fconcepts-ts.

In the unlikely event anyone is still using -fconcepts in C++17 mode, they
can either fix their code to work with C++20 concepts or adjust the compiler
flag.

gcc/c-family/ChangeLog:

* c-opts.cc (c_common_post_options): -fconcepts no longer implies
-fconcepts-ts before C++20.

gcc/ChangeLog:

* doc/invoke.texi: -fconcepts no longer implies
-fconcepts-ts before C++20.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_template_declaration_after_parameters): Fix
concept parsing below C++20.

gcc/testsuite/ChangeLog:

* g++.dg/concepts/auto1.C:
* g++.dg/concepts/auto3.C:
* g++.dg/concepts/auto4.C:
* g++.dg/concepts/class-deduction1.C:
* g++.dg/concepts/class5.C:
* g++.dg/concepts/class6.C:
* g++.dg/concepts/debug1.C:
* g++.dg/concepts/decl-diagnose.C:
* g++.dg/concepts/deduction-constraint1.C:
* g++.dg/concepts/diagnostic1.C:
* g++.dg/concepts/dr1430.C:
* g++.dg/concepts/equiv.C:
* g++.dg/concepts/equiv2.C:
* g++.dg/concepts/expression.C:
* g++.dg/concepts/expression2.C:
* g++.dg/concepts/expression3.C:
* g++.dg/concepts/fn-concept1.C:
* g++.dg/concepts/fn-concept2.C:
* g++.dg/concepts/fn-concept3.C:
* g++.dg/concepts/fn1.C:
* g++.dg/concepts/fn10.C:
* g++.dg/concepts/fn2.C:
* g++.dg/concepts/fn3.C:
* g++.dg/concepts/fn4.C:
* g++.dg/concepts/fn5.C:
* g++.dg/concepts/fn6.C:
* g++.dg/concepts/fn8.C:
* g++.dg/concepts/fn9.C:
* g++.dg/concepts/generic-fn-err.C:
* g++.dg/concepts/generic-fn.C:
* g++.dg/concepts/inherit-ctor1.C:
* g++.dg/concepts/inherit-ctor3.C:
* g++.dg/concepts/intro1.C:
* g++.dg/concepts/intro2.C:
* g++.dg/concepts/intro3.C:
* g++.dg/concepts/intro4.C:
* g++.dg/concepts/intro5.C:
* g++.dg/concepts/intro6.C:
* g++.dg/concepts/intro7.C:
* g++.dg/concepts/locations1.C:
* g++.dg/concepts/partial-concept-id1.C:
* g++.dg/concepts/partial-concept-id2.C:
* g++.dg/concepts/partial-spec5.C:
* g++.dg/concepts/placeholder2.C:
* g++.dg/concepts/placeholder3.C:
* g++.dg/concepts/placeholder4.C:
* g++.dg/concepts/placeholder5.C:
* g++.dg/concepts/placeholder6.C:
* g++.dg/concepts/pr65634.C:
* g++.dg/concepts/pr65636.C:
* g++.dg/concepts/pr65681.C:
* g++.dg/concepts/pr65848.C:
* g++.dg/concepts/pr67249.C:
* g++.dg/concepts/pr67595.C:
* g++.dg/concepts/pr68434.C:
* g++.dg/concepts/pr71127.C:
* g++.dg/concepts/pr71128.C:
* g++.dg/concepts/pr71131.C:
* g++.dg/concepts/pr71385.C:
* g++.dg/concepts/pr85065.C:
* g++.dg/concepts/template-parm11.C:
* g++.dg/concepts/template-parm12.C:
* g++.dg/concepts/template-parm2.C:
* g++.dg/concepts/template-parm3.C:
* g++.dg/concepts/template-parm4.C:
* g++.dg/concepts/template-template-parm1.C:
* g++.dg/concepts/var-concept1.C:
* g++.dg/concepts/var-concept2.C:
* g++.dg/concepts/var-concept3.C:
* g++.dg/concepts/var-concept4.C:
* g++.dg/concepts/var-concept5.C:
* g++.dg/concepts/var-concept6.C:
* g++.dg/concepts/var-concept7.C:
* g++.dg/concepts/var-templ2.C:
* g++.dg/concepts/var-templ3.C:
* g++.dg/concepts/variadic1.C:
* g++.dg/concepts/variadic2.C:
* g++.dg/concepts/variadic3.C:
* g++.dg/concepts/variadic4.C:
* g++.dg/cpp2a/concepts-pr65575.C:
* g++.dg/cpp2a/concepts-pr66091.C:
* g++.dg/cpp2a/concepts-pr84980.C:
* g++.dg/cpp2a/concepts-pr85265.C: Pass -fconcepts-ts.
* g++.dg/cpp2a/concepts-pr84979-2.C:
* g++.dg/cpp2a/concepts-pr84979-3.C: Same diagnostics
in C++20 and below.
---
 gcc/doc/invoke.texi| 14 +++---
 gcc/c-family/c-opts.cc |  3 ---
 gcc/cp/parser.cc   |  7 ---
 gcc/testsuite/g++.dg/concepts/auto1.C  |  2 +-
 gcc/testsuite/g++.dg/concepts/auto3.C  |  2 +-
 gcc/testsuite/g++.dg/concepts/auto4.C  |  2 +-
 gcc/testsuite/g++.dg/concepts/class-deduction1.C   |  2 +-
 gcc/testsuite/g++.dg/concepts/class5.C |  2 +-
 gcc/testsuite/g++.dg/concepts/class6.C |  2 +-
 gcc/testsuite/g++.dg/concepts/debug1.C |  2 +-
 gcc/testsuite/g++.dg/concepts/decl-diagnose.C  |  2 +-
 .../g++.dg/concepts/deduction-constraint1.C|  2 +-
 

Re: [PATCH] c++: Disable -Wignored-qualifiers for template args [PR107492]

2022-11-03 Thread Jason Merrill via Gcc-patches

On 11/1/22 13:01, Marek Polacek wrote:

It seems wrong to issue a -Wignored-qualifiers warning for code like:

   static_assert(!is_same_v);

because there the qualifier matters.  Likewise in template
specialization:

   template struct S { };
   template<> struct S { };
   template<> struct S { }; // OK, not a redefinition

I'm of the mind that we should disable the warning for template
arguments, as in the patch below.


Hmm, I'm not sure why we would want to treat template arguments 
differently from other type-ids.  Maybe only warn if funcdecl_p?



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

PR c++/107492

gcc/cp/ChangeLog:

* parser.cc (cp_parser_template_type_arg): Suppress -Wignored-qualifiers
warning.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wignored-qualifiers3.C: New test.
---
  gcc/cp/parser.cc |  4 
  gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C | 12 
  2 files changed, 16 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e0e3cf3eaf6..54ad4b98ed3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -24334,6 +24334,10 @@ cp_parser_template_type_arg (cp_parser *parser)
const char *saved_message = parser->type_definition_forbidden_message;
parser->type_definition_forbidden_message
  = G_("types may not be defined in template arguments");
+  /* It's wrong to issue a -Wignored-qualifiers warning for
+  static_assert(!is_same_v);
+ because there the qualifier matters.  */
+  warning_sentinel w (warn_ignored_qualifiers);
r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL);
parser->type_definition_forbidden_message = saved_message;
if (cxx_dialect >= cxx14 && !flag_concepts && type_uses_auto (r))
diff --git a/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C 
b/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C
new file mode 100644
index 000..5696feaaefe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C
@@ -0,0 +1,12 @@
+// PR c++/107492
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-Wignored-qualifiers" }
+
+template struct S { };
+template<> struct S { };
+template<> struct S { }; // { dg-bogus "ignored" }
+
+template constexpr bool is_same_v = false;
+template constexpr bool is_same_v = true;
+
+static_assert( ! is_same_v< void(*)(), const void(*)() >, ""); // { dg-bogus 
"ignored" }

base-commit: e7310e24b1c0ca67b1bb507c1330b2bf39e59e32




Re: [RFC] RISC-V: Add profile supports.

2022-11-03 Thread Christoph Müllner
On Wed, Nov 2, 2022 at 7:12 PM Palmer Dabbelt  wrote:
>
> On Wed, 02 Nov 2022 10:19:15 PDT (-0700), gcc-patches@gcc.gnu.org wrote:
> > Could you add some test cases?
>
> Also documentation, and ideally some sort of spec for what this should
> do so we can maintain compatibility with LLVM as well as we can.
>
> IIUC this also allows for profiles in the arch function attributes,
> which would end up plumbing through to the assembler so we'd need
> support there?  Probably best to just expand these out for the rest of
> the tools so we don't need the profile->extension mappings everywhere,
> IMO it's the same as the -mcpu discussion.
>
> >
> > ---
> >
> > Parsing logic is kind of too adhoc, I would prefer using something
> > like the following code to prevent magic pointer arithmetic like p+6:
> >
> > something like this:
> >
> > Table of all profile names = {"RVA20U64", riscv_profile::RVA20U64, ...}
> >
> > const char *rva20u64[] = {"m", "a", "f", "d",... NULL};
> >
> > table of profile content =
> > {
> >   {riscv_profile::RVA20U64, rva20u64},
> >..
> > }
> >
> > parse march ()
> > {
> >   if march is startswith
> >   else if ((profile = parse_proile(march)) != risv_profile::NOT_PROFILE)
> >  handle_profile (profile)
> >   else
> >  error
> > }
> >
> > handle_profile (profile)
> > {
> >   use table of profile content to update ext.
> > }
> >
> >
> > On Wed, Nov 2, 2022 at 5:54 AM jiawei  wrote:
> >>handle_profile
> >> Add two new function to handle profile input,
> >> "parse_profile" will check if a input into -march is
> >> legal, if it is then "handle_profile" will check the
> >> profile's type[I/M/A], year[20/22] and mode[U/S/M],
> >> set different extensions combine, just deal mandatory
> >> part currently.
> >>
> >> gcc/ChangeLog:
> >>
> >> * common/config/riscv/riscv-common.cc
> >> (riscv_subset_list::parse_profile): Check if profile name is valid 
> >> or not.
> >> (riscv_subset_list::parse_std_ext): If input of -march option is
> >> a profile,skip first ISA check.
> >> (riscv_subset_list::parse): Handle rofile input in -march.
> >> (riscv_subset_list::handle_profile): Handle differen profiles
> >>  expand to extensions.
> >> * config/riscv/riscv-subset.h: New function prototypes.
> >>
> >>
> >> ---
> >>  gcc/common/config/riscv/riscv-common.cc | 95 +++--
> >>  gcc/config/riscv/riscv-subset.h |  5 +-
> >>  2 files changed, 94 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/gcc/common/config/riscv/riscv-common.cc 
> >> b/gcc/common/config/riscv/riscv-common.cc
> >> index 602491c638d..da06bd89144 100644
> >> --- a/gcc/common/config/riscv/riscv-common.cc
> >> +++ b/gcc/common/config/riscv/riscv-common.cc
> >> @@ -777,6 +777,35 @@ riscv_subset_list::parsing_subset_version (const char 
> >> *ext,
> >>return p;
> >>  }
> >>
> >> +/* Parsing function for profile.
> >> +
> >> +   Return Value:
> >> + Points to the end of profile.
> >> +
> >> +   Arguments:
> >> + `p`: Current parsing position.  */
> >> +
> >> +const char *
> >> +riscv_subset_list::parse_profile (const char *p)
> >> +{
> >> +  if(*p == 'I' || *p == 'M' || *p == 'A'){
> >> +p++;
> >> +if(startswith (p, "20") || startswith (p, "22"))
> >> +  p += 2;
> >> +if (*p == 'U' || *p == 'S' || *p == 'M')
> >> +  p++;
> >> +if(startswith (p, "64") || startswith (p, "32")){
> >> +   p += 2;
> >> +   riscv_subset_list::handle_profile(p-6, p-4, p-3);
> >> +   return p;
> >> +}
> >> +  }
> >> +  else
> >> +error_at (m_loc, "%<-march=%s%>: Invalid profile.", m_arch);
> >> +  return NULL;
> >> +}
> >> +
> >> +
> >>  /* Parsing function for standard extensions.parse_std_ext
> >>
> >
> > It's sort of too adhoc parsing the profile name, I would prefer using
> > something like the following code to prevent magic pointer arithmetic
> > like p+6.
> > something
> > Table of all profile names = {"RVA20U64", riscv_profile::RVA20U64, ...}
> >
> > const char *rva20u64[] = {"m", "a", "f", "d",... NULL};
> >
> > table of profile content =
> > {
> >   {riscv_profile::RVA20U64, rva20u64},
> >..
> > }
> >
> > parse march ()
> > {
> >   if march is startswith
> >   else if ((profile = parse_proile(march)) != risv_profile::NOT_PROFILE)
> >  handle_profile (profile)
> >   else
> >  error
> > }
> >
> > handle_profile (profile)
> > {
> >   ad
> > }
> >
> >> Return Value:
> >> @@ -786,7 +815,7 @@ riscv_subset_list::parsing_subset_version (const char 
> >> *ext,
> >>   `p`: Current parsing position.  */
> >>
> >>  const char *
> >> -riscv_subset_list::parse_std_ext (const char *p)
> >> +riscv_subset_list::parse_std_ext (const char *p, bool isprofile)
> >>  {
> >>const char *all_std_exts = riscv_supported_std_ext ();
> >>const char *std_exts = all_std_exts;
> >> @@ -795,8 +824,8 @@ riscv_subset_list::parse_std_ext (const 

Re: [PATCH] c++: Quash -Wdangling-reference for member operator* [PR107488]

2022-11-03 Thread Marek Polacek via Gcc-patches
On Thu, Nov 03, 2022 at 02:54:12PM -0400, Jason Merrill wrote:
> On 11/1/22 18:06, Marek Polacek wrote:
> > -Wdangling-reference complains here:
> > 
> >std::vector v = ...;
> >std::vector::const_iterator it = v.begin();
> >while (it != v.end()) {
> >  const int  = *it++; // warning
> >}
> > 
> > because it sees a call to
> > __gnu_cxx::__normal_iterator >::operator*
> > which returns a reference and its argument is a TARGET_EXPR representing
> > the result of
> > __gnu_cxx::__normal_iterator >::operator++
> > But 'r' above refers to one of the int elements of the vector 'v', not
> > to a temporary object.  Therefore the warning is a false positive.
> > 
> > I suppose code like the above is relatively common (the warning broke
> > cppunit-1.15.1 and a few other projects), so presumably it makes sense
> > to suppress the warning when it comes to member operator*.  In this case
> > it's defined as
> > 
> >reference
> >operator*() const _GLIBCXX_NOEXCEPT
> >{ return *_M_current; }
> > 
> > and I'm guessing a lot of member operator* are like that, at least when
> > it comes to iterators.  I've looked at _Fwd_list_iterator,
> > _Fwd_list_const_iterator, __shared_ptr_access, _Deque_iterator,
> > istream_iterator, etc, and they're all like that, so adding #pragmas
> > would be quite tedious.  :/
> 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> OK.

Thanks.
 
> It also occurred to me that we should avoid warning if the reference we're
> initializing is a non-const lvalue reference, which can't bind to a
> temporary.

Yup; amusingly I noticed that too while working with the reduced version
of the testcase, which I deliberately didn't end up using, and which
reduced to 'int&' rather than 'const int&'.

> Maybe also if the function returns a non-const lvalue reference.

Ok.  Expect a patch soon.

Marek



Re: [PATCH] c++: requires-expr substitution and access checking [PR107179]

2022-11-03 Thread Jason Merrill via Gcc-patches

On 11/3/22 11:45, Patrick Palka wrote:

Like during satisfaction, we need to check access immediately during
substitution of a requires-expr since the outcome of an access check can
determine the value of the requires-expr.  And otherwise, in contexts
where access checking is deferred (such as during substitution into a
base-clause), a failed access check may leak out from the requires-expr
into a non-SFINAE context and cause a hard error (as in the testcase
below).

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


OK.


PR c++/107179

gcc/cp/ChangeLog:

* constraint.cc (tsubst_requires_expr): Make sure we're not
deferring access checks.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-requires31.C: New test.
---
  gcc/cp/constraint.cc |  3 +++
  gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C | 13 +
  2 files changed, 16 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e6a3bcf059..f6ef078171a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2252,6 +2252,9 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
  {
local_specialization_stack stack (lss_copy);
  
+  /* We need to check access during the substitution.  */

+  deferring_access_check_sentinel acs (dk_no_deferred);
+
/* A requires-expression is an unevaluated context.  */
cp_unevaluated u;
  
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C

new file mode 100644
index 000..9b7e2a34889
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C
@@ -0,0 +1,13 @@
+// PR c++/107179
+// { dg-do compile { target c++20 } }
+
+template struct bool_constant { static constexpr bool value = B; };
+
+template
+  struct is_implicitly_default_constructible
+  : bool_constant
+  { };
+
+struct X { private: X(); };
+
+static_assert( !is_implicitly_default_constructible::value );




Re: [PATCH] c++: Quash -Wdangling-reference for member operator* [PR107488]

2022-11-03 Thread Jason Merrill via Gcc-patches

On 11/1/22 18:06, Marek Polacek wrote:

-Wdangling-reference complains here:

   std::vector v = ...;
   std::vector::const_iterator it = v.begin();
   while (it != v.end()) {
 const int  = *it++; // warning
   }

because it sees a call to
__gnu_cxx::__normal_iterator >::operator*
which returns a reference and its argument is a TARGET_EXPR representing
the result of
__gnu_cxx::__normal_iterator >::operator++
But 'r' above refers to one of the int elements of the vector 'v', not
to a temporary object.  Therefore the warning is a false positive.

I suppose code like the above is relatively common (the warning broke
cppunit-1.15.1 and a few other projects), so presumably it makes sense
to suppress the warning when it comes to member operator*.  In this case
it's defined as

   reference
   operator*() const _GLIBCXX_NOEXCEPT
   { return *_M_current; }

and I'm guessing a lot of member operator* are like that, at least when
it comes to iterators.  I've looked at _Fwd_list_iterator,
_Fwd_list_const_iterator, __shared_ptr_access, _Deque_iterator,
istream_iterator, etc, and they're all like that, so adding #pragmas
would be quite tedious.  :/



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


OK.

It also occurred to me that we should avoid warning if the reference 
we're initializing is a non-const lvalue reference, which can't bind to 
a temporary.


Maybe also if the function returns a non-const lvalue reference.


PR c++/107488

gcc/cp/ChangeLog:

* call.cc (do_warn_dangling_reference): Quash -Wdangling-reference
for member operator*.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wdangling-reference5.C: New test.
---
  gcc/cp/call.cc| 12 +-
  .../g++.dg/warn/Wdangling-reference5.C| 22 +++
  2 files changed, 33 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference5.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index c7c7a122045..2c0fa37f53a 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13467,7 +13467,17 @@ do_warn_dangling_reference (tree expr)
   can be e.g.
 const int& z = std::min({1, 2, 3, 4, 5, 6, 7});
   which doesn't dangle: std::min here returns an int.  */
-   || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl
+   || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl)))
+   /* Don't emit a false positive for:
+   std::vector v = ...;
+   std::vector::const_iterator it = v.begin();
+   const int  = *it++;
+  because R refers to one of the int elements of V, not to
+  a temporary object.  Member operator* may return a reference
+  but probably not to one of its arguments.  */
+   || (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+   && DECL_OVERLOADED_OPERATOR_P (fndecl)
+   && DECL_OVERLOADED_OPERATOR_IS (fndecl, INDIRECT_REF)))
  return NULL_TREE;
  
  	/* Here we're looking to see if any of the arguments is a temporary

diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference5.C 
b/gcc/testsuite/g++.dg/warn/Wdangling-reference5.C
new file mode 100644
index 000..59b5538aee5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference5.C
@@ -0,0 +1,22 @@
+// PR c++/107488
+// { dg-do compile }
+// { dg-options "-Wdangling-reference" }
+
+#include 
+
+int
+do_sum (std::vector& v)
+{
+  int sum = 0;
+
+  std::vector::const_iterator it = v.begin();
+  while (it != v.end())
+{
+  // R refers to one of the int elements of V, not to a temporary
+  // object, so no dangling reference here.
+  const int  = *it++; // { dg-bogus "dangling reference" }
+  sum += r;
+}
+
+  return sum;
+}

base-commit: 2b0e81d5cc2f7e1d773f6c502bd65b097f392675




[pushed] c++: change -fconcepts to mean C++20 concepts

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

-- >8 --

It was always weird that -fconcepts in C++17 mode meant the same thing as
-fconcepts-ts in C++20 mode; this patch harmonizes the flags so that for TS
concepts you always need to write -fconcepts-ts.

In the unlikely event anyone is still using -fconcepts in C++17 mode, they
can either fix their code to work with C++20 concepts or adjust the compiler
flag.

gcc/c-family/ChangeLog:

* c-opts.cc (c_common_post_options): -fconcepts no longer implies
-fconcepts-ts before C++20.

gcc/ChangeLog:

* doc/invoke.texi: -fconcepts no longer implies
-fconcepts-ts before C++20.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_template_declaration_after_parameters): Fix
concept parsing below C++20.

gcc/testsuite/ChangeLog:

* g++.dg/concepts/auto1.C:
* g++.dg/concepts/auto3.C:
* g++.dg/concepts/auto4.C:
* g++.dg/concepts/class-deduction1.C:
* g++.dg/concepts/class5.C:
* g++.dg/concepts/class6.C:
* g++.dg/concepts/debug1.C:
* g++.dg/concepts/decl-diagnose.C:
* g++.dg/concepts/deduction-constraint1.C:
* g++.dg/concepts/diagnostic1.C:
* g++.dg/concepts/dr1430.C:
* g++.dg/concepts/equiv.C:
* g++.dg/concepts/equiv2.C:
* g++.dg/concepts/expression.C:
* g++.dg/concepts/expression2.C:
* g++.dg/concepts/expression3.C:
* g++.dg/concepts/fn-concept1.C:
* g++.dg/concepts/fn-concept2.C:
* g++.dg/concepts/fn-concept3.C:
* g++.dg/concepts/fn1.C:
* g++.dg/concepts/fn10.C:
* g++.dg/concepts/fn2.C:
* g++.dg/concepts/fn3.C:
* g++.dg/concepts/fn4.C:
* g++.dg/concepts/fn5.C:
* g++.dg/concepts/fn6.C:
* g++.dg/concepts/fn8.C:
* g++.dg/concepts/fn9.C:
* g++.dg/concepts/generic-fn-err.C:
* g++.dg/concepts/generic-fn.C:
* g++.dg/concepts/inherit-ctor1.C:
* g++.dg/concepts/inherit-ctor3.C:
* g++.dg/concepts/intro1.C:
* g++.dg/concepts/intro2.C:
* g++.dg/concepts/intro3.C:
* g++.dg/concepts/intro4.C:
* g++.dg/concepts/intro5.C:
* g++.dg/concepts/intro6.C:
* g++.dg/concepts/intro7.C:
* g++.dg/concepts/locations1.C:
* g++.dg/concepts/partial-concept-id1.C:
* g++.dg/concepts/partial-concept-id2.C:
* g++.dg/concepts/partial-spec5.C:
* g++.dg/concepts/placeholder2.C:
* g++.dg/concepts/placeholder3.C:
* g++.dg/concepts/placeholder4.C:
* g++.dg/concepts/placeholder5.C:
* g++.dg/concepts/placeholder6.C:
* g++.dg/concepts/pr65634.C:
* g++.dg/concepts/pr65636.C:
* g++.dg/concepts/pr65681.C:
* g++.dg/concepts/pr65848.C:
* g++.dg/concepts/pr67249.C:
* g++.dg/concepts/pr67595.C:
* g++.dg/concepts/pr68434.C:
* g++.dg/concepts/pr71127.C:
* g++.dg/concepts/pr71128.C:
* g++.dg/concepts/pr71131.C:
* g++.dg/concepts/pr71385.C:
* g++.dg/concepts/pr85065.C:
* g++.dg/concepts/template-parm11.C:
* g++.dg/concepts/template-parm12.C:
* g++.dg/concepts/template-parm2.C:
* g++.dg/concepts/template-parm3.C:
* g++.dg/concepts/template-parm4.C:
* g++.dg/concepts/template-template-parm1.C:
* g++.dg/concepts/var-concept1.C:
* g++.dg/concepts/var-concept2.C:
* g++.dg/concepts/var-concept3.C:
* g++.dg/concepts/var-concept4.C:
* g++.dg/concepts/var-concept5.C:
* g++.dg/concepts/var-concept6.C:
* g++.dg/concepts/var-concept7.C:
* g++.dg/concepts/var-templ2.C:
* g++.dg/concepts/var-templ3.C:
* g++.dg/concepts/variadic1.C:
* g++.dg/concepts/variadic2.C:
* g++.dg/concepts/variadic3.C:
* g++.dg/concepts/variadic4.C:
* g++.dg/cpp2a/concepts-pr65575.C:
* g++.dg/cpp2a/concepts-pr66091.C:
* g++.dg/cpp2a/concepts-pr84980.C:
* g++.dg/cpp2a/concepts-pr85265.C: Pass -fconcepts-ts.
* g++.dg/cpp2a/concepts-pr84979-2.C:
* g++.dg/cpp2a/concepts-pr84979-3.C: Same diagnostics
in C++20 and below.
---
 gcc/doc/invoke.texi| 14 +++---
 gcc/c-family/c-opts.cc |  3 ---
 gcc/cp/parser.cc   |  7 ---
 gcc/testsuite/g++.dg/concepts/auto1.C  |  2 +-
 gcc/testsuite/g++.dg/concepts/auto3.C  |  2 +-
 gcc/testsuite/g++.dg/concepts/auto4.C  |  2 +-
 gcc/testsuite/g++.dg/concepts/class-deduction1.C   |  2 +-
 gcc/testsuite/g++.dg/concepts/class5.C |  2 +-
 gcc/testsuite/g++.dg/concepts/class6.C |  2 +-
 gcc/testsuite/g++.dg/concepts/debug1.C |  2 +-
 gcc/testsuite/g++.dg/concepts/decl-diagnose.C  |  2 +-
 .../g++.dg/concepts/deduction-constraint1.C|  2 +-
 

Re: [PATCH] amdgcn: Fix instruction generation for exp2 and log2 operations

2022-11-03 Thread Andrew Stubbs

On 03/11/2022 17:47, Kwok Cheung Yeung wrote:

Hello

This patch fixes a bug introduced in a previous patch adding support for 
generating native instructions for the exp2 and log2 patterns. The 
problem is that the name of the instruction implementing the exp2 
operation is v_exp (and not v_exp2), and similarly log2 is implemented 
by v_log, so we cannot use the RTL name of the operation when outputting 
the instruction.


I've added an extra iterator for the GCN operation name and used that 
when outputting instructions instead. I have also added an extra 
testcase for GCN that exercises this case.


Okay for trunk?


OK.

Andrew



[committed 8/8] analyzer: use std::unique_ptr for state machines from plugins

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* analyzer.h: Use std::unique_ptr for state machines from plugins.
* engine.cc: Likewise.

gcc/testsuite/ChangeLog:
* gcc.dg/plugin/analyzer_gil_plugin.c: Use std::unique_ptr for
state machines from plugins.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/analyzer.h   | 2 +-
 gcc/analyzer/engine.cc| 4 ++--
 gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 88fdc1d04f0..c0041c35d1a 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -242,7 +242,7 @@ public:
 class plugin_analyzer_init_iface
 {
 public:
-  virtual void register_state_machine (state_machine *) = 0;
+  virtual void register_state_machine (std::unique_ptr) = 0;
   virtual void register_known_function (const char *name,
std::unique_ptr) = 0;
   virtual logger *get_logger () const = 0;
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index fe17f8f76ce..9c32afc6c71 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -5953,10 +5953,10 @@ public:
 m_logger (logger)
   {}
 
-  void register_state_machine (state_machine *sm) final override
+  void register_state_machine (std::unique_ptr sm) final 
override
   {
 LOG_SCOPE (m_logger);
-m_checkers->safe_push (sm);
+m_checkers->safe_push (sm.release ());
   }
 
   void register_known_function (const char *name,
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c 
b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
index cf0baa5670d..b72856bf6f6 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
@@ -410,7 +410,8 @@ gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
   LOG_SCOPE (iface->get_logger ());
   if (0)
 inform (input_location, "got here: gil_analyzer_init_cb");
-  iface->register_state_machine (new gil_state_machine (iface->get_logger ()));
+  iface->register_state_machine
+(make_unique (iface->get_logger ()));
 }
 
 } // namespace ana
-- 
2.26.3



[committed 5/8] analyzer: use std::unique_ptr for checker_event

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* call-info.cc: Use std::unique_ptr for checker_event.
* checker-path.cc: Likewise.
* checker-path.h: Likewise.
* diagnostic-manager.cc: Likewise.
* engine.cc: Likewise.
* pending-diagnostic.cc: Likewise.
* sm-signal.cc: Likewise.
* varargs.cc: Likewise.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/call-info.cc  |   9 +-
 gcc/analyzer/checker-path.cc   |  25 ++---
 gcc/analyzer/checker-path.h|   4 +-
 gcc/analyzer/diagnostic-manager.cc | 146 +++--
 gcc/analyzer/engine.cc |  40 
 gcc/analyzer/pending-diagnostic.cc |  13 +--
 gcc/analyzer/sm-signal.cc  |   2 +-
 gcc/analyzer/varargs.cc|  14 +--
 8 files changed, 133 insertions(+), 120 deletions(-)

diff --git a/gcc/analyzer/call-info.cc b/gcc/analyzer/call-info.cc
index 3572e06d14b..ffdab73b165 100644
--- a/gcc/analyzer/call-info.cc
+++ b/gcc/analyzer/call-info.cc
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "analyzer/diagnostic-manager.h"
 #include "analyzer/exploded-graph.h"
 #include "analyzer/call-info.h"
+#include "make-unique.h"
 
 #if ENABLE_ANALYZER
 
@@ -113,10 +114,10 @@ call_info::add_events_to_path (checker_path 
*emission_path,
   tree caller_fndecl = src_point.get_fndecl ();
   const int stack_depth = src_point.get_stack_depth ();
 
-  emission_path->add_event (new call_event (get_call_stmt ()->location,
-   caller_fndecl,
-   stack_depth,
-   this));
+  emission_path->add_event (make_unique (get_call_stmt 
()->location,
+caller_fndecl,
+stack_depth,
+this));
 }
 
 /* Recreate a call_details instance from this call_info.  */
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 49940ce839e..40f9ccfe08f 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "analyzer/diagnostic-manager.h"
 #include "analyzer/checker-path.h"
 #include "analyzer/exploded-graph.h"
+#include "make-unique.h"
 
 #if ENABLE_ANALYZER
 
@@ -1262,16 +1263,16 @@ checker_path::add_region_creation_events (const region 
*reg,
 if (const svalue *capacity_sval = model->get_capacity (reg))
   capacity = model->get_representative_tree (capacity_sval);
 
-  add_event (new region_creation_event (reg, capacity, RCE_MEM_SPACE,
-   loc, fndecl, depth));
+  add_event (make_unique (reg, capacity, RCE_MEM_SPACE,
+loc, fndecl, depth));
 
   if (capacity)
-add_event (new region_creation_event (reg, capacity, RCE_CAPACITY,
- loc, fndecl, depth));
+add_event (make_unique (reg, capacity, RCE_CAPACITY,
+  loc, fndecl, depth));
 
   if (debug)
-add_event (new region_creation_event (reg, capacity, RCE_DEBUG,
- loc, fndecl, depth));
+add_event (make_unique (reg, capacity, RCE_DEBUG,
+  loc, fndecl, depth));
 }
 
 /* Add a warning_event to the end of this path.  */
@@ -1281,12 +1282,12 @@ checker_path::add_final_event (const state_machine *sm,
   const exploded_node *enode, const gimple *stmt,
   tree var, state_machine::state_t state)
 {
-  checker_event *end_of_path
-= new warning_event (get_stmt_location (stmt, enode->get_function ()),
-enode->get_function ()->decl,
-enode->get_stack_depth (),
-sm, var, state);
-  add_event (end_of_path);
+  add_event
+(make_unique (get_stmt_location (stmt,
+   enode->get_function ()),
+enode->get_function ()->decl,
+enode->get_stack_depth (),
+sm, var, state));
 }
 
 void
diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h
index 5d009340189..c8de5c9be2c 100644
--- a/gcc/analyzer/checker-path.h
+++ b/gcc/analyzer/checker-path.h
@@ -631,9 +631,9 @@ public:
 
   void maybe_log (logger *logger, const char *desc) const;
 
-  void add_event (checker_event *event)
+  void add_event (std::unique_ptr event)
   {
-m_events.safe_push (event);
+m_events.safe_push (event.release ());
   }
 
   void delete_event (int idx)
diff --git a/gcc/analyzer/diagnostic-manager.cc 
b/gcc/analyzer/diagnostic-manager.cc
index 0a8a2e8df8c..e77547567c1 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ 

[committed 1/8] analyzer: use std::unique_ptr for pending_diagnostic/note

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* call-info.cc: Add define of INCLUDE_MEMORY.
* call-summary.cc: Likewise.
* checker-path.cc: Likewise.
* constraint-manager.cc: Likewise.
* diagnostic-manager.cc: Likewise.
(saved_diagnostic::saved_diagnostic): Use std::unique_ptr for
param d and field m_d.
(saved_diagnostic::~saved_diagnostic): Remove explicit delete of m_d.
(saved_diagnostic::add_note): Use std::unique_ptr for
param pn.
(saved_diagnostic::get_pending_diagnostic): Update for conversion
of m_sd.m_d to unique_ptr.
(diagnostic_manager::add_diagnostic): Use std::unique_ptr for
param d.  Remove explicit deletion.
(diagnostic_manager::add_note): Use std::unique_ptr for param pn.
(diagnostic_manager::emit_saved_diagnostic): Update for conversion
of m_sd.m_d to unique_ptr.
(null_assignment_sm_context::warn): Use std::unique_ptr for
param d.  Remove explicit deletion.
* diagnostic-manager.h (saved_diagnostic::saved_diagnostic): Use
std::unique_ptr for param d.
(saved_diagnostic::add_note): Likewise for param pn.
(saved_diagnostic::m_d): Likewise.
(diagnostic_manager::add_diagnostic): Use std::unique_ptr for
param d.
(diagnostic_manager::add_note): Use std::unique_ptr for param pn.
* engine.cc: Include "make-unique.h".
(impl_region_model_context::warn): Update to use std::unique_ptr
for param, removing explicit deletion.
(impl_region_model_context::add_note): Likewise.
(impl_sm_context::warn): Update to use std::unique_ptr
for param.
(impl_region_model_context::on_state_leak): Likewise for result of
on_leak.
(exploded_node::on_longjmp): Use make_unique when creating
pending_diagnostic.
(exploded_graph::process_node): Likewise.
* exploded-graph.h (impl_region_model_context::warn): Update to
use std::unique_ptr for param.
(impl_region_model_context::add_note): Likewise.
* feasible-graph.cc: Add define of INCLUDE_MEMORY.
* pending-diagnostic.cc: Likewise.
* pending-diagnostic.h: Include analyzer.sm.h"
* program-point.cc: Add define of INCLUDE_MEMORY.
* program-state.cc: Likewise.
* region-model-asm.cc: Likewise.
* region-model-impl-calls.cc: Likewise.  Include "make-unique.h".
(region_model::impl_call_putenv): Use make_unique when creating
pending_diagnostic.
* region-model-manager.cc: Add define of INCLUDE_MEMORY.
* region-model-reachability.cc: Likewise.
* region-model.cc: Likewise.  Include "make-unique.h".
(region_model::get_gassign_result): Use make_unique when creating
pending_diagnostic.
(region_model::check_for_poison): Likewise.
(region_model::on_stmt_pre): Likewise.
(region_model::check_symbolic_bounds): Likewise.
(region_model::check_region_bounds): Likewise.
(annotating_ctxt: make_note): Use std::unique_ptr for result.
(region_model::deref_rvalue): Use make_unique when creating
pending_diagnostic.
(region_model::check_for_writable_region): Likewise.
(region_model::check_region_size): Likewise.
(region_model::check_dynamic_size_for_floats): Likewise.
(region_model::maybe_complain_about_infoleak): Likewise.
(noop_region_model_context::add_note): Use std::unique_ptr for
param.  Remove explicit deletion.
* region-model.h: Include "analyzer/pending-diagnostic.h".
(region_model_context::warn): Convert param to std::unique_ptr.
(region_model_context::add_note): Likewise.
(noop_region_model_context::warn): Likewise.
(noop_region_model_context::add_note): Likewise.
(region_model_context_decorator::warn): Likewise.
(region_model_context_decorator::add_note): Likewise.
(note_adding_context::warn): Likewise.
(note_adding_context::make_note): Likewise for return type.
(test_region_model_context::warn): Convert param to
std::unique_ptr.
* region.cc: Add define of INCLUDE_MEMORY.
* sm-fd.cc: Likewise.  Include "make-unique.h".
(fd_state_machine::check_for_fd_attrs): Use make_unique when
creating pending_diagnostics.
(fd_state_machine::on_open): Likewise.
(fd_state_machine::on_creat): Likewise.
(fd_state_machine::check_for_dup): Likewise.
(fd_state_machine::on_close): Likewise.
(fd_state_machine::check_for_open_fd): Likewise.
(fd_state_machine::on_leak): Likewise, converting return type to
std::unique_ptr.
* sm-file.cc: Add define of INCLUDE_MEMORY.  Include
"make-unique.h".
(fileptr_state_machine::on_stmt): Use make_unique when creating
pending_diagnostic.
(fileptr_state_machine::on_leak): 

[committed 6/8] analyzer: use std::unique_ptr during bifurcation

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* analysis-plan.cc: Define INCLUDE_MEMORY before including
system.h.
* analyzer-pass.cc: Likewise.
* analyzer-selftests.cc: Likewise.
* analyzer.cc: Likewise.
* analyzer.h: Use std::unique_ptr in bifurcation code.
* call-string.cc: Define INCLUDE_MEMORY before including system.h.
* complexity.cc: Likewise.
* engine.cc: Use std::unique_ptr in bifurcation code.
* exploded-graph.h: Likewise.
* known-function-manager.cc: Define INCLUDE_MEMORY before
including system.h.
* region-model-impl-calls.cc: Use std::unique_ptr in bifurcation
code.
* region-model.cc: Likewise.
* region-model.h: Likewise.
* supergraph.cc: Define INCLUDE_MEMORY before including system.h.

gcc/testsuite/ChangeLog:
* gcc.dg/plugin/analyzer_kernel_plugin.c: Include "make-unique.h".
Use std::unique_ptr in bifurcation code.
* gcc.dg/plugin/analyzer_known_fns_plugin.c: Likewise.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/analysis-plan.cc  |  1 +
 gcc/analyzer/analyzer-pass.cc  |  1 +
 gcc/analyzer/analyzer-selftests.cc |  1 +
 gcc/analyzer/analyzer.cc   |  1 +
 gcc/analyzer/analyzer.h|  5 ++---
 gcc/analyzer/call-string.cc|  1 +
 gcc/analyzer/complexity.cc |  1 +
 gcc/analyzer/engine.cc | 18 --
 gcc/analyzer/exploded-graph.h  |  2 +-
 gcc/analyzer/known-function-manager.cc |  1 +
 gcc/analyzer/region-model-impl-calls.cc| 12 ++--
 gcc/analyzer/region-model.cc   |  3 +--
 gcc/analyzer/region-model.h| 11 +--
 gcc/analyzer/supergraph.cc |  1 +
 .../gcc.dg/plugin/analyzer_kernel_plugin.c |  3 ++-
 .../gcc.dg/plugin/analyzer_known_fns_plugin.c  |  3 ++-
 16 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/gcc/analyzer/analysis-plan.cc b/gcc/analyzer/analysis-plan.cc
index a4a42c5cd3d..aa75bd6b67e 100644
--- a/gcc/analyzer/analysis-plan.cc
+++ b/gcc/analyzer/analysis-plan.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
diff --git a/gcc/analyzer/analyzer-pass.cc b/gcc/analyzer/analyzer-pass.cc
index fc7098ddccb..423595f45f0 100644
--- a/gcc/analyzer/analyzer-pass.cc
+++ b/gcc/analyzer/analyzer-pass.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "context.h"
diff --git a/gcc/analyzer/analyzer-selftests.cc 
b/gcc/analyzer/analyzer-selftests.cc
index 278c245f415..028cc5ed009 100644
--- a/gcc/analyzer/analyzer-selftests.cc
+++ b/gcc/analyzer/analyzer-selftests.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 6c7c969538c..899202bb44c 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index c41cfb01656..d8d3e78b20a 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -300,9 +300,8 @@ class path_context
 public:
   virtual ~path_context () {}
 
-  /* Hook for clients to split state with a non-standard path.
- Take ownership of INFO.  */
-  virtual void bifurcate (custom_edge_info *info) = 0;
+  /* Hook for clients to split state with a non-standard path.  */
+  virtual void bifurcate (std::unique_ptr info) = 0;
 
   /* Hook for clients to terminate the standard path.  */
   virtual void terminate_path () = 0;
diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc
index f0a30d9b2b6..5caf92155b9 100644
--- a/gcc/analyzer/call-string.cc
+++ b/gcc/analyzer/call-string.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
 #include "pretty-print.h"
diff --git a/gcc/analyzer/complexity.cc b/gcc/analyzer/complexity.cc
index 39fbbc133f4..2756f961d80 100644
--- a/gcc/analyzer/complexity.cc
+++ b/gcc/analyzer/complexity.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#define 

[committed 7/8] analyzer: use std::unique_ptr for known functions

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* analyzer.h: Use std::unique_ptr for known functions.
* engine.cc: Likewise.
* known-function-manager.cc: Likewise.
* known-function-manager.h: Likewise.

gcc/testsuite/ChangeLog:
* gcc.dg/plugin/analyzer_kernel_plugin.c: Use std::unique_ptr for
known functions.
* gcc.dg/plugin/analyzer_known_fns_plugin.c: Likewise.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/analyzer.h | 2 +-
 gcc/analyzer/engine.cc  | 4 ++--
 gcc/analyzer/known-function-manager.cc  | 5 +++--
 gcc/analyzer/known-function-manager.h   | 2 +-
 gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c| 7 ---
 gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c | 7 ---
 6 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index d8d3e78b20a..88fdc1d04f0 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -244,7 +244,7 @@ class plugin_analyzer_init_iface
 public:
   virtual void register_state_machine (state_machine *) = 0;
   virtual void register_known_function (const char *name,
-   known_function *) = 0;
+   std::unique_ptr) = 0;
   virtual logger *get_logger () const = 0;
 };
 
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index d770c6fc29c..fe17f8f76ce 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -5960,10 +5960,10 @@ public:
   }
 
   void register_known_function (const char *name,
-   known_function *kf) final override
+   std::unique_ptr kf) final 
override
   {
 LOG_SCOPE (m_logger);
-m_known_fn_mgr->add (name, kf);
+m_known_fn_mgr->add (name, std::move (kf));
   }
 
   logger *get_logger () const final override
diff --git a/gcc/analyzer/known-function-manager.cc 
b/gcc/analyzer/known-function-manager.cc
index 42dfe3af583..7341b068480 100644
--- a/gcc/analyzer/known-function-manager.cc
+++ b/gcc/analyzer/known-function-manager.cc
@@ -48,11 +48,12 @@ known_function_manager::~known_function_manager ()
 }
 
 void
-known_function_manager::add (const char *name, known_function *kf)
+known_function_manager::add (const char *name,
+std::unique_ptr kf)
 {
   LOG_FUNC_1 (get_logger (), "registering %s", name);
   tree id = get_identifier (name);
-  m_map_id_to_kf.put (id, kf);
+  m_map_id_to_kf.put (id, kf.release ());
 }
 
 const known_function *
diff --git a/gcc/analyzer/known-function-manager.h 
b/gcc/analyzer/known-function-manager.h
index 2b95b7e2589..daf1bc57855 100644
--- a/gcc/analyzer/known-function-manager.h
+++ b/gcc/analyzer/known-function-manager.h
@@ -30,7 +30,7 @@ class known_function_manager : public log_user
 public:
   known_function_manager (logger *logger);
   ~known_function_manager ();
-  void add (const char *name, known_function *kf);
+  void add (const char *name, std::unique_ptr kf);
   const known_function *get_by_identifier (tree identifier);
   const known_function *get_by_fndecl (tree fndecl);
 
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c 
b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c
index dfa30c8d61b..92b4dfbd4d0 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c
@@ -210,10 +210,11 @@ kernel_analyzer_init_cb (void *gcc_data, void 
*/*user_data*/)
   LOG_SCOPE (iface->get_logger ());
   if (0)
 inform (input_location, "got here: kernel_analyzer_init_cb");
-  iface->register_known_function ("copy_from_user",
- new known_function_copy_from_user ());
+  iface->register_known_function
+("copy_from_user",
+ make_unique ());
   iface->register_known_function ("copy_to_user",
- new known_function_copy_to_user ());
+ make_unique ());
 }
 
 } // namespace ana
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c 
b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c
index 5c1f3986aa7..e9f607f58fe 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c
@@ -175,9 +175,10 @@ known_fn_analyzer_init_cb (void *gcc_data, void 
*/*user_data*/)
   if (0)
 inform (input_location, "got here: known_fn_analyzer_init_cb");
   iface->register_known_function ("returns_42",
- new known_function_returns_42 ());
-  iface->register_known_function ("attempt_to_copy",
- new known_function_attempt_to_copy ());
+ make_unique ());
+  iface->register_known_function
+("attempt_to_copy",
+ make_unique ());
 }
 
 } // namespace ana
-- 
2.26.3



[committed 3/8] analyzer: use std::unique_ptr for custom_edge_info pointers

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* checker-path.cc (rewind_event::rewind_event): Update for usage of
std::unique_ptr on custom_edge_info.
* engine.cc (exploded_node::on_longjmp): Likewise.
(exploded_edge::exploded_edge): Likewise.
(exploded_edge::~exploded_edge): Delete.
(exploded_graph::add_function_entry): Update for usage of
std::unique_ptr on custom_edge_info.
(exploded_graph::add_edge): Likewise.
(add_tainted_args_callback): Likewise.
(exploded_graph::maybe_create_dynamic_call): Likewise.
(exploded_graph::process_node): Likewise.
* exploded-graph.h (exploded_edge::~exploded_edge): Delete.
(exploded_edge::m_custom_info): Use std::unique_ptr.
(exploded_edge::add_edge): Likewise.
* sm-signal.cc (register_signal_handler::impl_transition): Use
make_unique.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/checker-path.cc  |  2 +-
 gcc/analyzer/engine.cc| 52 +--
 gcc/analyzer/exploded-graph.h | 11 +++-
 gcc/analyzer/sm-signal.cc |  2 +-
 4 files changed, 25 insertions(+), 42 deletions(-)

diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 4cf28c2af86..49940ce839e 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -1037,7 +1037,7 @@ rewind_event::rewind_event (const exploded_edge *eedge,
   m_rewind_info (rewind_info),
   m_eedge (eedge)
 {
-  gcc_assert (m_eedge->m_custom_info == m_rewind_info);
+  gcc_assert (m_eedge->m_custom_info.get () == m_rewind_info);
 }
 
 /* class rewind_from_longjmp_event : public rewind_event.  */
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 553957ad982..c7bc63e48a5 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1878,7 +1878,7 @@ exploded_node::on_longjmp (exploded_graph ,
 {
   exploded_edge *eedge
= eg.add_edge (const_cast (this), next, NULL,
-  new rewind_info_t (tmp_setjmp_record, longjmp_call));
+  make_unique (tmp_setjmp_record, 
longjmp_call));
 
   /* For any diagnostics that were queued here (such as leaks) we want
 the checker_path to show the rewinding events after the "final event"
@@ -2089,19 +2089,12 @@ rewind_info_t::add_events_to_path (checker_path 
*emission_path,
 
 exploded_edge::exploded_edge (exploded_node *src, exploded_node *dest,
  const superedge *sedge,
- custom_edge_info *custom_info)
+ std::unique_ptr custom_info)
 : dedge (src, dest), m_sedge (sedge),
-  m_custom_info (custom_info)
+  m_custom_info (std::move (custom_info))
 {
 }
 
-/* exploded_edge's dtor.  */
-
-exploded_edge::~exploded_edge ()
-{
-  delete m_custom_info;
-}
-
 /* Implementation of dedge::dump_dot vfunc for exploded_edge.
Use the label of the underlying superedge, if any.  */
 
@@ -2709,12 +2702,12 @@ exploded_graph::add_function_entry (function *fun)
   program_state state (m_ext_state);
   state.push_frame (m_ext_state, fun);
 
-  custom_edge_info *edge_info = NULL;
+  std::unique_ptr edge_info = NULL;
 
   if (lookup_attribute ("tainted_args", DECL_ATTRIBUTES (fun->decl)))
 {
   if (mark_params_as_tainted (, fun->decl, m_ext_state))
-   edge_info = new tainted_args_function_info (fun->decl);
+   edge_info = make_unique (fun->decl);
 }
 
   if (!state.m_valid)
@@ -2722,12 +2715,9 @@ exploded_graph::add_function_entry (function *fun)
 
   exploded_node *enode = get_or_create_node (point, state, NULL);
   if (!enode)
-{
-  delete edge_info;
-  return NULL;
-}
+return NULL;
 
-  add_edge (m_origin, enode, NULL, edge_info);
+  add_edge (m_origin, enode, NULL, std::move (edge_info));
 
   m_functions_with_enodes.add (fun);
 
@@ -2925,18 +2915,19 @@ exploded_graph::get_or_create_node (const program_point 
,
 
 /* Add an exploded_edge from SRC to DEST, recording its association
with SEDGE (which may be NULL), and, if non-NULL, taking ownership
-   of REWIND_INFO.
+   of CUSTOM_INFO.
Return the newly-created eedge.  */
 
 exploded_edge *
 exploded_graph::add_edge (exploded_node *src, exploded_node *dest,
  const superedge *sedge,
- custom_edge_info *custom_info)
+   std::unique_ptr custom_info)
 {
   if (get_logger ())
 get_logger ()->log ("creating edge EN: %i -> EN: %i",
src->m_index, dest->m_index);
-  exploded_edge *e = new exploded_edge (src, dest, sedge, custom_info);
+  exploded_edge *e = new exploded_edge (src, dest, sedge,
+   std::move (custom_info));
   digraph::add_edge (e);
   return e;
 }
@@ -3183,9 +3174,8 @@ add_tainted_args_callback (exploded_graph *eg, tree 
field, tree fndecl,
}
 }
 
-  tainted_args_call_info *info
-= new tainted_args_call_info (field, 

[committed 2/8] analyzer: use std::unique_ptr for saved_diagnostic::m_stmt_finder

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* diagnostic-manager.cc (saved_diagnostic::saved_diagnostic): Make
stmt_finder const.
(saved_diagnostic::~saved_diagnostic): Remove explicit delete of
m_stmt_finder.
(diagnostic_manager::add_diagnostic): Make stmt_finder const.
* diagnostic-manager.h (saved_diagnostic::saved_diagnostic):
Likewise.
(saved_diagnostic::m_stmt_finder): Convert to std::unique_ptr.
(diagnostic_manager::add_diagnostic): Make stmt_finder const.
* engine.cc (impl_sm_context::impl_sm_context): Likewise.
(impl_sm_context::m_stmt_finder): Likewise.
(leak_stmt_finder::clone): Convert return type to std::unique_ptr.
* exploded-graph.h (stmt_finder::clone): Likewise.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/diagnostic-manager.cc | 7 +++
 gcc/analyzer/diagnostic-manager.h  | 8 
 gcc/analyzer/engine.cc | 8 
 gcc/analyzer/exploded-graph.h  | 2 +-
 4 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/gcc/analyzer/diagnostic-manager.cc 
b/gcc/analyzer/diagnostic-manager.cc
index 0444e52258c..bb8584a1e0b 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -635,7 +635,7 @@ epath_finder::dump_feasible_path (const exploded_node 
*target_enode,
 saved_diagnostic::saved_diagnostic (const state_machine *sm,
const exploded_node *enode,
const supernode *snode, const gimple *stmt,
-   stmt_finder *stmt_finder,
+   const stmt_finder *stmt_finder,
tree var,
const svalue *sval,
state_machine::state_t state,
@@ -662,7 +662,6 @@ saved_diagnostic::saved_diagnostic (const state_machine *sm,
 
 saved_diagnostic::~saved_diagnostic ()
 {
-  delete m_stmt_finder;
   delete m_best_epath;
   delete m_problem;
 }
@@ -961,7 +960,7 @@ bool
 diagnostic_manager::add_diagnostic (const state_machine *sm,
exploded_node *enode,
const supernode *snode, const gimple *stmt,
-   stmt_finder *finder,
+   const stmt_finder *finder,
tree var,
const svalue *sval,
state_machine::state_t state,
@@ -1010,7 +1009,7 @@ diagnostic_manager::add_diagnostic (const state_machine 
*sm,
 bool
 diagnostic_manager::add_diagnostic (exploded_node *enode,
const supernode *snode, const gimple *stmt,
-   stmt_finder *finder,
+   const stmt_finder *finder,
std::unique_ptr d)
 {
   gcc_assert (enode);
diff --git a/gcc/analyzer/diagnostic-manager.h 
b/gcc/analyzer/diagnostic-manager.h
index fdab038d7a1..c87f2159753 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -33,7 +33,7 @@ public:
   saved_diagnostic (const state_machine *sm,
const exploded_node *enode,
const supernode *snode, const gimple *stmt,
-   stmt_finder *stmt_finder,
+   const stmt_finder *stmt_finder,
tree var, const svalue *sval,
state_machine::state_t state,
std::unique_ptr d,
@@ -72,7 +72,7 @@ public:
   const exploded_node *m_enode;
   const supernode *m_snode;
   const gimple *m_stmt;
-  stmt_finder *m_stmt_finder;
+  std::unique_ptr m_stmt_finder;
   tree m_var;
   const svalue *m_sval;
   state_machine::state_t m_state;
@@ -113,7 +113,7 @@ public:
   bool add_diagnostic (const state_machine *sm,
   exploded_node *enode,
   const supernode *snode, const gimple *stmt,
-  stmt_finder *finder,
+  const stmt_finder *finder,
   tree var,
   const svalue *sval,
   state_machine::state_t state,
@@ -121,7 +121,7 @@ public:
 
   bool add_diagnostic (exploded_node *enode,
   const supernode *snode, const gimple *stmt,
-  stmt_finder *finder,
+  const stmt_finder *finder,
   std::unique_ptr d);
 
   void add_note (std::unique_ptr pn);
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index fd532b1384d..553957ad982 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -282,7 +282,7 @@ public:
   const sm_state_map *old_smap,
   sm_state_map *new_smap,
   path_context *path_ctxt,
-  stmt_finder *stmt_finder = NULL,
+  const 

[committed 4/8] analyzer: use std::unique_ptr for feasibility_problems and exploded_path

2022-11-03 Thread David Malcolm via Gcc-patches
gcc/analyzer/ChangeLog:
* diagnostic-manager.cc: Include "make-unique.h".
Use std::unique_ptr for feasibility_problems and exploded_path.
Delete explicit saved_diagnostic dtor.
* diagnostic-manager.h: Likewise.
* engine.cc: Likewise.
* exploded-graph.h: Likewise.
* feasible-graph.cc: Likewise.
* feasible-graph.h: Likewise.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/diagnostic-manager.cc | 64 ++
 gcc/analyzer/diagnostic-manager.h  |  9 ++---
 gcc/analyzer/engine.cc |  9 +++--
 gcc/analyzer/exploded-graph.h  |  2 +-
 gcc/analyzer/feasible-graph.cc |  4 +-
 gcc/analyzer/feasible-graph.h  |  2 +-
 6 files changed, 43 insertions(+), 47 deletions(-)

diff --git a/gcc/analyzer/diagnostic-manager.cc 
b/gcc/analyzer/diagnostic-manager.cc
index bb8584a1e0b..0a8a2e8df8c 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "analyzer/feasible-graph.h"
 #include "analyzer/checker-path.h"
 #include "analyzer/reachability.h"
+#include "make-unique.h"
 
 #if ENABLE_ANALYZER
 
@@ -85,21 +86,24 @@ public:
 
   logger *get_logger () const { return m_eg.get_logger (); }
 
-  exploded_path *get_best_epath (const exploded_node *target_enode,
-const char *desc, unsigned diag_idx,
-feasibility_problem **out_problem);
+  std::unique_ptr
+  get_best_epath (const exploded_node *target_enode,
+ const char *desc, unsigned diag_idx,
+ std::unique_ptr *out_problem);
 
 private:
   DISABLE_COPY_AND_ASSIGN(epath_finder);
 
-  exploded_path *explore_feasible_paths (const exploded_node *target_enode,
-const char *desc, unsigned diag_idx);
-  bool process_worklist_item (feasible_worklist *worklist,
- const trimmed_graph ,
- feasible_graph *fg,
- const exploded_node *target_enode,
- unsigned diag_idx,
- exploded_path **out_best_path) const;
+  std::unique_ptr
+  explore_feasible_paths (const exploded_node *target_enode,
+ const char *desc, unsigned diag_idx);
+  bool
+  process_worklist_item (feasible_worklist *worklist,
+const trimmed_graph ,
+feasible_graph *fg,
+const exploded_node *target_enode,
+unsigned diag_idx,
+std::unique_ptr *out_best_path) const;
   void dump_trimmed_graph (const exploded_node *target_enode,
   const char *desc, unsigned diag_idx,
   const trimmed_graph ,
@@ -132,10 +136,10 @@ private:
 
Write any feasibility_problem to *OUT_PROBLEM.  */
 
-exploded_path *
+std::unique_ptr
 epath_finder::get_best_epath (const exploded_node *enode,
  const char *desc, unsigned diag_idx,
- feasibility_problem **out_problem)
+ std::unique_ptr *out_problem)
 {
   logger *logger = get_logger ();
   LOG_SCOPE (logger);
@@ -156,7 +160,8 @@ epath_finder::get_best_epath (const exploded_node *enode,
   /* Attempt to find the shortest feasible path using feasible_graph.  */
   if (logger)
logger->log ("trying to find shortest feasible path");
-  if (exploded_path *epath = explore_feasible_paths (enode, desc, 
diag_idx))
+  if (std::unique_ptr epath
+   = explore_feasible_paths (enode, desc, diag_idx))
{
  if (logger)
logger->log ("accepting %qs at EN: %i, SN: %i (sd: %i)"
@@ -184,8 +189,8 @@ epath_finder::get_best_epath (const exploded_node *enode,
   if (logger)
logger->log ("trying to find shortest path ignoring feasibility");
   gcc_assert (m_sep);
-  exploded_path *epath
-   = new exploded_path (m_sep->get_shortest_path (enode));
+  std::unique_ptr epath
+   = make_unique (m_sep->get_shortest_path (enode));
   if (epath->feasible_p (logger, out_problem, m_eg.get_engine (), _eg))
{
  if (logger)
@@ -367,7 +372,7 @@ private:
  continue forever without reaching the target), or
- getting monotonically closer to the termination threshold.  */
 
-exploded_path *
+std::unique_ptr
 epath_finder::explore_feasible_paths (const exploded_node *target_enode,
  const char *desc, unsigned diag_idx)
 {
@@ -405,7 +410,7 @@ epath_finder::explore_feasible_paths (const exploded_node 
*target_enode,
  a limit.  */
 
   /* Set this if we find a feasible path to TARGET_ENODE.  */
-  exploded_path *best_path = NULL;
+  std::unique_ptr best_path = NULL;
 
   {
 auto_checking_feasibility sentinel (mgr);
@@ -447,12 +452,13 @@ 

[committed 0/8] Use std::unique_ptr in analyzer

2022-11-03 Thread David Malcolm via Gcc-patches
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-3629-g6341f14e369a5c through
r13-3636-ge177be86c7d327.

David Malcolm (8):
  analyzer: use std::unique_ptr for pending_diagnostic/note
  analyzer: use std::unique_ptr for saved_diagnostic::m_stmt_finder
  analyzer: use std::unique_ptr for custom_edge_info pointers
  analyzer: use std::unique_ptr for feasibility_problems and
exploded_path
  analyzer: use std::unique_ptr for checker_event
  analyzer: use std::unique_ptr during bifurcation
  analyzer: use std::unique_ptr for known functions
  analyzer: use std::unique_ptr for state machines from plugins

 gcc/analyzer/analysis-plan.cc |   1 +
 gcc/analyzer/analyzer-pass.cc |   1 +
 gcc/analyzer/analyzer-selftests.cc|   1 +
 gcc/analyzer/analyzer.cc  |   1 +
 gcc/analyzer/analyzer.h   |   9 +-
 gcc/analyzer/call-info.cc |  10 +-
 gcc/analyzer/call-string.cc   |   1 +
 gcc/analyzer/call-summary.cc  |   1 +
 gcc/analyzer/checker-path.cc  |  28 +-
 gcc/analyzer/checker-path.h   |   4 +-
 gcc/analyzer/complexity.cc|   1 +
 gcc/analyzer/constraint-manager.cc|   1 +
 gcc/analyzer/diagnostic-manager.cc| 257 +-
 gcc/analyzer/diagnostic-manager.h |  29 +-
 gcc/analyzer/engine.cc| 176 ++--
 gcc/analyzer/exploded-graph.h |  21 +-
 gcc/analyzer/feasible-graph.cc|   5 +-
 gcc/analyzer/feasible-graph.h |   2 +-
 gcc/analyzer/known-function-manager.cc|   6 +-
 gcc/analyzer/known-function-manager.h |   2 +-
 gcc/analyzer/pending-diagnostic.cc|  14 +-
 gcc/analyzer/pending-diagnostic.h |   1 +
 gcc/analyzer/program-point.cc |   1 +
 gcc/analyzer/program-state.cc |   1 +
 gcc/analyzer/region-model-asm.cc  |   1 +
 gcc/analyzer/region-model-impl-calls.cc   |  16 +-
 gcc/analyzer/region-model-manager.cc  |   1 +
 gcc/analyzer/region-model-reachability.cc |   1 +
 gcc/analyzer/region-model.cc  |  90 +++---
 gcc/analyzer/region-model.h   |  42 +--
 gcc/analyzer/region.cc|   1 +
 gcc/analyzer/sm-fd.cc |  58 ++--
 gcc/analyzer/sm-file.cc   |  10 +-
 gcc/analyzer/sm-malloc.cc |  53 ++--
 gcc/analyzer/sm-pattern-test.cc   |   6 +-
 gcc/analyzer/sm-sensitive.cc  |   5 +-
 gcc/analyzer/sm-signal.cc |  10 +-
 gcc/analyzer/sm-taint.cc  |  22 +-
 gcc/analyzer/sm.cc|  10 +
 gcc/analyzer/sm.h |  12 +-
 gcc/analyzer/state-purge.cc   |   1 +
 gcc/analyzer/store.cc |   1 +
 gcc/analyzer/supergraph.cc|   1 +
 gcc/analyzer/svalue.cc|   1 +
 gcc/analyzer/trimmed-graph.cc |   1 +
 gcc/analyzer/varargs.cc   |  38 +--
 .../gcc.dg/plugin/analyzer_gil_plugin.c   |  15 +-
 .../gcc.dg/plugin/analyzer_kernel_plugin.c|  11 +-
 .../gcc.dg/plugin/analyzer_known_fns_plugin.c |  11 +-
 49 files changed, 534 insertions(+), 458 deletions(-)

-- 
2.26.3



[PATCH] amdgcn: Fix instruction generation for exp2 and log2 operations

2022-11-03 Thread Kwok Cheung Yeung

Hello

This patch fixes a bug introduced in a previous patch adding support for 
generating native instructions for the exp2 and log2 patterns. The 
problem is that the name of the instruction implementing the exp2 
operation is v_exp (and not v_exp2), and similarly log2 is implemented 
by v_log, so we cannot use the RTL name of the operation when outputting 
the instruction.


I've added an extra iterator for the GCN operation name and used that 
when outputting instructions instead. I have also added an extra 
testcase for GCN that exercises this case.


Okay for trunk?

Thanks

KwokFrom c0e74e01743cd3a3e0dcb2a071396e3a5751ff4c Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung 
Date: Thu, 3 Nov 2022 17:19:11 +
Subject: [PATCH] amdgcn: Fix instruction generation for exp2 and log2
 operations

The GCN instructions for the exp2 and log2 operations are v_exp_* and v_log_*
respectively, which unfortunately do not line up with the RTL naming
convention.  To deal with this, a new set of int attributes is now used when
generating the assembly for these instructions.

2022-11-03  Kwok Cheung Yeung  

gcc/
* config/gcn/gcn-valu.md (math_unop_insn): New attribute.
(2, 2, 2,
2, *2_insn,
*2_insn): Use math_unop_insn to generate
assembler output.

gcc/testsuite/
* gcc.target/gcn/unsafe-math-1.c: New.
---
 gcc/config/gcn/gcn-valu.md   | 20 ++--
 gcc/testsuite/gcc.target/gcn/unsafe-math-1.c | 10 ++
 2 files changed, 24 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/gcn/unsafe-math-1.c

diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 3b619512e13..9f4353831bd 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -2549,13 +2549,21 @@
(UNSPEC_SIN "sin")
(UNSPEC_COS "cos")])
 
+(define_int_attr math_unop_insn
+  [(UNSPEC_FLOOR "floor")
+   (UNSPEC_CEIL "ceil")
+   (UNSPEC_EXP2 "exp")
+   (UNSPEC_LOG2 "log")
+   (UNSPEC_SIN "sin")
+   (UNSPEC_COS "cos")])
+
 (define_insn "2"
   [(set (match_operand:FP 0 "register_operand"  "=  v")
(unspec:FP
  [(match_operand:FP 1 "gcn_alu_operand" "vSvB")]
  MATH_UNOP_1OR2REG))]
   ""
-  "v_%i0\t%0, %1"
+  "v_%i0\t%0, %1"
   [(set_attr "type" "vop1")
(set_attr "length" "8")])
 
@@ -2565,7 +2573,7 @@
  [(match_operand:V_FP 1 "gcn_alu_operand" "vSvB")]
  MATH_UNOP_1OR2REG))]
   ""
-  "v_%i0\t%0, %1"
+  "v_%i0\t%0, %1"
   [(set_attr "type" "vop1")
(set_attr "length" "8")])
 
@@ -2575,7 +2583,7 @@
  [(match_operand:FP_1REG 1 "gcn_alu_operand" "vSvB")]
  MATH_UNOP_1REG))]
   "flag_unsafe_math_optimizations"
-  "v_%i0\t%0, %1"
+  "v_%i0\t%0, %1"
   [(set_attr "type" "vop1")
(set_attr "length" "8")])
 
@@ -2585,7 +2593,7 @@
  [(match_operand:V_FP_1REG 1 "gcn_alu_operand" "vSvB")]
  MATH_UNOP_1REG))]
   "flag_unsafe_math_optimizations"
-  "v_%i0\t%0, %1"
+  "v_%i0\t%0, %1"
   [(set_attr "type" "vop1")
(set_attr "length" "8")])
 
@@ -2595,7 +2603,7 @@
  [(match_operand:FP_1REG 1 "gcn_alu_operand" "vSvB")]
  MATH_UNOP_TRIG))]
   "flag_unsafe_math_optimizations"
-  "v_%i0\t%0, %1"
+  "v_%i0\t%0, %1"
   [(set_attr "type" "vop1")
(set_attr "length" "8")])
 
@@ -2605,7 +2613,7 @@
  [(match_operand:V_FP_1REG 1 "gcn_alu_operand" "vSvB")]
  MATH_UNOP_TRIG))]
   "flag_unsafe_math_optimizations"
-  "v_%i0\t%0, %1"
+  "v_%i0\t%0, %1"
   [(set_attr "type" "vop1")
(set_attr "length" "8")])
 
diff --git a/gcc/testsuite/gcc.target/gcn/unsafe-math-1.c 
b/gcc/testsuite/gcc.target/gcn/unsafe-math-1.c
new file mode 100644
index 000..2b54fa232e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/unsafe-math-1.c
@@ -0,0 +1,10 @@
+/* { dg-do link } */
+/* { dg-options "-O0 -ffast-math" } */
+
+int main (void)
+{
+  float x = 0.123456f;
+
+  float r1 = __builtin_exp2f (x);
+  float r2 = __builtin_log2f (x);
+}
-- 
2.25.1



[COMMITTED] Update range query cache when a statement is updated.

2022-11-03 Thread Andrew MacLeod via Gcc-patches
Whenever the IL changes under ranger, its possible the resulting range 
calculation could be different. Once cached, we don't really recalculate 
ranges unless we can detect an input range has caused the result to go 
stale.


Simplification and folding can both change the IL in such a way that the 
result can be refined, but it is not obvious to ranger. Ive been looking 
at a case from glibc (I finally produced a reduced testcase which I 
included) where the original IL is


 __message_length_90 = __builtin_strlen (iftmp.39_117);

for which which we calculate a range:

  [irange] size_t [0, 9223372036854775805] NONZERO 0x7fff

Then in vrp1, simplification at the last second changes the IL to:

 __message_length_90 = 52;

but range has no way to know this has happened, and continues with the 
original range.  This eventually feeds


_39 = __builtin_constant_p (__message_length_90);

and if we are not aware of the new range, we fold this builtin the wrong 
way.  Then a function with no linkage that should have been removed 
remains in the object, and glibc builds break. doh.



I've been looking at various alternatives, none of which I liked much.  
I tried a final re-evaluation every time we looked at a stmt for the 
last time in VRP, but that was a 20% penalty. yuck.


What I finally settled on is simple and effective for all passes.  ssa 
has an update_stmt() call which is invoked to ensure all the 
ssa-operands are updated properly when the IL changes.  I added an 
update_stmt call to the generic range_query (which does nothing), then 
overload it in ranger to force a recalculation of the statement, and 
update the global value only if it changes as a result.


THis solves the problem elegantly, and will be applicable no matter 
where and how the IL changes.  The overhead of adding the call to 
update_stmt is very minute..  0.01% overall, and the VRP pass itself 
only slows down by 0.3%.


And this should allow glibc to build again.

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

Andrew
From 6fd485d15c1a2c427c39bcd45e03bed8cde689e6 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Wed, 2 Nov 2022 21:37:49 -0400
Subject: [PATCH] Update range query cache when a statement is updated.

Add an update_stmt interface to range query, and hook into it with the
ssa statement update call.

	gcc/
	* gimple-range.cc (gimple_ranger::update_stmt): New.
	* gimple-range.h (gimple_ranger::update_stmt): New prototype.
	* tree-ssa-operands.cc (update_stmt_operands): Notify range
	query that stmt has changed.
	* value-query.h (range_query::update_stmt): New.

	gcc/testsuite/
	* gcc.dg/tree-ssa/vrp-update.c: New.
---
 gcc/gimple-range.cc| 34 ++
 gcc/gimple-range.h |  1 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-update.c | 21 +
 gcc/tree-ssa-operands.cc   |  3 ++
 gcc/value-query.h  |  3 ++
 5 files changed, 62 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-update.c

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 110cf574454..806386918bd 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -482,6 +482,40 @@ gimple_ranger::register_inferred_ranges (gimple *s)
   m_cache.apply_inferred_ranges (s);
 }
 
+// When a statement S has changed since the result was cached, re-evaluate
+// and update the global cache.
+
+void
+gimple_ranger::update_stmt (gimple *s)
+{
+  tree lhs = gimple_get_lhs (s);
+  if (!lhs || !gimple_range_ssa_p (lhs))
+return;
+  Value_Range r (TREE_TYPE (lhs));
+  // Only update if it already had a value.
+  if (m_cache.get_global_range (r, lhs))
+{
+  // Re-calculate a new value using just cache values.
+  Value_Range tmp (TREE_TYPE (lhs));
+  fold_using_range f;
+  fur_depend src (s, &(gori ()), _cache);
+  f.fold_stmt (tmp, s, src, lhs);
+
+  // Combine the new value with the old value to check for a change.
+  if (r.intersect (tmp))
+	{
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	{
+	  print_generic_expr (dump_file, lhs, TDF_SLIM);
+	  fprintf (dump_file, " : global value re-evaluated to ");
+	  r.dump (dump_file);
+	  fputc ('\n', dump_file);
+	}
+	  m_cache.set_global_range (lhs, r);
+	}
+}
+}
+
 // This routine will export whatever global ranges are known to GCC
 // SSA_RANGE_NAME_INFO and SSA_NAME_PTR_INFO fields.
 
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 4800bfbf890..22e05f645f8 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -51,6 +51,7 @@ public:
   virtual bool range_of_stmt (vrange , gimple *, tree name = NULL) override;
   virtual bool range_of_expr (vrange , tree name, gimple * = NULL) override;
   virtual bool range_on_edge (vrange , edge e, tree name) override;
+  virtual void update_stmt (gimple *) override;
   void range_on_entry (vrange , basic_block bb, tree name);
   void range_on_exit (vrange , 

Re: [PATCH] libstdc++: Declare const global variables inline

2022-11-03 Thread Jonathan Wakely via Gcc-patches
On Wed, 2 Nov 2022 at 13:42, Patrick Palka via Libstdc++
 wrote:
>
> IIUC such variables should be declared inline to avoid potential ODR
> violations since they're otherwise considered to be distinct (internal
> linkage) entities across TUs.
>
> The changes inside the regex_constants and execution namespace seem to
> be unimplemented parts of P0607R0; the rest of the changes touch only
> implementation details.
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

OK, thanks.

My understanding was that [basic.def.odr] p14.5 means we don't get ODR
violations, but I think that only works for sensible uses of the
variables. Any inline function that takes the address of (or binds a
reference to) one of these variables will get an ODR violation. So the
patch is an improvement.


>
> libstdc++-v3/ChangeLog:
>
> * include/bits/atomic_wait.h (_detail::__platform_wait_alignment):
> Declare inline.  Remove redundant static specifier.
> (__detail::__atomic_spin_count_relax): Declare inline.
> (__detail::__atomic_spin_count): Likewise.
> * include/bits/regex_automaton.h (__detail::_S_invalid_state_id):
> Conditionally declare inline.  Declare constexpr.  Remove
> redundant const and static specifiers.
> * include/bits/regex_error.h (regex_constants::error_collate): 
> Conditionally
> declare inline.
> (regex_constants::error_ctype): Likewise.
> (regex_constants::error_escape): Likewise.
> (regex_constants::error_backref): Likewise.
> (regex_constants::error_brack): Likewise.
> (regex_constants::error_paren): Likewise.
> (regex_constants::error_brace): Likewise.
> (regex_constants::error_badbrace): Likewise.
> (regex_constants::error_range): Likewise.
> (regex_constants::error_space): Likewise.
> (regex_constants::error_badrepeat): Likewise.
> (regex_constants::error_complexity): Likewise.
> (regex_constants::error_stack): Likewise.
> * include/ext/concurrence.h (__gnu_cxx::__default_lock_policy):
> Likewise.  Remove redundant static specifier.
> * include/pstl/execution_defs.h (execution::seq): Conditionally 
> declare
> inline.
> (execution::par): Likewise.
> (execution::par_unseq): Likewise.
> (execution::unseq): Likewise.
> ---
>  libstdc++-v3/include/bits/atomic_wait.h |  8 +++
>  libstdc++-v3/include/bits/regex_automaton.h |  2 +-
>  libstdc++-v3/include/bits/regex_error.h | 26 ++---
>  libstdc++-v3/include/ext/concurrence.h  |  2 +-
>  libstdc++-v3/include/pstl/execution_defs.h  |  8 +++
>  5 files changed, 23 insertions(+), 23 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
> b/libstdc++-v3/include/bits/atomic_wait.h
> index 76ed7409937..bd1ed56d157 100644
> --- a/libstdc++-v3/include/bits/atomic_wait.h
> +++ b/libstdc++-v3/include/bits/atomic_wait.h
> @@ -58,14 +58,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  #ifdef _GLIBCXX_HAVE_LINUX_FUTEX
>  #define _GLIBCXX_HAVE_PLATFORM_WAIT 1
>  using __platform_wait_t = int;
> -static constexpr size_t __platform_wait_alignment = 4;
> +inline constexpr size_t __platform_wait_alignment = 4;
>  #else
>  // define _GLIBCX_HAVE_PLATFORM_WAIT and implement __platform_wait()
>  // and __platform_notify() if there is a more efficient primitive supported
>  // by the platform (e.g. __ulock_wait()/__ulock_wake()) which is better than
>  // a mutex/condvar based wait.
>  using __platform_wait_t = uint64_t;
> -static constexpr size_t __platform_wait_alignment
> +inline constexpr size_t __platform_wait_alignment
>= __alignof__(__platform_wait_t);
>  #endif
>} // namespace __detail
> @@ -142,8 +142,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  #endif
>  }
>
> -constexpr auto __atomic_spin_count_relax = 12;
> -constexpr auto __atomic_spin_count = 16;
> +inline constexpr auto __atomic_spin_count_relax = 12;
> +inline constexpr auto __atomic_spin_count = 16;
>
>  struct __default_spin_policy
>  {
> diff --git a/libstdc++-v3/include/bits/regex_automaton.h 
> b/libstdc++-v3/include/bits/regex_automaton.h
> index f95eb7dad6d..44bde42e212 100644
> --- a/libstdc++-v3/include/bits/regex_automaton.h
> +++ b/libstdc++-v3/include/bits/regex_automaton.h
> @@ -46,7 +46,7 @@ namespace __detail
> */
>
>typedef long _StateIdT;
> -  static const _StateIdT _S_invalid_state_id  = -1;
> +  _GLIBCXX17_INLINE constexpr _StateIdT _S_invalid_state_id  = -1;
>
>template
>  using _Matcher = std::function;
> diff --git a/libstdc++-v3/include/bits/regex_error.h 
> b/libstdc++-v3/include/bits/regex_error.h
> index 74a1428c2c7..ab207650d44 100644
> --- a/libstdc++-v3/include/bits/regex_error.h
> +++ b/libstdc++-v3/include/bits/regex_error.h
> @@ -66,60 +66,60 @@ namespace regex_constants
>  };
>
>/** The expression contained an invalid collating 

Re: [PATCH] c++: constexpr error with defaulted virtual dtor [PR93413]

2022-11-03 Thread Jason Merrill via Gcc-patches

On 11/3/22 08:33, Patrick Palka wrote:

We're rejecting the below testcase with

   error: 'virtual constexpr Base::~Base()' used before its definition
   error: 'virtual constexpr Derived::~Derived()' used before its definition

due to an early exit added to mark_used by r181272 to defer synthesis of
virtual destructors until EOF where we can set their linkage.  This makes
them effectively unusable for constexpr evaluation since that needs to
be done immediately and can't also be deferred.

Fortunately, this early exit seems to no longer be necessary ever since
r208030 enabled us to tentatively set linkage of all defaulted virtual
destructors, including templated ones.  So this patch just gets rid of
this early exit.

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


OK.


PR c++/93413

gcc/cp/ChangeLog:

* decl2.cc (mark_used): Don't defer synthesis of virtual
functions.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/constexpr-virtual21.C: New test.
---
  gcc/cp/decl2.cc  |  8 
  gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C | 10 ++
  2 files changed, 10 insertions(+), 8 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index e6779268ad4..eeb59eae64f 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -5788,14 +5788,6 @@ mark_used (tree decl, tsubst_flags_t complain /* = 
tf_warning_or_error */)
&& !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
&& ! DECL_INITIAL (decl))
  {
-  /* Defer virtual destructors so that thunks get the right
-linkage.  */
-  if (DECL_VIRTUAL_P (decl) && !at_eof)
-   {
- note_vague_linkage_fn (decl);
- return true;
-   }
-
/* Remember the current location for a function we will end up
 synthesizing.  Then we can inform the user where it was
 required in the case of error.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C
new file mode 100644
index 000..8b70c5f538b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C
@@ -0,0 +1,10 @@
+// PR c++/93413
+// { dg-do compile { target c++20 } }
+
+struct Base {
+  virtual ~Base() = default;
+};
+constexpr Base b;
+
+struct Derived : Base { };
+constexpr Derived d;




[PATCH] c++: requires-expr substitution and access checking [PR107179]

2022-11-03 Thread Patrick Palka via Gcc-patches
Like during satisfaction, we need to check access immediately during
substitution of a requires-expr since the outcome of an access check can
determine the value of the requires-expr.  And otherwise, in contexts
where access checking is deferred (such as during substitution into a
base-clause), a failed access check may leak out from the requires-expr
into a non-SFINAE context and cause a hard error (as in the testcase
below).

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

PR c++/107179

gcc/cp/ChangeLog:

* constraint.cc (tsubst_requires_expr): Make sure we're not
deferring access checks.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-requires31.C: New test.
---
 gcc/cp/constraint.cc |  3 +++
 gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C | 13 +
 2 files changed, 16 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e6a3bcf059..f6ef078171a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2252,6 +2252,9 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
 {
   local_specialization_stack stack (lss_copy);
 
+  /* We need to check access during the substitution.  */
+  deferring_access_check_sentinel acs (dk_no_deferred);
+
   /* A requires-expression is an unevaluated context.  */
   cp_unevaluated u;
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C
new file mode 100644
index 000..9b7e2a34889
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C
@@ -0,0 +1,13 @@
+// PR c++/107179
+// { dg-do compile { target c++20 } }
+
+template struct bool_constant { static constexpr bool value = B; };
+
+template
+  struct is_implicitly_default_constructible
+  : bool_constant
+  { };
+
+struct X { private: X(); };
+
+static_assert( !is_implicitly_default_constructible::value );
-- 
2.38.1.381.gc03801e19c



Re: [PATCH] c++: Allow module name to be a single letter on Windows

2022-11-03 Thread Torbjorn SVENSSON via Gcc-patches




On 2022-11-03 15:17, Nathan Sidwell wrote:

On 10/28/22 05:15, Torbjörn SVENSSON wrote:

On Windows, the ':' character is special and when the module name is
a single character, like 'A', then the flatname would be (for
example) 'A:Foo'. On Windows, 'A:Foo' is treated as an absolute
path by the module loader and is likely not found.

Without this patch, the test case pr98944_c.C fails with:

In module imported at /src/gcc/testsuite/g++.dg/modules/pr98944_b.C:7:1,
of module A:Foo, imported at 
/src/gcc/testsuite/g++.dg/modules/pr98944_c.C:7:

A:Internals: error: header module expected, module 'A:Internals' found
A:Internals: error: failed to read compiled module: Bad file data
A:Internals: note: compiled module file is 'gcm.cache/A-Internals.gcm'
In module imported at /src/gcc/testsuite/g++.dg/modules/pr98944_c.C:7:8:
A:Foo: error: failed to read compiled module: Bad import dependency
A:Foo: note: compiled module file is 'gcm.cache/A-Foo.gcm'
A:Foo: fatal error: returning to the gate for a mechanical issue
compilation terminated.

include/ChangeLog:

* filenames.h: Added IS_REAL_ABSOLUTE_PATH macro to check if
path is absolute and not semi-absolute on Windows.


Hm, this is unfortunate.  The current IS_ABSOLUTE_PATH, is really 'not 
relative to cwd', and even then that's untrue if the drive letter there 
is the drive letter of cwd, right?


It's awkward to have a new macro for just this purpose and the new name 
isn't very indicative of the difference to the current IS_ABSOLUTE_PATH.


Would it be better to not deal with drive letters here?  How prevalent 
are they these days in windows?  Would something like


    if (IS_DIR_SEPARATOR (ptr[ptr[0] == '.'])

suffice?


I don't think you can ignore the drive letter part... see below.


#include 
#include "include/filenames.h"
#define TF(x) ((x) ? "true" : "false")
int main(int argc, char *argv[]) {
  const char *test[] = {
  /* absolute */  "c:\\foo", "c:/foo", "/foo", "\\foo",
  /* semi-absolute */ "c:foo",
  /* relative */  "foo", "./foo", ".\\foo",
  };
  for (int i = 0; i < sizeof(test) / sizeof(test[0]); i++) {
const char *ptr = test[i];
printf("\nptr: %s\n", ptr);
printf("  IS_DOS_ABSOLUTE_PATH: %s\n",
   TF(IS_DOS_ABSOLUTE_PATH(ptr)));
printf("  IS_DOS_REAL_ABSOLUTE_PATH: %s\n",
   TF(IS_DOS_REAL_ABSOLUTE_PATH(ptr)));
printf("  IS_DIR_SEPARATOR: %s\n",
   TF(IS_DIR_SEPARATOR(ptr[ptr[0] == '.'])));
  }
  return 0;
}


The output is:

ptr: c:\foo
  IS_DOS_ABSOLUTE_PATH: true
  IS_DOS_REAL_ABSOLUTE_PATH: true
  IS_DIR_SEPARATOR: false

ptr: c:/foo
  IS_DOS_ABSOLUTE_PATH: true
  IS_DOS_REAL_ABSOLUTE_PATH: true
  IS_DIR_SEPARATOR: false

ptr: /foo
  IS_DOS_ABSOLUTE_PATH: true
  IS_DOS_REAL_ABSOLUTE_PATH: true
  IS_DIR_SEPARATOR: true

ptr: \foo
  IS_DOS_ABSOLUTE_PATH: true
  IS_DOS_REAL_ABSOLUTE_PATH: true
  IS_DIR_SEPARATOR: false

ptr: c:foo
  IS_DOS_ABSOLUTE_PATH: true
  IS_DOS_REAL_ABSOLUTE_PATH: false
  IS_DIR_SEPARATOR: false

ptr: foo
  IS_DOS_ABSOLUTE_PATH: false
  IS_DOS_REAL_ABSOLUTE_PATH: false
  IS_DIR_SEPARATOR: false

ptr: ./foo
  IS_DOS_ABSOLUTE_PATH: false
  IS_DOS_REAL_ABSOLUTE_PATH: false
  IS_DIR_SEPARATOR: true

ptr: .\foo
  IS_DOS_ABSOLUTE_PATH: false
  IS_DOS_REAL_ABSOLUTE_PATH: false
  IS_DIR_SEPARATOR: false




or, failing that perhaps put some explicit WINDOWS-specific #ifdef'd 
code there?  It's a real corner case.


Would you rather have something like this in module.cc?

if (ptr[0] == '.')
  {
if IS_DIR_SEPARATOR (ptr[1]))
  return get_module (build_string (strlen (ptr), ptr));
  }
else
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
if (HAS_DRIVE_SPEC (ptr) && IS_DIR_SEPARATOR (ptr[2]))
#else
if (IS_ABSOLUTE_PATH (ptr))
#endif
  return get_module (build_string (strlen (ptr), ptr));
  }


Let me know what you prefer.

Kind regards,
Torbjörn



nathan



gcc/cp/ChangeLog:

* module.cc: Use IS_REAL_ABSOLUTE_PATH macro.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
  gcc/cp/module.cc    | 2 +-
  include/filenames.h | 4 
  2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 9957df510e6..84680e183b7 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13958,7 +13958,7 @@ get_module (tree name, module_state *parent, 
bool partition)

  static module_state *
  get_module (const char *ptr)
  {
-  if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : IS_ABSOLUTE_PATH 
(ptr))
+  if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : 
IS_REAL_ABSOLUTE_PATH (ptr))

  /* A header name.  */
  return get_module (build_string (strlen (ptr), ptr));
diff --git a/include/filenames.h b/include/filenames.h
index 6c72c422edd..d04fccfed64 100644
--- a/include/filenames.h
+++ b/include/filenames.h
@@ -43,6 +43,7 @@ extern "C" {
  #  define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f)
  #  define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c)
  #  define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f)

[committed] analyzer: fix ICE when pipe's arg isn't a pointer [PR107486]

2022-11-03 Thread David Malcolm via Gcc-patches
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-3626-g5acc10a9ea6641.

gcc/analyzer/ChangeLog:
PR analyzer/107486
* analyzer.cc (is_pipe_call_p): New.
* analyzer.h (is_pipe_call_p): New decl.
* region-model.cc (region_model::on_call_pre): Use it.
(region_model::on_call_post): Likewise.

gcc/testsuite/ChangeLog:
PR analyzer/107486
* gcc.dg/analyzer/pipe-pr107486.c: New test.
* gcc.dg/analyzer/pipe-void-return.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/analyzer.cc | 16 
 gcc/analyzer/analyzer.h  |  2 ++
 gcc/analyzer/region-model.cc |  8 
 gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c|  5 +
 gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c | 11 +++
 5 files changed, 38 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c

diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 8a2a7734f24..6c7c969538c 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -379,6 +379,22 @@ is_longjmp_call_p (const gcall *call)
   return false;
 }
 
+/* Return true if this is a "pipe" call.  */
+
+bool
+is_pipe_call_p (const_tree fndecl, const char *funcname,
+   const gcall *call, unsigned int num_args)
+{
+  if (!is_named_call_p (fndecl, funcname, call, num_args))
+return false;
+
+  /* We require a pointer for the initial argument.  */
+  if (!POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0
+return false;
+
+  return true;
+}
+
 /* For a CALL that matched is_special_named_call_p or is_named_call_p for
some name, return a name for the called function suitable for use in
diagnostics (stripping the leading underscores).  */
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index a2d79e4a59f..c41cfb01656 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -324,6 +324,8 @@ extern bool is_std_named_call_p (const_tree fndecl, const 
char *funcname,
 const gcall *call, unsigned int num_args);
 extern bool is_setjmp_call_p (const gcall *call);
 extern bool is_longjmp_call_p (const gcall *call);
+extern bool is_pipe_call_p (const_tree fndecl, const char *funcname,
+   const gcall *call, unsigned int num_args);
 
 extern const char *get_user_facing_name (const gcall *call);
 
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 7c44fc9e253..4713f0d2519 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -2315,8 +2315,8 @@ region_model::on_call_pre (const gcall *call, 
region_model_context *ctxt,
  impl_call_memset (cd);
  return false;
}
-  else if (is_named_call_p (callee_fndecl, "pipe", call, 1)
-  || is_named_call_p (callee_fndecl, "pipe2", call, 2))
+  else if (is_pipe_call_p (callee_fndecl, "pipe", call, 1)
+  || is_pipe_call_p (callee_fndecl, "pipe2", call, 2))
{
  /* Handle in "on_call_post"; bail now so that fd array
 is left untouched so that we can detect use-of-uninit
@@ -2403,8 +2403,8 @@ region_model::on_call_post (const gcall *call,
  impl_call_operator_delete (cd);
  return;
}
-  else if (is_named_call_p (callee_fndecl, "pipe", call, 1)
-  || is_named_call_p (callee_fndecl, "pipe2", call, 2))
+  else if (is_pipe_call_p (callee_fndecl, "pipe", call, 1)
+  || is_pipe_call_p (callee_fndecl, "pipe2", call, 2))
{
  impl_call_pipe (cd);
  return;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c 
b/gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c
new file mode 100644
index 000..e9fc7fb4943
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c
@@ -0,0 +1,5 @@
+void pipe(int);
+
+void f1(void) {
+  pipe(1);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c 
b/gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c
new file mode 100644
index 000..0de676305f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c
@@ -0,0 +1,11 @@
+extern void pipe(int pipefd[2]);
+extern int close(int fd);
+
+void
+test_unchecked (void)
+{
+  int fds[2];
+  pipe (fds); /* { dg-message "when 'pipe' fails" } */
+  close (fds[0]); /* { dg-warning "use of uninitialized value 'fds\\\[0\\\]'" 
} */
+  close (fds[1]); /* { dg-warning "use of uninitialized value 'fds\\\[1\\\]'" 
} */
+}
-- 
2.26.3



Re: [PATCH] c++: Allow module name to be a single letter on Windows

2022-11-03 Thread Nathan Sidwell via Gcc-patches

On 10/28/22 05:15, Torbjörn SVENSSON wrote:

On Windows, the ':' character is special and when the module name is
a single character, like 'A', then the flatname would be (for
example) 'A:Foo'. On Windows, 'A:Foo' is treated as an absolute
path by the module loader and is likely not found.

Without this patch, the test case pr98944_c.C fails with:

In module imported at /src/gcc/testsuite/g++.dg/modules/pr98944_b.C:7:1,
of module A:Foo, imported at /src/gcc/testsuite/g++.dg/modules/pr98944_c.C:7:
A:Internals: error: header module expected, module 'A:Internals' found
A:Internals: error: failed to read compiled module: Bad file data
A:Internals: note: compiled module file is 'gcm.cache/A-Internals.gcm'
In module imported at /src/gcc/testsuite/g++.dg/modules/pr98944_c.C:7:8:
A:Foo: error: failed to read compiled module: Bad import dependency
A:Foo: note: compiled module file is 'gcm.cache/A-Foo.gcm'
A:Foo: fatal error: returning to the gate for a mechanical issue
compilation terminated.

include/ChangeLog:

* filenames.h: Added IS_REAL_ABSOLUTE_PATH macro to check if
path is absolute and not semi-absolute on Windows.


Hm, this is unfortunate.  The current IS_ABSOLUTE_PATH, is really 'not relative 
to cwd', and even then that's untrue if the drive letter there is the drive 
letter of cwd, right?


It's awkward to have a new macro for just this purpose and the new name isn't 
very indicative of the difference to the current IS_ABSOLUTE_PATH.


Would it be better to not deal with drive letters here?  How prevalent are they 
these days in windows?  Would something like


   if (IS_DIR_SEPARATOR (ptr[ptr[0] == '.'])

suffice?

or, failing that perhaps put some explicit WINDOWS-specific #ifdef'd code there? 
 It's a real corner case.


nathan



gcc/cp/ChangeLog:

* module.cc: Use IS_REAL_ABSOLUTE_PATH macro.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
  gcc/cp/module.cc| 2 +-
  include/filenames.h | 4 
  2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 9957df510e6..84680e183b7 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13958,7 +13958,7 @@ get_module (tree name, module_state *parent, bool 
partition)
  static module_state *
  get_module (const char *ptr)
  {
-  if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : IS_ABSOLUTE_PATH (ptr))
+  if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : IS_REAL_ABSOLUTE_PATH (ptr))
  /* A header name.  */
  return get_module (build_string (strlen (ptr), ptr));
  
diff --git a/include/filenames.h b/include/filenames.h

index 6c72c422edd..d04fccfed64 100644
--- a/include/filenames.h
+++ b/include/filenames.h
@@ -43,6 +43,7 @@ extern "C" {
  #  define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f)
  #  define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c)
  #  define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f)
+#  define IS_REAL_ABSOLUTE_PATH(f) IS_DOS_REAL_ABSOLUTE_PATH (f)
  #else /* not DOSish */
  #  if defined(__APPLE__)
  #ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
@@ -52,6 +53,7 @@ extern "C" {
  #  define HAS_DRIVE_SPEC(f) (0)
  #  define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c)
  #  define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f)
+#  define IS_REAL_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH (f)
  #endif
  
  #define IS_DIR_SEPARATOR_1(dos_based, c)\

@@ -67,6 +69,8 @@ extern "C" {
  
  #define IS_DOS_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (1, c)

  #define IS_DOS_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (1, f)
+#define IS_DOS_REAL_ABSOLUTE_PATH(f) \
+  ((f)[0] && (f)[1] == ':' && ((f)[2] == '/' || (f)[2] == '\\'))
  #define HAS_DOS_DRIVE_SPEC(f) HAS_DRIVE_SPEC_1 (1, f)
  
  #define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c)


--
Nathan Sidwell



Re: [PATCH v2] c++: Use in-process client when networking is disabled

2022-11-03 Thread Nathan Sidwell via Gcc-patches

On 11/3/22 09:48, Torbjorn SVENSSON wrote:

Hello Nathan,

On 2022-11-03 14:13, Nathan Sidwell wrote:

On 11/3/22 05:37, Torbjörn SVENSSON wrote:

v1 -> v2:
Updated expression in bad-mapper-3.C

Ok for trunk?

---

Without the patch, the output for bad-mapper-3.C would be:

/src/gcc/gcc/testsuite/g++.dg/modules/bad-mapper-3.C:2:1: error: unknown 
Compiled Module Interface: no such module


As this line is unexpected, the test case would fail.
The same problem can also be seen for g++.dg/modules/bad-mapper-2.C.

gcc/cp/ChangeLog:

* mapper-client.cc: Use in-process client when networking is
disabled.

gcc/testsuite/ChangeLog:

* g++.dg/modules/bad-mapper-3.C: Update dg-error pattern.

Tested on Windows with arm-none-eabi for Cortex-M3 in gcc-11 tree.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
  gcc/cp/mapper-client.cc | 4 
  gcc/testsuite/g++.dg/modules/bad-mapper-3.C | 2 +-
  2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index fe9544b5ba4..4dcb3a03660 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -227,6 +227,8 @@ module_client::open_module_client (location_t loc, const 
char *o,

  int fd = -1;
  #if CODY_NETWORKING
  fd = Cody::OpenLocal (, name.c_str () + 1);
+#else
+    errmsg = "CODY_NETWORKING disabled";


CODY_NETWORKING is implementor speak. I think just "disabled" is sufficient 
here?


Ok for trunk if I change to just "disabled" here and in the other places below?


yes, thanks


Kind regards,
Torbjörn




  #endif
  if (fd >= 0)
    c = new module_client (fd, fd);
@@ -254,6 +256,8 @@ module_client::open_module_client (location_t loc, const 
char *o,

  int fd = -1;
  #if CODY_NETWORKING
  fd = Cody::OpenInet6 (, name.c_str (), port);
+#else
+    errmsg = "CODY_NETWORKING disabled";
  #endif
  name[colon] = ':';
diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C 
b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C

index 9dab332ccb2..c91bb4e260c 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
@@ -1,6 +1,6 @@
  //  { dg-additional-options "-fmodules-ts 
-fmodule-mapper=localhost:172477262" }

  import unique3.bob;
-// { dg-error {failed connecting mapper 'localhost:172477262'} "" { target 
*-*-* } 0 }
+// { dg-error {failed (connecting|CODY_NETWORKING disabled) mapper 
'localhost:172477262'} "" { target *-*-* } 0 }

  // { dg-prune-output "fatal error:" }
  // { dg-prune-output "failed to read" }
  // { dg-prune-output "compilation terminated" }




--
Nathan Sidwell



Re: [PATCH v2] c++: Use in-process client when networking is disabled

2022-11-03 Thread Torbjorn SVENSSON via Gcc-patches

Hello Nathan,

On 2022-11-03 14:13, Nathan Sidwell wrote:

On 11/3/22 05:37, Torbjörn SVENSSON wrote:

v1 -> v2:
Updated expression in bad-mapper-3.C

Ok for trunk?

---

Without the patch, the output for bad-mapper-3.C would be:

/src/gcc/gcc/testsuite/g++.dg/modules/bad-mapper-3.C:2:1: error: 
unknown Compiled Module Interface: no such module


As this line is unexpected, the test case would fail.
The same problem can also be seen for g++.dg/modules/bad-mapper-2.C.

gcc/cp/ChangeLog:

* mapper-client.cc: Use in-process client when networking is
disabled.

gcc/testsuite/ChangeLog:

* g++.dg/modules/bad-mapper-3.C: Update dg-error pattern.

Tested on Windows with arm-none-eabi for Cortex-M3 in gcc-11 tree.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
  gcc/cp/mapper-client.cc | 4 
  gcc/testsuite/g++.dg/modules/bad-mapper-3.C | 2 +-
  2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index fe9544b5ba4..4dcb3a03660 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -227,6 +227,8 @@ module_client::open_module_client (location_t loc, 
const char *o,

  int fd = -1;
  #if CODY_NETWORKING
  fd = Cody::OpenLocal (, name.c_str () + 1);
+#else
+    errmsg = "CODY_NETWORKING disabled";


CODY_NETWORKING is implementor speak. I think just "disabled" is 
sufficient here?


Ok for trunk if I change to just "disabled" here and in the other places 
below?


Kind regards,
Torbjörn




  #endif
  if (fd >= 0)
    c = new module_client (fd, fd);
@@ -254,6 +256,8 @@ module_client::open_module_client (location_t loc, 
const char *o,

  int fd = -1;
  #if CODY_NETWORKING
  fd = Cody::OpenInet6 (, name.c_str (), port);
+#else
+    errmsg = "CODY_NETWORKING disabled";
  #endif
  name[colon] = ':';
diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C 
b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C

index 9dab332ccb2..c91bb4e260c 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
@@ -1,6 +1,6 @@
  //  { dg-additional-options "-fmodules-ts 
-fmodule-mapper=localhost:172477262" }

  import unique3.bob;
-// { dg-error {failed connecting mapper 'localhost:172477262'} "" { 
target *-*-* } 0 }
+// { dg-error {failed (connecting|CODY_NETWORKING disabled) mapper 
'localhost:172477262'} "" { target *-*-* } 0 }

  // { dg-prune-output "fatal error:" }
  // { dg-prune-output "failed to read" }
  // { dg-prune-output "compilation terminated" }




[PATCH] ifcvt: Support bitfield lowering of multiple-exit loops

2022-11-03 Thread Andre Vieira (lists) via Gcc-patches

Hi,

With Tamar's patch 
(https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604880.html) 
enabling the vectorization of early-breaks, I'd like to allow bitfield 
lowering in such loops, which requires the relaxation of allowing 
multiple exits when doing so.  In order to avoid a similar issue to 
PR107275, I hoisted the code that rejects loops with certain types of 
gimple_stmts from 'if_convertible_loop_p_1' to 
'get_loop_body_in_if_conv_order', to avoid trying to lower bitfields in 
loops we are not going to vectorize anyway.  This also ensures 
'ifcvt_local_dce' doesn't accidentally remove statements it shouldn't as 
it will never come across them.  I made sure to add a comment to make 
clear that there is a direct connection between the two and if we were 
to enable vectorization of any other gimple statement we should make 
sure both handle it.


Bootstrapped and regression tested on aarch64-none-linux-gnu and 
x86_64-pc-linux-gnu


gcc/ChangeLog:

    * tree-if-conv.cc (if_convertible_loop_p_1): Move statement 
check loop from here ...

    (get_loop_body_if_conv_order): ... to here.
    (if_convertible_loop_p): Remove single_exit check.
    (tree_if_conversion): Move single_exit check to if-conversion part.

gcc/testsuite/ChangeLog:

    * gcc.dg/vect/vect-bitfield-read-1-not.c: New test.
    * gcc.dg/vect/vect-bitfield-read-2-not.c: New test.
    * gcc.dg/vect/vect-bitfield-read-8.c: New test.
    * gcc.dg/vect/vect-bitfield-read-9.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-1-not.c 
b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-1-not.c
new file mode 100644
index 
..0d91067ebb27b1db2b2352975c43bce8b4171e3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-1-not.c
@@ -0,0 +1,60 @@
+/* { dg-require-effective-target vect_shift } */
+/* { dg-require-effective-target vect_long_long } */
+/* { dg-additional-options { "-fdump-tree-ifcvt-all" } } */
+
+#include 
+#include "tree-vect.h"
+
+extern void abort(void);
+
+struct s {
+char a : 4;
+};
+
+#define N 32
+#define ELT0 {0}
+#define ELT1 {1}
+#define ELT2 {2}
+#define ELT3 {3}
+#define RES 56
+struct s A[N]
+  = { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3,
+  ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3,
+  ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3,
+  ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3};
+
+int __attribute__ ((noipa))
+f(struct s *ptr, unsigned n) {
+int res = 0;
+for (int i = 0; i < n; ++i)
+  {
+   switch (ptr[i].a)
+ {
+ case 0:
+   res += ptr[i].a + 1;
+   break;
+ case 1:
+ case 2:
+ case 3:
+   res += ptr[i].a;
+   break;
+ default:
+   return 0;
+ }
+  }
+return res;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  if (f([0], N) != RES)
+abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Bitfield OK to lower." "ifcvt" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-2-not.c 
b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-2-not.c
new file mode 100644
index 
..4ac7b3fc0dfd1c9d0b5e94a2ba6a745545577ec1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-2-not.c
@@ -0,0 +1,49 @@
+/* { dg-require-effective-target vect_shift } */
+/* { dg-require-effective-target vect_long_long } */
+/* { dg-additional-options { "-fdump-tree-ifcvt-all" } } */
+
+#include 
+#include "tree-vect.h"
+
+extern void abort(void);
+
+struct s {
+char a : 4;
+};
+
+#define N 32
+#define ELT0 {0}
+#define ELT1 {1}
+#define ELT2 {2}
+#define ELT3 {3}
+#define RES 48
+struct s A[N]
+  = { ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3,
+  ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3,
+  ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3,
+  ELT0, ELT1, ELT2, ELT3, ELT0, ELT1, ELT2, ELT3};
+
+int __attribute__ ((noipa))
+f(struct s *ptr, unsigned n) {
+int res = 0;
+for (int i = 0; i < n; ++i)
+  {
+   asm volatile ("" ::: "memory");
+   res += ptr[i].a;
+  }
+return res;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  if (f([0], N) != RES)
+abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Bitfield OK to lower." "ifcvt" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-8.c 
b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-8.c
new file mode 100644
index 
..52cfd33d937ae90f3fe9556716c90e098b768ac8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bitfield-read-8.c
@@ -0,0 +1,49 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_shift } */
+/* { dg-additional-options { "-fdump-tree-ifcvt-all" } } */
+
+#include 
+#include "tree-vect.h"
+
+extern void abort(void);
+
+struct s { int i : 31; };
+
+#define ELT0 {0}
+#define ELT1 {1}
+#define ELT2 {2}
+#define 

Re: [Patch] OpenMP/Fortran: 'target update' with DT components (was: [Patch] OpenMP/Fortran: 'target update' with strides + DT components)

2022-11-03 Thread Jakub Jelinek via Gcc-patches
On Thu, Nov 03, 2022 at 02:35:03PM +0100, Tobias Burnus wrote:
> On 03.11.22 13:44, Jakub Jelinek wrote:
> > [...]
> > Otherwise LGTM, assuming it actually works correctly.
> > 
> > I don't remember support for non-contiguous copying to/from devices
> > being actually added, [...] And I think it is not ok to copy bytes
> > that aren't requested to be copied.
> 
> I have now removed that stride support and only kept the bug fix and the
> DT component parts of the patch.
> 
> The only code change is to remove the stride check disabling in
> openmp.cc and in one testcase, to remove the stride part.
> 
> I will commit it as attached, unless there are further comments (or the
> just started reg testing shows that something does not work).
> 
> Tobias
> 
> PS: For strides, I now filed: PR middle-end/107517 "[OpenMP][5.0]
> 'target update' with strides — for C/C++ and Fortran"
> https://gcc.gnu.org/PR107517
> -
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
> München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
> Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
> München, HRB 106955

> OpenMP/Fortran: 'target update' with DT components
> 
> OpenMP 5.0 permits to use arrays with derived type components for the list
> items to the 'from'/'to' clauses of the 'target update' directive.
> 
> gcc/fortran/ChangeLog:
> 
>   * openmp.cc (gfc_match_omp_clauses): Permit derived types for
>   the 'to' and 'from' clauses of 'target update'.
>   * trans-openmp.cc (gfc_trans_omp_clauses): Fixes for
>   derived-type changes; fix size for scalars.
> 
> libgomp/ChangeLog:
> 
>   * testsuite/libgomp.fortran/target-11.f90: New test.
>   * testsuite/libgomp.fortran/target-13.f90: New test.

LGTM, thanks.

Jakub



Re: [PATCH v3] c++: parser - Support for target address spaces in C++

2022-11-03 Thread Georg-Johann Lay

[PATCH v3] c++: parser - Support for target address spaces in C++


First of all, it is great news that GCC is going to implement named 
address spaces for C++.


I have some questions:

1. How is name-mangling going to work?
==

Clang supports address spaces in C++, and for address-space 1 it does 
generate code like the following:


#define __flash __attribute__((__address_space__(1)))

char get_p (const __flash char *p)
{
return *p;
}


_Z5get_pPU3AS1Kc:
   ...

I.e. address-space 1 is mangled as "AS1".

(Notice that Clang's attribute actually works like a qualifier here, one 
could not get this to work with GCC attributes.)



2. Will it work with compound literals?
===

Currently, the following C code works for target avr:

const __flash char *pHallo = (const __flash char[]) { "Hallo" };

This is a pointer in RAM (AS0) that holds the address of a string in 
flash (AS1) and is initialized with that address. Unfortunately, this 
does not work locally:


const __flash char* get_hallo (void)
{
[static] const __flash char *p2 = (const __flash char[]) { "Hallo2" };
return p2;
}

foo.c: In function 'get_hallo':
foo.c: error: compound literal qualified by address-space qualifier

Is there any way to make this work now? Would be great!


3. Will TARGET_ADDR_SPACE_DIAGNOSE_USAGE still work?


Currently there is target hook TARGET_ADDR_SPACE_DIAGNOSE_USAGE.
I did not see it in your patches, so maybe I just missed it? See
https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gccint/Named-Address-Spaces.html#index-TARGET_005fADDR_005fSPACE_005fDIAGNOSE_005fUSAGE


4. Will it be possible to put C++ virtual tables in ASs, and how?
=

One big complaint about avr-g++ is that there is no way to put vtables 
in flash (address-space 1) and to access them accordingly.  How can this 
be achieved with C++ address spaces?


Background: The AVR architecture has non-linear address space, and you 
cannot tell from the numeric value of an address whether it's in RAM or 
flash. You will have to use different instructions depending on the 
location.


This means that .rodata must be located in RAM, because otherwise one 
would not know whether const char* pointed to RAM or flash, but to 
de-reference you's need different instructions.


One way out is named address spaces, so we could finally fix

https://gcc.gnu.org/PR43745


Regards,

Johann



[Patch] OpenMP/Fortran: 'target update' with DT components (was: [Patch] OpenMP/Fortran: 'target update' with strides + DT components)

2022-11-03 Thread Tobias Burnus

On 03.11.22 13:44, Jakub Jelinek wrote:

[...]
Otherwise LGTM, assuming it actually works correctly.

I don't remember support for non-contiguous copying to/from devices
being actually added, [...] And I think it is not ok to copy bytes
that aren't requested to be copied.


I have now removed that stride support and only kept the bug fix and the
DT component parts of the patch.

The only code change is to remove the stride check disabling in
openmp.cc and in one testcase, to remove the stride part.

I will commit it as attached, unless there are further comments (or the
just started reg testing shows that something does not work).

Tobias

PS: For strides, I now filed: PR middle-end/107517 "[OpenMP][5.0]
'target update' with strides — for C/C++ and Fortran"
https://gcc.gnu.org/PR107517
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
OpenMP/Fortran: 'target update' with DT components

OpenMP 5.0 permits to use arrays with derived type components for the list
items to the 'from'/'to' clauses of the 'target update' directive.

gcc/fortran/ChangeLog:

	* openmp.cc (gfc_match_omp_clauses): Permit derived types for
	the 'to' and 'from' clauses of 'target update'.
	* trans-openmp.cc (gfc_trans_omp_clauses): Fixes for
	derived-type changes; fix size for scalars.

libgomp/ChangeLog:

	* testsuite/libgomp.fortran/target-11.f90: New test.
	* testsuite/libgomp.fortran/target-13.f90: New test.

 gcc/fortran/openmp.cc   |  10 +-
 gcc/fortran/trans-openmp.cc |   9 +-
 libgomp/testsuite/libgomp.fortran/target-11.f90 |  75 +++
 libgomp/testsuite/libgomp.fortran/target-13.f90 | 159 
 4 files changed, 246 insertions(+), 7 deletions(-)

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 653c43f79ff..e0e3b52ad57 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -2499,9 +2499,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	  true) == MATCH_YES)
 	continue;
 	  if ((mask & OMP_CLAUSE_FROM)
-	  && gfc_match_omp_variable_list ("from (",
+	  && (gfc_match_omp_variable_list ("from (",
 	  >lists[OMP_LIST_FROM], false,
-	  NULL, , true) == MATCH_YES)
+	  NULL, , true, true)
+		  == MATCH_YES))
 	continue;
 	  break;
 	case 'g':
@@ -3436,9 +3437,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		continue;
 	}
 	  else if ((mask & OMP_CLAUSE_TO)
-	  && gfc_match_omp_variable_list ("to (",
+	  && (gfc_match_omp_variable_list ("to (",
 	  >lists[OMP_LIST_TO], false,
-	  NULL, , true) == MATCH_YES)
+	  NULL, , true, true)
+		  == MATCH_YES))
 	continue;
 	  break;
 	case 'u':
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 9bd4e6c7e1b..4bfdf85cd9b 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -3626,7 +3626,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		  gcc_unreachable ();
 		}
 	  tree node = build_omp_clause (input_location, clause_code);
-	  if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
+	  if (n->expr == NULL
+		  || (n->expr->ref->type == REF_ARRAY
+		  && n->expr->ref->u.ar.type == AR_FULL
+		  && n->expr->ref->next == NULL))
 		{
 		  tree decl = gfc_trans_omp_variable (n->sym, false);
 		  if (gfc_omp_privatize_by_reference (decl))
@@ -3666,13 +3669,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		{
 		  tree ptr;
 		  gfc_init_se (, NULL);
-		  if (n->expr->ref->u.ar.type == AR_ELEMENT)
+		  if (n->expr->rank == 0)
 		{
 		  gfc_conv_expr_reference (, n->expr);
 		  ptr = se.expr;
 		  gfc_add_block_to_block (block, );
 		  OMP_CLAUSE_SIZE (node)
-			= TYPE_SIZE_UNIT (TREE_TYPE (ptr));
+			= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ptr)));
 		}
 		  else
 		{
diff --git a/libgomp/testsuite/libgomp.fortran/target-11.f90 b/libgomp/testsuite/libgomp.fortran/target-11.f90
new file mode 100644
index 000..b0faa2e620d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-11.f90
@@ -0,0 +1,75 @@
+! Based on libgomp.c/target-23.c
+
+! { dg-additional-options "-fdump-tree-original" }
+! { dg-final { scan-tree-dump "omp target update to\\(xxs\\\[3\\\] \\\[len: 2\\\]\\)" "original" } }
+! { dg-final { scan-tree-dump "omp target update to\\(s\\.s \\\[len: 4\\\]\\)" "original" } }
+! { dg-final { scan-tree-dump "omp target update from\\(s\\.s \\\[len: 4\\\]\\)" "original" } }
+
+module m
+  implicit none
+  type S_type
+integer s
+integer, pointer :: u(:) => null()
+integer :: v(0:4)
+  end type S_type
+  integer, volatile :: z
+end module m
+
+program main
+  use m
+  implicit none
+  

Re: [PATCH] gcc: honour -ffile-prefix-map in ASM_MAP [PR93371]

2022-11-03 Thread Rasmus Villemoes
On 02/11/2022 16.45, Jeff Law wrote:
> 
> On 11/2/22 06:35, Rasmus Villemoes wrote:

>> However, when I try to push the new master branch I get
>>
>> $ git push origin master
>> fatal: remote error: service not enabled: /git/gcc.git
>>
>> I do gcc patches sufficiently rare that I may have forgotten the right
>> procedure, but this is what I think I've done previously (along with
>> running a "git gcc-verify HEAD" to ensure there's a proper changelog
>> fragment to extract, with gcc-verify being a suitable alias).
>>
>> Have I simply lost by commit bit?
> 
> No idea what that error means.  If I had to guess, it'd be that you've
> got an anonymous checkout tree which is obviously unsuitable for pushing
> or something of that nature.
> 
> It's probably just faster/easier for me to push it for you.  I'll take
> care of it momentarily.

Thanks.

I think I found out what was wrong (though I know it has worked for me
previously): My remote url was git://gcc.gnu.org/git/gcc.git , and I
used to rely on my .ssh/config specifying "villemoes" as username when
accessing gcc.gnu.org. For some reason that no longer worked, but
updating the remote url to git+ssh://villem...@gcc.gnu.org/git/gcc.git
seemed to do the trick.

What do you think about applying this to older branches? IMO it's a
defect from when the umbrella -ffile-prefix-map was introduced, and the
potential for regressions should be very low, but I can also see how it
might not really qualify as a bug fix.

Rasmus



[PATCH] i386: Fix uninitialized register after peephole2 conversion [PR107404]

2022-11-03 Thread Uros Bizjak via Gcc-patches
The eliminate reg-reg move by inverting the condition of
a cmove #2 peephole2 converts the following sequence:

  473: bx:DI=[r14:DI*0x8+r12:DI]
  960: r15:DI=r8:DI
  485: {flags:CCC=cmp(r15:DI+bx:DI,bx:DI);r15:DI=r15:DI+bx:DI;}
  737: r15:DI={(geu(flags:CCC,0))?r15:DI:bx:DI}

to:

 1110: {flags:CCC=cmp(r8:DI+bx:DI,bx:DI);r8:DI=r8:DI+bx:DI;}
 : r15:DI=[r14:DI*0x8+r12:DI]
 1112: r15:DI={(geu(flags:CCC,0))?r8:DI:r15:DI}

Please note that(insn 1110) uses register BX, but its
initialization was eliminated.

Avoid conversion if eliminated move intialized a register, used
in the moved instruction.

2022-11-03  Uroš Bizjak  

gcc/ChangeLog:

PR target/107404
* config/i386/i386.md (eliminate reg-reg move by inverting the
condition of a cmove #2 peephole2): Check if eliminated move
initialized a register, used in the moved instruction.

gcc/testsuite/ChangeLog:

PR target/107404
* g++.target/i386/pr107404.C: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Pushed to master.

Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 85567980aa3..436eabb691a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -21800,7 +21800,8 @@ (define_peephole2
   && REGNO (operands[2]) != REGNO (operands[1])
   && peep2_reg_dead_p (2, operands[1])
   && peep2_reg_dead_p (4, operands[2])
-  && !reg_overlap_mentioned_p (operands[0], operands[3])"
+  && !reg_overlap_mentioned_p (operands[0], operands[3])
+  && !reg_mentioned_p (operands[2], operands[6])"
  [(parallel [(set (match_dup 7) (match_dup 8))
 (set (match_dup 1) (match_dup 9))])
   (set (match_dup 0) (match_dup 3))
diff --git a/gcc/testsuite/g++.target/i386/pr107404.C 
b/gcc/testsuite/g++.target/i386/pr107404.C
new file mode 100644
index 000..e47d0fd779d
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr107404.C
@@ -0,0 +1,53 @@
+// PR target/107404
+// { dg-do run }
+// { dg-options "-O3" }
+
+unsigned long long a;
+void b(unsigned long long *f, int p2) { *f ^= p2; }
+long c;
+char e, i;
+short g, m;
+long long ab[1][25][21][22];
+unsigned long long aa[1][21][22];
+unsigned long long ae[1][25][21][21];
+long long ac[129360];
+char ad[25][1][21];
+char ah[1][25][1][21];
+short af[100];
+long max(long f, unsigned long p2) { return f < p2 ? p2 : f; }
+const int (const int , const int ) { return f < p2 ? p2 : f; }
+void foo(unsigned f, unsigned p2, char l, char p4, long long n[][25][21][22],
+unsigned long long p6[][21][22], unsigned long long u[][25][21][21]) {
+  long an;
+  for (int j = 0; j < 4; j = p2)
+for (short k = 0; k < 7; k += 2)
+  for (short o = 0; o < (short)p2 + 21742; o = l) {
+for (signed char p = 2; p < 9; p += p4)
+  if (p6[j][o][p])
+for (long q(3); 4 ? n[0][k][o][0] : 0;
+ q += p6[0][o][0] ? p6[j][0][p] : 0)
+  ac[j + q] = 5066799590;
+for (long r(p4 - 16); r < 21; r += 4) {
+  ad[k][o][r] = max(u[j][k][o][r], f + u[j][k][o][r]);
+  long d = u[j][k][o][r];
+  an = d < p2 ? p2 : d;
+  e = ah[j][k][o][r] = an;
+  af[o * r] = i;
+}
+for (short s(c); s < (short)p2; s = 2)
+  for (short am(m); am; am = max2(3, p2))
+for (long y = 0; y; y = 3)
+  for (short t(0); t < max2(g, 0);)
+;
+  }
+}
+int main() {
+  foo(7, 1558227751, 104, 16, ab, aa, ae);
+  for (unsigned long v = 0; v < 5; ++v)
+for (unsigned long w = 0; w < 1; ++w)
+  for (unsigned long x = 0; x < 21; ++x)
+b(, ad[v][w][x]);
+
+  if (a)
+__builtin_abort();
+}


Re: [PATCH v2] c++: Use in-process client when networking is disabled

2022-11-03 Thread Nathan Sidwell via Gcc-patches

On 11/3/22 05:37, Torbjörn SVENSSON wrote:

v1 -> v2:
Updated expression in bad-mapper-3.C

Ok for trunk?

---

Without the patch, the output for bad-mapper-3.C would be:

/src/gcc/gcc/testsuite/g++.dg/modules/bad-mapper-3.C:2:1: error: unknown 
Compiled Module Interface: no such module

As this line is unexpected, the test case would fail.
The same problem can also be seen for g++.dg/modules/bad-mapper-2.C.

gcc/cp/ChangeLog:

* mapper-client.cc: Use in-process client when networking is
disabled.

gcc/testsuite/ChangeLog:

* g++.dg/modules/bad-mapper-3.C: Update dg-error pattern.

Tested on Windows with arm-none-eabi for Cortex-M3 in gcc-11 tree.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
  gcc/cp/mapper-client.cc | 4 
  gcc/testsuite/g++.dg/modules/bad-mapper-3.C | 2 +-
  2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index fe9544b5ba4..4dcb3a03660 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -227,6 +227,8 @@ module_client::open_module_client (location_t loc, const 
char *o,
int fd = -1;
  #if CODY_NETWORKING
fd = Cody::OpenLocal (, name.c_str () + 1);
+#else
+   errmsg = "CODY_NETWORKING disabled";


CODY_NETWORKING is implementor speak. I think just "disabled" is sufficient 
here?


  #endif
if (fd >= 0)
  c = new module_client (fd, fd);
@@ -254,6 +256,8 @@ module_client::open_module_client (location_t loc, const 
char *o,
int fd = -1;
  #if CODY_NETWORKING
fd = Cody::OpenInet6 (, name.c_str (), port);
+#else
+   errmsg = "CODY_NETWORKING disabled";
  #endif
name[colon] = ':';
  
diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C

index 9dab332ccb2..c91bb4e260c 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
@@ -1,6 +1,6 @@
  //  { dg-additional-options "-fmodules-ts 
-fmodule-mapper=localhost:172477262" }
  import unique3.bob;
-// { dg-error {failed connecting mapper 'localhost:172477262'} "" { target 
*-*-* } 0 }
+// { dg-error {failed (connecting|CODY_NETWORKING disabled) mapper 
'localhost:172477262'} "" { target *-*-* } 0 }
  // { dg-prune-output "fatal error:" }
  // { dg-prune-output "failed to read" }
  // { dg-prune-output "compilation terminated" }


--
Nathan Sidwell



Re: [Patch] OpenMP/Fortran: 'target update' with strides + DT components

2022-11-03 Thread Jakub Jelinek via Gcc-patches
On Mon, Oct 31, 2022 at 03:46:25PM +0100, Tobias Burnus wrote:
> OpenMP/Fortran: 'target update' with strides + DT components
> 
> OpenMP 5.0 permits to use arrays with strides and derived
> type components for the list items to the 'from'/'to' clauses
> of the 'target update' directive.
> 
> gcc/fortran/ChangeLog:
> 
>   * openmp.cc (gfc_match_omp_clauses): Permit derived types.
>   (resolve_omp_clauses):Accept noncontiguous
>   arrays.

Formatting.  Missing space before Accept and arrays. could fit on the
same line.

>   * trans-openmp.cc (gfc_trans_omp_clauses): Fixes for
>   derived-type changes; fix size for scalars.
> 
> libgomp/ChangeLog:
> 
>   * testsuite/libgomp.fortran/target-11.f90: New test.
>   * testsuite/libgomp.fortran/target-13.f90: New test.

Otherwise LGTM, assuming it actually works correctly.

I don't remember support for non-contiguous copying to/from devices
being actually added, on the library side we certainly have
omp_target_memcpy_rect which under the hood just does multiple copies
of the contiguous subparts, but I don't remember something similar
done in GOMP_target_update.  And I think it is not ok to copy bytes
that aren't requested to be copied.

Jakub



Re: [RFC] postreload cse'ing vector constants

2022-11-03 Thread Robin Dapp via Gcc-patches
Should we go ahead with this, i.e. push the change and wait for fallout?
 I guess we're still early enough in the cycle for that.  There are no
regressions anymore on s390, Power9, x86 and aarch64 (at least on the
farm machines I checked).

Regards
 Robin


[PATCH] c++: constexpr error with defaulted virtual dtor [PR93413]

2022-11-03 Thread Patrick Palka via Gcc-patches
We're rejecting the below testcase with

  error: 'virtual constexpr Base::~Base()' used before its definition
  error: 'virtual constexpr Derived::~Derived()' used before its definition

due to an early exit added to mark_used by r181272 to defer synthesis of
virtual destructors until EOF where we can set their linkage.  This makes
them effectively unusable for constexpr evaluation since that needs to
be done immediately and can't also be deferred.

Fortunately, this early exit seems to no longer be necessary ever since
r208030 enabled us to tentatively set linkage of all defaulted virtual
destructors, including templated ones.  So this patch just gets rid of
this early exit.

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

PR c++/93413

gcc/cp/ChangeLog:

* decl2.cc (mark_used): Don't defer synthesis of virtual
functions.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/constexpr-virtual21.C: New test.
---
 gcc/cp/decl2.cc  |  8 
 gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C | 10 ++
 2 files changed, 10 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index e6779268ad4..eeb59eae64f 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -5788,14 +5788,6 @@ mark_used (tree decl, tsubst_flags_t complain /* = 
tf_warning_or_error */)
   && !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
   && ! DECL_INITIAL (decl))
 {
-  /* Defer virtual destructors so that thunks get the right
-linkage.  */
-  if (DECL_VIRTUAL_P (decl) && !at_eof)
-   {
- note_vague_linkage_fn (decl);
- return true;
-   }
-
   /* Remember the current location for a function we will end up
 synthesizing.  Then we can inform the user where it was
 required in the case of error.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C
new file mode 100644
index 000..8b70c5f538b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C
@@ -0,0 +1,10 @@
+// PR c++/93413
+// { dg-do compile { target c++20 } }
+
+struct Base {
+  virtual ~Base() = default;
+};
+constexpr Base b;
+
+struct Derived : Base { };
+constexpr Derived d;
-- 
2.38.1.381.gc03801e19c



Re: [PATCH] docs: document sanitizers can trigger warnings

2022-11-03 Thread Gerald Pfeifer
Hi Martin,

On Wed, 26 Oct 2022, Martin Liška wrote:
> +Note the enabled sanitizer options tend to increase a false-positive rate
> +of selected warnings, most notably @option{-Wmaybe-uninitialized}.
> +And thus we recommend to disable @option{-Werror}.

I've been sitting muling over this and here is what I'm wondering might
be a possible alternative?

  Note that sanitzers tend to increase the rate of false positive
  warnings, most notably those around @option{-Wmaybe-uninitialized}.
  We recommend against combining @option{-Werror} and [the use of] 
  sanitzers.


Rationale for the second sentence: Disabling a warning that is off by 
default confused my mental model (and maybe those of other readers). :-)

What do you think?

Gerald


[committed] libstdc++: Add missing move in ranges::copy

2022-11-03 Thread Jonathan Wakely via Gcc-patches
Tested x86_64-linux. Pushed to trunk.

-- >8 --

This is needed to support a move-only output iterator when the input
iterators are specializations of __normal_iterator.

libstdc++-v3/ChangeLog:

* include/bits/ranges_algobase.h (__detail::__copy_or_move):
Move output iterator.
* testsuite/25_algorithms/copy/constrained.cc: Check copying to
move-only output iterator.
---
 libstdc++-v3/include/bits/ranges_algobase.h   |  2 +-
 .../25_algorithms/copy/constrained.cc | 24 +++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
b/libstdc++-v3/include/bits/ranges_algobase.h
index f6f0b9c83b0..443ad52ecc6 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -239,7 +239,7 @@ namespace ranges
{
  auto [__in,__out]
= ranges::__copy_or_move<_IsMove>(__first.base(), __last.base(),
- __result);
+ std::move(__result));
  return {decltype(__first){__in}, std::move(__out)};
}
   else if constexpr (__is_normal_iterator<_Out>)
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/constrained.cc 
b/libstdc++-v3/testsuite/25_algorithms/copy/constrained.cc
index 98f038a6c5f..444dfa78894 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/constrained.cc
@@ -226,6 +226,29 @@ test06()
   VERIFY( ranges::equal(v, (int[]){1,2,3,0}) );
 }
 
+void
+test07()
+{
+  struct move_only_output_iterator
+  {
+using value_type = int;
+using difference_type = short;
+using iterator_category = std::output_iterator_tag;
+
+move_only_output_iterator() = default;
+move_only_output_iterator(move_only_output_iterator&&) = default;
+move_only_output_iterator& operator=(move_only_output_iterator&&) = 
default;
+
+move_only_output_iterator& operator*() { return *this; }
+move_only_output_iterator& operator++() { return *this; }
+move_only_output_iterator operator++(int) { return std::move(*this); }
+
+void operator=(int) { }
+  };
+
+  ranges::copy(std::vector{1,2,3}, move_only_output_iterator{});
+}
+
 int
 main()
 {
@@ -235,4 +258,5 @@ main()
   test04();
   static_assert(test05());
   test06();
+  test07();
 }
-- 
2.38.1



Re: [PATCH, v2] Fortran: ordering of hidden procedure arguments [PR107441]

2022-11-03 Thread Mikael Morin

Le 02/11/2022 à 22:19, Harald Anlauf via Fortran a écrit :

Am 02.11.22 um 18:20 schrieb Mikael Morin:

Unfortunately no, the coarray case works, but the other problem remains.
The type problem is not visible in the definition of S, it is in the 
declaration of S's prototype in P.


S is defined as:

void s (character(kind=1)[1:_c] & restrict c, integer(kind=4) o, 
logical(kind=1) _o, integer(kind=8) _c)

{
...
}

but P has:

void p ()
{
   static void s (character(kind=1)[1:] & restrict, integer(kind=4), 
integer(kind=8), logical(kind=1));
   void (*) (character(kind=1)[1:] & restrict, integer(kind=4), 
integer(kind=8), logical(kind=1)) pp;


   pp = s;
...
}


Right, now I see it too.  Simplified case:

program p
   call s ("abcd")
contains
   subroutine s(c, o)
     character(*) :: c
     integer, optional, value :: o
   end subroutine s
end

I do see what needs to be done in gfc_get_function_type, which seems
in fact very simple.  But I get really lost in create_function_arglist
when trying to get the typelist right.

One thing is I really don't understand how the (hidden_)typelist is
managed here.  How does that macro TREE_CHAIN work?  Can we somehow
chain two typelists the same way we chain arguments?

TREE_CHAIN is just a linked list "next" pointer like there is in the 
fortran frontend a "next" pointer in gfc_ref or gfc_actual_arglist 
structures.
Yes, we can chain typelists; the implementation of chainon in tree.cc is 
just TREE_CHAIN appending under the hood.



(Failing that, I tried to split the loop over the dummy arguments in
create_function_arglist into two passes, one for the optional+value
variant, and one for the rest.  It turned out to be a bad idea...)

Not necessarily a bad idea, but one has to be careful to keep linked 
lists synchronized with argument walking.


The most simple, I think, is to move the hidden_typelist advancement for 
optional, value presence arguments from the main loop to a preliminary loop.


I hope it helps.


[PATCH v2] genmultilib: Add sanity check

2022-11-03 Thread Christophe Lyon via Gcc-patches
When a list of dirnames is provided to genmultilib, its length is
expected to match the number of options.  If this is not the case, the
build fails later for reasons not obviously related to this mistake.
This patch adds a sanity check to help diagnose such cases.

Tested by adding an option to t-aarch64 and no corresponding dirname,
with both bash and dash.

v2: do not use arrays (bash feature).

OK for trunk?

gcc/ChangeLog:

* genmultilib: Add sanity check.
---
 gcc/genmultilib | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/gcc/genmultilib b/gcc/genmultilib
index 1e387fb1589..b5f372c8358 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -141,6 +141,20 @@ multiarch=$9
 multilib_reuse=${10}
 enable_multilib=${11}
 
+# Sanity check: make sure we have as many dirnames as options
+if [ -n "${dirnames}" ]; then
+set x $options
+nboptions=$#
+set x $dirnames
+nbdirnames=$#
+if [ $nbdirnames -ne $nboptions ]; then
+   echo 1>&2 "Error calling $0: Number of dirnames ($nbdirnames) does not 
match number of options ($nboptions)"
+   echo 1>&2 "options: ${options}"
+   echo 1>&2 "dirnames: ${dirnames}"
+   exit 1
+fi
+fi
+
 echo "static const char *const multilib_raw[] = {"
 
 mkdir tmpmultilib.$$ || exit 1
-- 
2.34.1



RE: PING^1 [PATCH] arm: Allow to override location of .gnu.sgstubs section

2022-11-03 Thread Kyrylo Tkachov via Gcc-patches


> -Original Message-
> From: Torbjorn SVENSSON 
> Sent: Wednesday, November 2, 2022 6:19 PM
> To: gcc-patches@gcc.gnu.org
> Cc: Kyrylo Tkachov 
> Subject: PING^1 [PATCH] arm: Allow to override location of .gnu.sgstubs
> section
> 
> Hi,
> 
> Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603878.html
> 

Ok, thanks for pinging it.
Kyrill

> Kind regards,
> Torbjörn
> 
> On 2022-10-19 11:42, Torbjörn SVENSSON wrote:
> > Depending on the DejaGNU board definition, the .gnu.sgstubs section
> > might be placed on different locations in order to suite the target.
> > With this patch, the start location of the section is overrideable
> > from the board definition with the fallback of the previously
> > hardcoded location.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/arm/cmse/bitfield-1.c: Use overridable location.
> > * gcc.target/arm/cmse/bitfield-2.c: Likewise.
> > * gcc.target/arm/cmse/bitfield-3.c: Likewise.
> > * gcc.target/arm/cmse/cmse-20.c: Likewise.
> > * gcc.target/arm/cmse/struct-1.c: Likewise.
> > * gcc.target/arm/cmse/cmse.exp (cmse_sgstubs): New.
> >
> > Signed-off-by: Torbjörn SVENSSON 
> > ---
> >   gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c |  2 +-
> >   gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c |  2 +-
> >   gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c |  2 +-
> >   gcc/testsuite/gcc.target/arm/cmse/cmse-20.c|  2 +-
> >   gcc/testsuite/gcc.target/arm/cmse/cmse.exp | 11 +++
> >   gcc/testsuite/gcc.target/arm/cmse/struct-1.c   |  2 +-
> >   6 files changed, 16 insertions(+), 5 deletions(-)
> >
> > diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
> b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
> > index 5685f744435..c1221bef29f 100644
> > --- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
> > +++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
> > @@ -1,5 +1,5 @@
> >   /* This test is executed only if the execution engine supports CMSE
> instructions.  */
> > -/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=0x0040" } */
> > +/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=[cmse_sgstubs]" } */
> >
> >   typedef struct
> >   {
> > diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
> b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
> > index 7a794d44644..79e9a3efc93 100644
> > --- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
> > +++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
> > @@ -1,5 +1,5 @@
> >   /* This test is executed only if the execution engine supports CMSE
> instructions.  */
> > -/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=0x0040" } */
> > +/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=[cmse_sgstubs]" } */
> >
> >   typedef struct
> >   {
> > diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
> b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
> > index 5875f8dff48..d621a802ee1 100644
> > --- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
> > +++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
> > @@ -1,5 +1,5 @@
> >   /* This test is executed only if the execution engine supports CMSE
> instructions.  */
> > -/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=0x0040" } */
> > +/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=[cmse_sgstubs]" } */
> >
> >   typedef struct
> >   {
> > diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
> b/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
> > index 08e89bff637..bbea9358870 100644
> > --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
> > +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
> > @@ -1,5 +1,5 @@
> >   /* This test is executed only if the execution engine supports CMSE
> instructions.  */
> > -/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=0x0040" } */
> > +/* { dg-options "--save-temps -mcmse -Wl,--section-
> start,.gnu.sgstubs=[cmse_sgstubs]" } */
> >
> >   #include 
> >   #include 
> > diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
> b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
> > index 436dd71ef89..1df5d56c6d5 100644
> > --- a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
> > +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
> > @@ -44,6 +44,17 @@ if {[is-effective-target arm_cmse_hw]} then {
> >   set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
> >   set LTO_TORTURE_OPTIONS ""
> >
> > +# Return the start address of the .gnu.sgstubs section.
> > +proc cmse_sgstubs {} {
> > +# Allow to override the location of .gnu.sgstubs section.
> > +set tboard [target_info name]
> > +if {[board_info $tboard exists cmse_sgstubs]} {
> > +   return [board_info $tboard cmse_sgstubs]
> > +}
> > +
> > +return "0x0040"
> > +}
> > +
> >   # These are for both baseline and mainline.
> >   gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
> > "" $DEFAULT_CFLAGS
> > diff --git 

[PATCH v2] c++: Use in-process client when networking is disabled

2022-11-03 Thread Torbjörn SVENSSON via Gcc-patches
v1 -> v2:
Updated expression in bad-mapper-3.C

Ok for trunk?

---

Without the patch, the output for bad-mapper-3.C would be:

/src/gcc/gcc/testsuite/g++.dg/modules/bad-mapper-3.C:2:1: error: unknown 
Compiled Module Interface: no such module

As this line is unexpected, the test case would fail.
The same problem can also be seen for g++.dg/modules/bad-mapper-2.C.

gcc/cp/ChangeLog:

* mapper-client.cc: Use in-process client when networking is
disabled.

gcc/testsuite/ChangeLog:

* g++.dg/modules/bad-mapper-3.C: Update dg-error pattern.

Tested on Windows with arm-none-eabi for Cortex-M3 in gcc-11 tree.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
 gcc/cp/mapper-client.cc | 4 
 gcc/testsuite/g++.dg/modules/bad-mapper-3.C | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index fe9544b5ba4..4dcb3a03660 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -227,6 +227,8 @@ module_client::open_module_client (location_t loc, const 
char *o,
int fd = -1;
 #if CODY_NETWORKING
fd = Cody::OpenLocal (, name.c_str () + 1);
+#else
+   errmsg = "CODY_NETWORKING disabled";
 #endif
if (fd >= 0)
  c = new module_client (fd, fd);
@@ -254,6 +256,8 @@ module_client::open_module_client (location_t loc, const 
char *o,
int fd = -1;
 #if CODY_NETWORKING
fd = Cody::OpenInet6 (, name.c_str (), port);
+#else
+   errmsg = "CODY_NETWORKING disabled";
 #endif
name[colon] = ':';
 
diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C 
b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
index 9dab332ccb2..c91bb4e260c 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
@@ -1,6 +1,6 @@
 //  { dg-additional-options "-fmodules-ts -fmodule-mapper=localhost:172477262" 
}
 import unique3.bob;
-// { dg-error {failed connecting mapper 'localhost:172477262'} "" { target 
*-*-* } 0 }
+// { dg-error {failed (connecting|CODY_NETWORKING disabled) mapper 
'localhost:172477262'} "" { target *-*-* } 0 }
 // { dg-prune-output "fatal error:" }
 // { dg-prune-output "failed to read" }
 // { dg-prune-output "compilation terminated" }
-- 
2.25.1



RE: [PATCH 1/2]middle-end: Support early break/return auto-vectorization.

2022-11-03 Thread Tamar Christina via Gcc-patches
> -Original Message-
> From: Gcc-patches  bounces+tamar.christina=arm@gcc.gnu.org> On Behalf Of Jeff Law via
> Gcc-patches
> Sent: Wednesday, November 2, 2022 10:33 PM
> To: gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH 1/2]middle-end: Support early break/return auto-
> vectorization.
> 
> 
> On 11/2/22 15:50, Bernhard Reutner-Fischer via Gcc-patches wrote:
> > On 2 November 2022 15:45:39 CET, Tamar Christina via Gcc-patches  patc...@gcc.gnu.org> wrote:
> >> Hi All,
> >>
> >> This patch adds initial support for early break vectorization in GCC.
> >> The support is added for any target that implements a vector cbranch
> optab.
> >>
> >> Concretely the kind of loops supported are of the forms:
> >>
> >> for (int i = 0; i < N; i++)
> >> {
> >>
> >>if ()
> >>  ;
> >>
> >> }
> >>
> >> where  can be:
> >> - break
> >> - return
> > Just curious, but don't we have graphite for splitting loops on control 
> > flow,
> respectively reflow loops to help vectorization like in this case? Did you
> compare, and if so, what's missing?
> 
> Graphite isn't generally enabled, is largely unmaintained and often makes
> things worse rather than better.
> 

Indeed, but also couldn't get graphite to do much in this case.

Pass just says

0 loops carried no dependency.
Pass statistics of "graphite": 

And bails out. and none of the other graphite passes seem to put anything
in the dump files..

That aside, other reason to do it in the vectorizer is that eventually we can 
build
to support general control flow support and vectorizing these loops without
needing to peel the loop for ISAs that are fully masked.

Regards,
Tamar

> 
> jeff
> 



Re: [wwwdocs] [GCC13] Mention Intel __bf16 support in AVX512BF16 intrinsics.

2022-11-03 Thread Hongtao Liu via Gcc-patches
On Thu, Nov 3, 2022 at 2:53 PM Kong, Lingling  wrote:
>
> > > > diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
> > > > index 7c6bfa6e..cd0282f1 100644
> > > > --- a/htdocs/gcc-13/changes.html
> > > > +++ b/htdocs/gcc-13/changes.html
> > > > @@ -230,6 +230,8 @@ a work-in-progress.
> > > >For both C and C++ the __bf16 type is supported on
> > > >x86 systems with SSE2 and above enabled.
> > > >
> > > > +  Use __bf16 type for AVX512BF16 intrinsics.
> > > Could you add more explanations. Like originally it's ..., now it's
> > > ..., and what's the difference when users compile the same source
> > > code(which contains
> > > avx512bf16 intrinsics) with gcc12(and before) and GCC13.
> > > > +  
> > > >  
> > > >
> > > >  
> > > > --
> > > > 2.18.2
> > > >
> > Yes,  changed it. Thanks a lot!
> >
> > Subject: [PATCH] Mention Intel __bf16 support in AVX512BF16 intrinsics.
> >
> > ---
> >  htdocs/gcc-13/changes.html | 6 ++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html index
> > 7c6bfa6e..a35f4fab 100644
> > --- a/htdocs/gcc-13/changes.html
> > +++ b/htdocs/gcc-13/changes.html
> > @@ -230,6 +230,12 @@ a work-in-progress.
> >For both C and C++ the __bf16 type is supported on
> >x86 systems with SSE2 and above enabled.
> >
> > +  Use __bf16 type for AVX512BF16 intrinsics.
> > + Previously we use  short to represent bf16. Now we introduced
> > __bf16 to x86 psABI.
> > +  So we switch intrinsics in AVX512BF16 to the new type 
> > __bf16.
> > +  When users compile the same source code contains AVX512BF16
> > + intrinsics with
> > +  GCC13 need to support SSE2, which is different to GCC12 (and before).
> > +  
> >  
> >
> >  
> > --
> > 2.18.2
> >
> > BRs,
> > Lingling
>
> Sorry, modified again. New patch is as below.
Ok, thanks.
>
> htdocs/gcc-13/changes.html | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html index 
> 7c6bfa6e..7a5d2ab6 100644
> --- a/htdocs/gcc-13/changes.html
> +++ b/htdocs/gcc-13/changes.html
> @@ -230,6 +230,11 @@ a work-in-progress.
>For both C and C++ the __bf16 type is supported on
>x86 systems with SSE2 and above enabled.
>
> +  Use real __bf16 type for AVX512BF16 intrinsics.
> + Previously  we use __bfloat16 which is typedef of short. Now we
> + introduced real  __bf16 type to x86 psABI. Users need to
> + adjust their  AVX512BF16-related source code when upgrading GCC12 to GCC13.
> +  
>  
>
>  
> --
> 2.18.2
>
> BRs,
> Lingling



-- 
BR,
Hongtao


Re: [PATCH] Support Intel CMPccXADD

2022-11-03 Thread Uros Bizjak via Gcc-patches
On Thu, Nov 3, 2022 at 7:29 AM Haochen Jiang  wrote:
>
> Hi all,
>
> I just revised the patch according to review. The changes comparing to
> previous version is mentioned below.
>
> Ok for trunk?
>
> BRs,
> Haochen
>
> gcc/ChangeLog:
>
> * common/config/i386/cpuinfo.h (get_available_features):
> Detect cmpccxadd.
> * common/config/i386/i386-common.cc
> (OPTION_MASK_ISA2_CMPCCXADD_SET,
> OPTION_MASK_ISA2_CMPCCXADD_UNSET): New.
> (ix86_handle_option): Handle -mcmpccxadd.
> * common/config/i386/i386-cpuinfo.h (enum processor_features):
> Add FEATURE_CMPCCXADD.
> * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
> cmpccxadd.
> * config.gcc: Add cmpccxaddintrin.h.
> * config/i386/cpuid.h (bit_CMPCCXADD): New.
> * config/i386/i386-builtin-types.def:
> Add DEF_FUNCTION_TYPE(INT, PINT, INT, INT, INT)
> and DEF_FUNCTION_TYPE(LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT).
> * config/i386/i386-builtin.def (BDESC): Add new builtins.
> * config/i386/i386-c.cc (ix86_target_macros_internal): Define
> __CMPCCXADD__.
> * config/i386/i386-expand.cc (ix86_expand_special_args_builtin):
> Add new parameter to indicate constant position.
> Handle INT_FTYPE_PINT_INT_INT_INT
> and LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT.
> * config/i386/i386-isa.def (CMPCCXADD): Add DEF_PTA(CMPCCXADD).
> * config/i386/i386-options.cc (isa2_opts): Add -mcmpccxadd.
> (ix86_valid_target_attribute_inner_p): Handle cmpccxadd.
> * config/i386/i386.opt: Add option -mcmpccxadd.
> * config/i386/sync.md (cmpccxadd_): New define insn.
> * config/i386/x86gprintrin.h: Include cmpccxaddintrin.h.
> * doc/extend.texi: Document cmpccxadd.
> * doc/invoke.texi: Document -mcmpccxadd.
> * doc/sourcebuild.texi: Document target cmpccxadd.
> * config/i386/cmpccxaddintrin.h: New file.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/other/i386-2.C: Add -mcmpccxadd.
> * g++.dg/other/i386-3.C: Ditto.
> * gcc.target/i386/avx-1.c: Ditto.
> * gcc.target/i386/funcspec-56.inc: Add new target attribute.
> * gcc.target/i386/sse-13.c: Add -mcmpccxadd.
> * gcc.target/i386/sse-23.c: Ditto.
> * gcc.target/i386/x86gprintrin-1.c: Ditto.
> * gcc.target/i386/x86gprintrin-2.c: Ditto.
> * gcc.target/i386/x86gprintrin-3.c: Ditto.
> * gcc.target/i386/x86gprintrin-4.c: Ditto.
> * gcc.target/i386/x86gprintrin-5.c: Ditto.
> * gcc.target/i386/cmpccxadd-1.c: New test.
> * gcc.target/i386/cmpccxadd-2.c: Ditto.

LGTM, with a small pattern adjustment, see inline.

Thanks,
Uros.

> ---
>  gcc/common/config/i386/cpuinfo.h  |   2 +
>  gcc/common/config/i386/i386-common.cc |  15 ++
>  gcc/common/config/i386/i386-cpuinfo.h |   1 +
>  gcc/common/config/i386/i386-isas.h|   1 +
>  gcc/config.gcc|   3 +-
>  gcc/config/i386/cmpccxaddintrin.h |  89 +++
>  gcc/config/i386/cpuid.h   |   1 +
>  gcc/config/i386/i386-builtin-types.def|   4 +
>  gcc/config/i386/i386-builtin.def  |   4 +
>  gcc/config/i386/i386-c.cc |   2 +
>  gcc/config/i386/i386-expand.cc|  22 ++-
>  gcc/config/i386/i386-isa.def  |   1 +
>  gcc/config/i386/i386-options.cc   |   4 +-
>  gcc/config/i386/i386.opt  |   5 +
>  gcc/config/i386/sync.md   |  29 
>  gcc/config/i386/x86gprintrin.h|   2 +
>  gcc/doc/extend.texi   |   5 +
>  gcc/doc/invoke.texi   |  10 +-
>  gcc/doc/sourcebuild.texi  |   3 +
>  gcc/testsuite/g++.dg/other/i386-2.C   |   2 +-
>  gcc/testsuite/g++.dg/other/i386-3.C   |   2 +-
>  gcc/testsuite/gcc.target/i386/avx-1.c |   4 +
>  gcc/testsuite/gcc.target/i386/cmpccxadd-1.c   |  61 
>  gcc/testsuite/gcc.target/i386/cmpccxadd-2.c   | 138 ++
>  gcc/testsuite/gcc.target/i386/funcspec-56.inc |   2 +
>  gcc/testsuite/gcc.target/i386/sse-13.c|   6 +-
>  gcc/testsuite/gcc.target/i386/sse-23.c|   6 +-
>  .../gcc.target/i386/x86gprintrin-1.c  |   2 +-
>  .../gcc.target/i386/x86gprintrin-2.c  |   6 +-
>  .../gcc.target/i386/x86gprintrin-3.c  |   2 +-
>  .../gcc.target/i386/x86gprintrin-4.c  |   2 +-
>  .../gcc.target/i386/x86gprintrin-5.c  |   6 +-
>  gcc/testsuite/lib/target-supports.exp |  10 ++
>  33 files changed, 437 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/config/i386/cmpccxaddintrin.h
>  create mode 100644 gcc/testsuite/gcc.target/i386/cmpccxadd-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/cmpccxadd-2.c
>
> diff 

RE: [wwwdocs] [GCC13] Mention Intel __bf16 support in AVX512BF16 intrinsics.

2022-11-03 Thread Kong, Lingling via Gcc-patches
> > > diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
> > > index 7c6bfa6e..cd0282f1 100644
> > > --- a/htdocs/gcc-13/changes.html
> > > +++ b/htdocs/gcc-13/changes.html
> > > @@ -230,6 +230,8 @@ a work-in-progress.
> > >For both C and C++ the __bf16 type is supported on
> > >x86 systems with SSE2 and above enabled.
> > >
> > > +  Use __bf16 type for AVX512BF16 intrinsics.
> > Could you add more explanations. Like originally it's ..., now it's
> > ..., and what's the difference when users compile the same source
> > code(which contains
> > avx512bf16 intrinsics) with gcc12(and before) and GCC13.
> > > +  
> > >  
> > >
> > >  
> > > --
> > > 2.18.2
> > >
> Yes,  changed it. Thanks a lot!
> 
> Subject: [PATCH] Mention Intel __bf16 support in AVX512BF16 intrinsics.
> 
> ---
>  htdocs/gcc-13/changes.html | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html index
> 7c6bfa6e..a35f4fab 100644
> --- a/htdocs/gcc-13/changes.html
> +++ b/htdocs/gcc-13/changes.html
> @@ -230,6 +230,12 @@ a work-in-progress.
>For both C and C++ the __bf16 type is supported on
>x86 systems with SSE2 and above enabled.
>
> +  Use __bf16 type for AVX512BF16 intrinsics.
> + Previously we use  short to represent bf16. Now we introduced
> __bf16 to x86 psABI.
> +  So we switch intrinsics in AVX512BF16 to the new type __bf16.
> +  When users compile the same source code contains AVX512BF16
> + intrinsics with
> +  GCC13 need to support SSE2, which is different to GCC12 (and before).
> +  
>  
> 
>  
> --
> 2.18.2
> 
> BRs,
> Lingling

Sorry, modified again. New patch is as below.

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

diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html index 
7c6bfa6e..7a5d2ab6 100644
--- a/htdocs/gcc-13/changes.html
+++ b/htdocs/gcc-13/changes.html
@@ -230,6 +230,11 @@ a work-in-progress.
   For both C and C++ the __bf16 type is supported on
   x86 systems with SSE2 and above enabled.
   
+  Use real __bf16 type for AVX512BF16 intrinsics. 
+ Previously  we use __bfloat16 which is typedef of short. Now we 
+ introduced real  __bf16 type to x86 psABI. Users need to 
+ adjust their  AVX512BF16-related source code when upgrading GCC12 to GCC13.
+  
 
 
 
--
2.18.2

BRs,
Lingling


Re: [PATCH 6/6] Initial Sierra Forest Support

2022-11-03 Thread Hongtao Liu via Gcc-patches
On Fri, Oct 14, 2022 at 3:57 PM Haochen Jiang via Gcc-patches
 wrote:
>
> gcc/ChangeLog:
>
> * common/config/i386/cpuinfo.h (get_intel_cpu):
> Add Sierra Forest.
> * common/config/i386/i386-common.cc
> (processor_names): Add Sierra Forest.
> (processor_alias_table): Ditto.
> * common/config/i386/i386-cpuinfo.h
> (enum processor_types): Add INTEL_SIERRAFOREST.
> * config.gcc: Add -march=sierraforest.
> * config/i386/driver-i386.cc (host_detect_local_cpu):
> Handle Sierra Forest.
> * config/i386/i386-c.cc (ix86_target_macros_internal):
> Ditto.
> * config/i386/i386-options.cc (m_SIERRAFOREST): New define.
> (processor_cost_table): Add sierra forest.
> * config/i386/i386.h (enum processor_type):
> Add PROCESSOR_SIERRA_FOREST.
> (PTA_SIERRAFOREST): Ditto.
> * doc/extend.texi: Add sierra forest.
> * doc/invoke.texi: Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * g++.target/i386/mv16.C: Add sierra forest.
> * gcc.target/i386/funcspec-56.inc: Handle new march.
Ok, please commit this patch after CMPCCXADD patch.
> ---
>  gcc/common/config/i386/cpuinfo.h  | 6 ++
>  gcc/common/config/i386/i386-common.cc | 3 +++
>  gcc/common/config/i386/i386-cpuinfo.h | 1 +
>  gcc/config.gcc| 3 ++-
>  gcc/config/i386/driver-i386.cc| 5 -
>  gcc/config/i386/i386-c.cc | 7 +++
>  gcc/config/i386/i386-options.cc   | 2 ++
>  gcc/config/i386/i386.h| 3 +++
>  gcc/doc/extend.texi   | 3 +++
>  gcc/doc/invoke.texi   | 8 
>  gcc/testsuite/g++.target/i386/mv16.C  | 6 ++
>  gcc/testsuite/gcc.target/i386/funcspec-56.inc | 1 +
>  12 files changed, 46 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/common/config/i386/cpuinfo.h 
> b/gcc/common/config/i386/cpuinfo.h
> index f73834b086c..cc499c46ed0 100644
> --- a/gcc/common/config/i386/cpuinfo.h
> +++ b/gcc/common/config/i386/cpuinfo.h
> @@ -516,6 +516,12 @@ get_intel_cpu (struct __processor_model *cpu_model,
>cpu_model->__cpu_type = INTEL_COREI7;
>cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS;
>break;
> +case 0xaf:
> +  /* Sierra Forest.  */
> +  cpu = "sierraforest";
> +  CHECK___builtin_cpu_is ("sierraforest");
> +  cpu_model->__cpu_type = INTEL_SIERRAFOREST;
> +  break;
>  case 0x17:
>  case 0x1d:
>/* Penryn.  */
> diff --git a/gcc/common/config/i386/i386-common.cc 
> b/gcc/common/config/i386/i386-common.cc
> index 75966779d82..6ccc4d2f03c 100644
> --- a/gcc/common/config/i386/i386-common.cc
> +++ b/gcc/common/config/i386/i386-common.cc
> @@ -1874,6 +1874,7 @@ const char *const processor_names[] =
>"goldmont",
>"goldmont-plus",
>"tremont",
> +  "sierraforest",
>"knl",
>"knm",
>"skylake",
> @@ -2019,6 +2020,8 @@ const pta processor_alias_table[] =
>  M_CPU_TYPE (INTEL_GOLDMONT_PLUS), P_PROC_SSE4_2},
>{"tremont", PROCESSOR_TREMONT, CPU_HASWELL, PTA_TREMONT,
>  M_CPU_TYPE (INTEL_TREMONT), P_PROC_SSE4_2},
> +  {"sierraforest", PROCESSOR_SIERRAFOREST, CPU_HASWELL, PTA_SIERRAFOREST,
> +M_CPU_SUBTYPE (INTEL_SIERRAFOREST), P_PROC_AVX2},
>{"knl", PROCESSOR_KNL, CPU_SLM, PTA_KNL,
>  M_CPU_TYPE (INTEL_KNL), P_PROC_AVX512F},
>{"knm", PROCESSOR_KNM, CPU_SLM, PTA_KNM,
> diff --git a/gcc/common/config/i386/i386-cpuinfo.h 
> b/gcc/common/config/i386/i386-cpuinfo.h
> index 5a61d817007..a71a10ebbd7 100644
> --- a/gcc/common/config/i386/i386-cpuinfo.h
> +++ b/gcc/common/config/i386/i386-cpuinfo.h
> @@ -58,6 +58,7 @@ enum processor_types
>INTEL_TREMONT,
>AMDFAM19H,
>ZHAOXIN_FAM7H,
> +  INTEL_SIERRAFOREST,
>CPU_TYPE_MAX,
>BUILTIN_CPU_TYPE_MAX = CPU_TYPE_MAX
>  };
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index fe063bfbb26..c0e10a72bd5 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -665,7 +665,8 @@ slm nehalem westmere sandybridge ivybridge haswell 
> broadwell bonnell \
>  silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \
>  skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \
>  sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 
> nano-3000 \
> -nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 native"
> +nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \
> +sierraforest native"
>
>  # Additional x86 processors supported by --with-cpu=.  Each processor
>  # MUST be separated by exactly one space.
> diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
> index ef567045c67..be205a56ea2 100644
> --- a/gcc/config/i386/driver-i386.cc
> +++ b/gcc/config/i386/driver-i386.cc
> @@ -589,8 +589,11 @@ const char *host_detect_local_cpu (int argc, const char 
> **argv)
> 

[PATCH] Support Intel CMPccXADD

2022-11-03 Thread Haochen Jiang via Gcc-patches
Hi all,

I just revised the patch according to review. The changes comparing to
previous version is mentioned below.

Ok for trunk?

BRs,
Haochen

gcc/ChangeLog:

* common/config/i386/cpuinfo.h (get_available_features):
Detect cmpccxadd.
* common/config/i386/i386-common.cc
(OPTION_MASK_ISA2_CMPCCXADD_SET,
OPTION_MASK_ISA2_CMPCCXADD_UNSET): New.
(ix86_handle_option): Handle -mcmpccxadd.
* common/config/i386/i386-cpuinfo.h (enum processor_features):
Add FEATURE_CMPCCXADD.
* common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
cmpccxadd.
* config.gcc: Add cmpccxaddintrin.h.
* config/i386/cpuid.h (bit_CMPCCXADD): New.
* config/i386/i386-builtin-types.def:
Add DEF_FUNCTION_TYPE(INT, PINT, INT, INT, INT)
and DEF_FUNCTION_TYPE(LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT).
* config/i386/i386-builtin.def (BDESC): Add new builtins.
* config/i386/i386-c.cc (ix86_target_macros_internal): Define
__CMPCCXADD__.
* config/i386/i386-expand.cc (ix86_expand_special_args_builtin):
Add new parameter to indicate constant position.
Handle INT_FTYPE_PINT_INT_INT_INT
and LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT.
* config/i386/i386-isa.def (CMPCCXADD): Add DEF_PTA(CMPCCXADD).
* config/i386/i386-options.cc (isa2_opts): Add -mcmpccxadd.
(ix86_valid_target_attribute_inner_p): Handle cmpccxadd.
* config/i386/i386.opt: Add option -mcmpccxadd.
* config/i386/sync.md (cmpccxadd_): New define insn.
* config/i386/x86gprintrin.h: Include cmpccxaddintrin.h.
* doc/extend.texi: Document cmpccxadd.
* doc/invoke.texi: Document -mcmpccxadd.
* doc/sourcebuild.texi: Document target cmpccxadd.
* config/i386/cmpccxaddintrin.h: New file.

gcc/testsuite/ChangeLog:

* g++.dg/other/i386-2.C: Add -mcmpccxadd.
* g++.dg/other/i386-3.C: Ditto.
* gcc.target/i386/avx-1.c: Ditto.
* gcc.target/i386/funcspec-56.inc: Add new target attribute.
* gcc.target/i386/sse-13.c: Add -mcmpccxadd.
* gcc.target/i386/sse-23.c: Ditto.
* gcc.target/i386/x86gprintrin-1.c: Ditto.
* gcc.target/i386/x86gprintrin-2.c: Ditto.
* gcc.target/i386/x86gprintrin-3.c: Ditto.
* gcc.target/i386/x86gprintrin-4.c: Ditto.
* gcc.target/i386/x86gprintrin-5.c: Ditto.
* gcc.target/i386/cmpccxadd-1.c: New test.
* gcc.target/i386/cmpccxadd-2.c: Ditto.
---
 gcc/common/config/i386/cpuinfo.h  |   2 +
 gcc/common/config/i386/i386-common.cc |  15 ++
 gcc/common/config/i386/i386-cpuinfo.h |   1 +
 gcc/common/config/i386/i386-isas.h|   1 +
 gcc/config.gcc|   3 +-
 gcc/config/i386/cmpccxaddintrin.h |  89 +++
 gcc/config/i386/cpuid.h   |   1 +
 gcc/config/i386/i386-builtin-types.def|   4 +
 gcc/config/i386/i386-builtin.def  |   4 +
 gcc/config/i386/i386-c.cc |   2 +
 gcc/config/i386/i386-expand.cc|  22 ++-
 gcc/config/i386/i386-isa.def  |   1 +
 gcc/config/i386/i386-options.cc   |   4 +-
 gcc/config/i386/i386.opt  |   5 +
 gcc/config/i386/sync.md   |  29 
 gcc/config/i386/x86gprintrin.h|   2 +
 gcc/doc/extend.texi   |   5 +
 gcc/doc/invoke.texi   |  10 +-
 gcc/doc/sourcebuild.texi  |   3 +
 gcc/testsuite/g++.dg/other/i386-2.C   |   2 +-
 gcc/testsuite/g++.dg/other/i386-3.C   |   2 +-
 gcc/testsuite/gcc.target/i386/avx-1.c |   4 +
 gcc/testsuite/gcc.target/i386/cmpccxadd-1.c   |  61 
 gcc/testsuite/gcc.target/i386/cmpccxadd-2.c   | 138 ++
 gcc/testsuite/gcc.target/i386/funcspec-56.inc |   2 +
 gcc/testsuite/gcc.target/i386/sse-13.c|   6 +-
 gcc/testsuite/gcc.target/i386/sse-23.c|   6 +-
 .../gcc.target/i386/x86gprintrin-1.c  |   2 +-
 .../gcc.target/i386/x86gprintrin-2.c  |   6 +-
 .../gcc.target/i386/x86gprintrin-3.c  |   2 +-
 .../gcc.target/i386/x86gprintrin-4.c  |   2 +-
 .../gcc.target/i386/x86gprintrin-5.c  |   6 +-
 gcc/testsuite/lib/target-supports.exp |  10 ++
 33 files changed, 437 insertions(+), 15 deletions(-)
 create mode 100644 gcc/config/i386/cmpccxaddintrin.h
 create mode 100644 gcc/testsuite/gcc.target/i386/cmpccxadd-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cmpccxadd-2.c

diff --git a/gcc/config/i386/cmpccxaddintrin.h 
b/gcc/config/i386/cmpccxaddintrin.h
--- /dev/null
+++ b/gcc/config/i386/cmpccxaddintrin.h
+#define __cmpccxadd_epi64(A,B,C,D) \
+  __builtin_ia32_cmpccxadd64 ((long long *) (A), (long long) (B), \
+ (long long) (C), (_CMPCCX_ENUM) (D))
+#endif