[PATCH 0/2] Fix two test failures with --enable-default-pie [PR70150]

2024-05-05 Thread Xi Ruoyao
In GCC 14.1-rc1, there are two new (comparing to GCC 13) failures if
the build is configured --enable-default-pie.  Let's fix them.

Tested on x86_64-linux-gnu.  Ok for trunk and releases/gcc-14?

Xi Ruoyao (2):
  i386: testsuite: Add -no-pie for pr113689-1.c [PR70150]
  i386: testsuite: Adapt fentryname3.c for r14-811 change [PR70150]

 gcc/testsuite/gcc.target/i386/fentryname3.c | 3 +--
 gcc/testsuite/gcc.target/i386/pr113689-1.c  | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

-- 
2.45.0



[PATCH 2/2] i386: testsuite: Adapt fentryname3.c for r14-811 change [PR70150]

2024-05-05 Thread Xi Ruoyao
After r14-811 "call *nop@GOTPCREL(%rip)" is only generated with
-mno-direct-extern-access even if --enable-default-pie.  So the r13-1614
change to this file is not valid anymore.

gcc/testsuite/ChangeLog:

PR testsuite/70150
* gcc.target/i386/fentryname3.c (dg-final): Revert r13-1614
change.
---
 gcc/testsuite/gcc.target/i386/fentryname3.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/fentryname3.c 
b/gcc/testsuite/gcc.target/i386/fentryname3.c
index c14a4ebb0cf..bd7c997c178 100644
--- a/gcc/testsuite/gcc.target/i386/fentryname3.c
+++ b/gcc/testsuite/gcc.target/i386/fentryname3.c
@@ -3,8 +3,7 @@
 /* { dg-require-profiling "-pg" } */
 /* { dg-options "-pg -mfentry"  } */
 /* { dg-final { scan-assembler "section.*__entry_loc" } } */
-/* { dg-final { scan-assembler "0x0f, 0x1f, 0x44, 0x00, 0x00" { target nonpic 
} } } */
-/* { dg-final { scan-assembler "call\t\\*nop@GOTPCREL" { target { ! nonpic } } 
} } */
+/* { dg-final { scan-assembler "0x0f, 0x1f, 0x44, 0x00, 0x00" } } */
 /* { dg-final { scan-assembler-not "__fentry__" } } */
 
 __attribute__((fentry_name("nop"), fentry_section("__entry_loc")))
-- 
2.45.0



[PATCH 1/2] i386: testsuite: Add -no-pie for pr113689-1.c [PR70150]

2024-05-05 Thread Xi Ruoyao
For a --enable-default-pie build, using -fno-pic (for compiler) but
not -no-pie (for linker) triggers some linker warnings counted as
excess errors:

/usr/bin/ld: /tmp/cc8MgxiR.o: warning: relocation in read-only
section `.text.startup'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE

gcc/testsuite/ChangeLog:

PR testsuite/70150
* gcc.target/i386/pr113689-1.c (dg-options): Add -no-pie.
---
 gcc/testsuite/gcc.target/i386/pr113689-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr113689-1.c 
b/gcc/testsuite/gcc.target/i386/pr113689-1.c
index 9b8474ed933..0424db2dfdc 100644
--- a/gcc/testsuite/gcc.target/i386/pr113689-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr113689-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run { target { lp64 && fpic } } } */
-/* { dg-options "-O2 -fno-pic -fprofile -mcmodel=large" } */
+/* { dg-options "-O2 -fno-pic -no-pie -fprofile -mcmodel=large" } */
 /* { dg-skip-if "PR90698" { *-*-darwin* } } */
 /* { dg-skip-if "PR113909" { *-*-solaris2* } } */
 
-- 
2.45.0



Re: [PATCH] x86: Fix cmov cost model issue [PR109549]

2024-05-05 Thread Hongtao Liu
CC uros.

On Mon, May 6, 2024 at 11:03 AM Kong, Lingling  wrote:
>
> Hi,
> (if_then_else:SI (eq (reg:CCZ 17 flags)
> (const_int 0 [0]))
> (reg/v:SI 101 [ e ])
> (reg:SI 102))
> The cost is 8 for the rtx, the cost for
> (eq (reg:CCZ 17 flags) (const_int 0 [0])) is 4, but this is just an operator 
> do not need to compute it's cost in cmov.
It looks like a reasonable change to me, for cmov, the first operand
of if_then_else is not a mask.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu.
> OK for trunk?
>
> gcc/ChangeLog:
>
> PR target/109549
> * config/i386/i386.cc (ix86_rtx_costs): The XEXP (x, 0) for cmov
> is an operator do not need to compute cost.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/cmov6.c: Fixed.
> ---
>  gcc/config/i386/i386.cc   | 2 +-
>  gcc/testsuite/gcc.target/i386/cmov6.c | 5 +
>  2 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 
> 4d6b2b98761..59b4ce3bfbf 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -22237,7 +22237,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int 
> outer_code_i, int opno,
> {
>   /* cmov.  */
>   *total = COSTS_N_INSNS (1);
> - if (!REG_P (XEXP (x, 0)))
> + if (!COMPARISON_P (XEXP (x, 0)) && !REG_P (XEXP (x, 0)))
> *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>   if (!REG_P (XEXP (x, 1)))
> *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed); diff 
> --git a/gcc/testsuite/gcc.target/i386/cmov6.c 
> b/gcc/testsuite/gcc.target/i386/cmov6.c
> index 5111c8a9099..535326e4c2a 100644
> --- a/gcc/testsuite/gcc.target/i386/cmov6.c
> +++ b/gcc/testsuite/gcc.target/i386/cmov6.c
> @@ -1,9 +1,6 @@
>  /* { dg-do compile } */
>  /* { dg-options "-O2 -march=k8" } */
> -/* if-converting this sequence would require two cmov
> -   instructions and seems to always cost more independent
> -   of the TUNE_ONE_IF_CONV setting.  */
> -/* { dg-final { scan-assembler-not "cmov\[^6\]" } } */
> +/* { dg-final { scan-assembler "cmov\[^6\]" } } */
>
>  /* Verify that blocks are converted to conditional moves.  */  extern int 
> bar (int, int);
> --
> 2.31.1
>


-- 
BR,
Hongtao


[PATCH] x86: Fix cmov cost model issue [PR109549]

2024-05-05 Thread Kong, Lingling
Hi,
(if_then_else:SI (eq (reg:CCZ 17 flags)
(const_int 0 [0]))
(reg/v:SI 101 [ e ])
(reg:SI 102))
The cost is 8 for the rtx, the cost for
(eq (reg:CCZ 17 flags) (const_int 0 [0])) is 4, but this is just an operator do 
not need to compute it's cost in cmov.

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

gcc/ChangeLog:

PR target/109549
* config/i386/i386.cc (ix86_rtx_costs): The XEXP (x, 0) for cmov
is an operator do not need to compute cost.

gcc/testsuite/ChangeLog:

* gcc.target/i386/cmov6.c: Fixed.
---
 gcc/config/i386/i386.cc   | 2 +-
 gcc/testsuite/gcc.target/i386/cmov6.c | 5 +
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 
4d6b2b98761..59b4ce3bfbf 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -22237,7 +22237,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int 
outer_code_i, int opno,
{
  /* cmov.  */
  *total = COSTS_N_INSNS (1);
- if (!REG_P (XEXP (x, 0)))
+ if (!COMPARISON_P (XEXP (x, 0)) && !REG_P (XEXP (x, 0)))
*total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
  if (!REG_P (XEXP (x, 1)))
*total += rtx_cost (XEXP (x, 1), mode, code, 1, speed); diff --git 
a/gcc/testsuite/gcc.target/i386/cmov6.c b/gcc/testsuite/gcc.target/i386/cmov6.c
index 5111c8a9099..535326e4c2a 100644
--- a/gcc/testsuite/gcc.target/i386/cmov6.c
+++ b/gcc/testsuite/gcc.target/i386/cmov6.c
@@ -1,9 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -march=k8" } */
-/* if-converting this sequence would require two cmov
-   instructions and seems to always cost more independent
-   of the TUNE_ONE_IF_CONV setting.  */
-/* { dg-final { scan-assembler-not "cmov\[^6\]" } } */
+/* { dg-final { scan-assembler "cmov\[^6\]" } } */
 
 /* Verify that blocks are converted to conditional moves.  */  extern int bar 
(int, int);
--
2.31.1



[NOT CODE REVIEW] [PATCH v3 1/1] [RISC-V] Add support for _Bfloat16

2024-05-05 Thread Xiao Zeng
1 At point ,
  BF16 has already been completed "post public review".

2 LLVM has also added support for RISCV BF16 in
   and
  .

3 According to the discussion 
,
  this use __bf16 and use DF16b in riscv_mangle_type like x86.

Below test are passed for this patch
* The riscv fully regression test.

gcc/ChangeLog:

* config/riscv/iterators.md: New mode iterator HFBF.
* config/riscv/riscv-builtins.cc (riscv_init_builtin_types):
Initialize data type _Bfloat16.
* config/riscv/riscv-modes.def (FLOAT_MODE): New.
(ADJUST_FLOAT_FORMAT): New.
* config/riscv/riscv.cc (riscv_mangle_type): Support for BFmode.
(riscv_scalar_mode_supported_p): Ditto.
(riscv_libgcc_floating_mode_supported_p): Ditto.
(riscv_init_libfuncs): Set the conversion method for BFmode and
HFmode.
(riscv_block_arith_comp_libfuncs_for_mode): Set the arithmetic
and comparison libfuncs for the mode.
* config/riscv/riscv.md (mode" ): Add BF.
(movhf): Support for BFmode.
(mov): Ditto.
(*movhf_softfloat): Ditto.
(*mov_softfloat): Ditto.

libgcc/ChangeLog:

* config/riscv/sfp-machine.h (_FP_NANFRAC_B): New.
(_FP_NANSIGN_B): Ditto.
* config/riscv/t-softfp32: Add support for BF16 libfuncs.
* config/riscv/t-softfp64: Ditto.
* soft-fp/floatsibf.c: For si -> bf16.
* soft-fp/floatunsibf.c: For unsi -> bf16.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/bf16_arithmetic.c: New test.
* gcc.target/riscv/bf16_call.c: New test.
* gcc.target/riscv/bf16_comparison.c: New test.
* gcc.target/riscv/bf16_float_libcall_convert.c: New test.
* gcc.target/riscv/bf16_integer_libcall_convert.c: New test.

Co-authored-by: Jin Ma 
---
 gcc/config/riscv/iterators.md |  2 +
 gcc/config/riscv/riscv-builtins.cc| 16 
 gcc/config/riscv/riscv-modes.def  |  3 +
 gcc/config/riscv/riscv.cc | 64 ++-
 gcc/config/riscv/riscv.md | 24 +++---
 .../gcc.target/riscv/bf16_arithmetic.c| 42 ++
 gcc/testsuite/gcc.target/riscv/bf16_call.c| 12 +++
 .../gcc.target/riscv/bf16_comparison.c| 36 +
 .../riscv/bf16_float_libcall_convert.c| 57 +
 .../riscv/bf16_integer_libcall_convert.c  | 81 +++
 libgcc/config/riscv/sfp-machine.h |  3 +
 libgcc/config/riscv/t-softfp32| 10 ++-
 libgcc/config/riscv/t-softfp64|  3 +-
 libgcc/soft-fp/floatsibf.c| 45 +++
 libgcc/soft-fp/floatunsibf.c  | 45 +++
 15 files changed, 407 insertions(+), 36 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_arithmetic.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_call.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_comparison.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_float_libcall_convert.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/bf16_integer_libcall_convert.c
 create mode 100644 libgcc/soft-fp/floatsibf.c
 create mode 100644 libgcc/soft-fp/floatunsibf.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 75e119e407a..32e1b140305 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -75,6 +75,8 @@
 ;; Iterator for floating-point modes that can be loaded into X registers.
 (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")])
 
+;; Iterator for floating-point modes of BF16
+(define_mode_iterator HFBF [HF BF])
 
 ;; ---
 ;; Mode attributes
diff --git a/gcc/config/riscv/riscv-builtins.cc 
b/gcc/config/riscv/riscv-builtins.cc
index d457e306dd1..4c08834288a 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -230,6 +230,7 @@ static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES];
   riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]]
 
 tree riscv_float16_type_node = NULL_TREE;
+tree riscv_bfloat16_type_node = NULL_TREE;
 
 /* Return the function type associated with function prototype TYPE.  */
 
@@ -273,6 +274,21 @@ riscv_init_builtin_types (void)
   if (!maybe_get_identifier ("_Float16"))
 lang_hooks.types.register_builtin_type (riscv_float16_type_node,
"_Float16");
+
+  /* Provide the _Bfloat16 type and bfloat16_type_node if needed.  */
+  if (!bfloat16_type_node)
+{
+  riscv_bfloat16_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (riscv_bfloat16_type_node) = 16;
+  SET_TYPE_MODE (riscv_bfloat16_type_node, BFmode);
+  layout_type (riscv_bfloat16_type_node);
+ 

[NOT CODE REVIEW] [PATCH v3 0/1] [RISC-V] Add support for _Bfloat16

2024-05-05 Thread Xiao Zeng
This v3 submission is only for testing whether the code meets the
format requirements of CI.

The CI testing website is located at: 


If satisfied, this code will be immediately pushed into trunk.

Detailed information can be found: 


Xiao Zeng (1):
  [RISC-V] Add support for _Bfloat16

 gcc/config/riscv/iterators.md |  2 +
 gcc/config/riscv/riscv-builtins.cc| 16 
 gcc/config/riscv/riscv-modes.def  |  3 +
 gcc/config/riscv/riscv.cc | 64 ++-
 gcc/config/riscv/riscv.md | 24 +++---
 .../gcc.target/riscv/bf16_arithmetic.c| 42 ++
 gcc/testsuite/gcc.target/riscv/bf16_call.c| 12 +++
 .../gcc.target/riscv/bf16_comparison.c| 36 +
 .../riscv/bf16_float_libcall_convert.c| 57 +
 .../riscv/bf16_integer_libcall_convert.c  | 81 +++
 libgcc/config/riscv/sfp-machine.h |  3 +
 libgcc/config/riscv/t-softfp32| 10 ++-
 libgcc/config/riscv/t-softfp64|  3 +-
 libgcc/soft-fp/floatsibf.c| 45 +++
 libgcc/soft-fp/floatunsibf.c  | 45 +++
 15 files changed, 407 insertions(+), 36 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_arithmetic.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_call.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_comparison.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_float_libcall_convert.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/bf16_integer_libcall_convert.c
 create mode 100644 libgcc/soft-fp/floatsibf.c
 create mode 100644 libgcc/soft-fp/floatunsibf.c

-- 
2.17.1



[PATCH v3] aarch64: Fix normal returns inside functions which use eh_returns [PR114843]

2024-05-05 Thread Andrew Pinski
The problem here is that on a normal return path, we still restore the
eh data return when we should not.
Instead of one return path in the case of eh_return, this changes over
to use multiple returns pathes just like a normal function.
On the normal path (non-eh return), we need to skip restoring of the eh
return data registers.

This fixes the code generation of _Unwind_RaiseException where the return value
was currupted.

Note this adds some testcases which might fail on some targets.
I know of the following targets will fail also:
arm is recorded as PR 114847.
powerpc is recorded as PR 114846.

Build and tested for aarch64-linux-gnu with no regressions.

Changes in:
* v2: Fix logical error in aarch64_pop_regs which was a premature optimization.
Check regno1 and regno2 independently now.
Also add eh_return-5.c which tests that case.
* v3: Instead of redoing the detection of the eh_return register store off
to frame.eh_return_allocated. Also don't consider eh_return data
registers as pop canidates.

Note v2 was not submitted.

PR target/114843

gcc/ChangeLog:

* config/aarch64/aarch64-protos.h (aarch64_expand_epilogue): New
prototype.
* config/aarch64/aarch64.h (EH_RETURN_DATA_REGISTERS_N): New define.
(EH_RETURN_DATA_REGNO): Use EH_RETURN_DATA_REGISTERS_N instead of hard 
coding 4.
(aarch64_frame): Add eh_return_allocated.
* config/aarch64/aarch64.cc (aarch64_restore_callee_saves): Skip
over the eh return data regs if not eh return.
(aarch64_expand_epilogue): New function, pass false.
(aarch64_expand_epilogue): Add was_eh_return argument.
Update calls to aarch64_restore_callee_saves and aarch64_pop_regs.
For eh_returns, update the sp and do an indirect jump.
Don't check EH_RETURN_TAKEN_RTX any more.
* config/aarch64/aarch64.h (EH_RETURN_TAKEN_RTX): Delete.
* config/aarch64/aarch64.md (eh_return): New define_expand.
(eh_return_internal): New pattern for eh_returns.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/eh_return-3.c: Update testcase.
* gcc.c-torture/execute/eh_return-1.c: New test.
* gcc.c-torture/execute/eh_return-2.c: New test.
* gcc.c-torture/execute/eh_return-3.c: New test.
* gcc.c-torture/execute/eh_return-4.c: New test.
* gcc.c-torture/execute/eh_return-5.c: New test.
* gcc.target/aarch64/eh_return-4.c: New test.

Signed-off-by: Andrew Pinski 
---
 gcc/config/aarch64/aarch64-protos.h   |  1 +
 gcc/config/aarch64/aarch64.cc | 78 ++-
 gcc/config/aarch64/aarch64.h  | 14 ++--
 gcc/config/aarch64/aarch64.md | 24 ++
 .../gcc.c-torture/execute/eh_return-1.c   | 20 +
 .../gcc.c-torture/execute/eh_return-2.c   | 23 ++
 .../gcc.c-torture/execute/eh_return-3.c   | 25 ++
 .../gcc.c-torture/execute/eh_return-4.c   | 25 ++
 .../gcc.c-torture/execute/eh_return-5.c   | 24 ++
 .../gcc.target/aarch64/eh_return-3.c  | 12 ++-
 .../gcc.target/aarch64/eh_return-4.c  | 32 
 11 files changed, 244 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/eh_return-1.c
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/eh_return-2.c
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/eh_return-3.c
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/eh_return-4.c
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/eh_return-5.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-4.c

diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 42639e9efcf..efe86d52873 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -904,6 +904,7 @@ const char * aarch64_gen_far_branch (rtx *, int, const char 
*, const char *);
 const char * aarch64_output_probe_stack_range (rtx, rtx);
 const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx);
 void aarch64_err_no_fpadvsimd (machine_mode);
+void aarch64_expand_epilogue (rtx_call_insn *, bool);
 void aarch64_expand_epilogue (rtx_call_insn *);
 rtx aarch64_ptrue_all (unsigned int);
 opt_machine_mode aarch64_ptrue_all_mode (rtx);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 662ff5a9b0c..afbe4eeb340 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7792,6 +7792,7 @@ aarch64_layout_frame (void)
 
 #define SLOT_NOT_REQUIRED (-2)
 #define SLOT_REQUIRED (-1)
+#define SLOT_EH_RETURN_REQUIRED (-3)
 
   frame.wb_push_candidate1 = INVALID_REGNUM;
   frame.wb_push_candidate2 = INVALID_REGNUM;
@@ -7805,7 +7806,7 @@ aarch64_layout_frame (void)
   /* ... that includes the eh data registers (if needed)...  */
   if (crtl->calls_eh_return)
 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
-  

Re: [RFA][RISC-V] Use "uw" forms for constant synthesis

2024-05-05 Thread Jeff Law




On 5/4/24 6:53 PM, Jeff Law wrote:


So another constant synthesis improvement.

In this patch we're looking at cases where we'd like to be able to use 
lui+slli, but can't because of the sign extending nature of lui on 
TARGET_64BIT.  For example: 0x800110020UL.  The trunk currently 
generates 4 instructions for that constant, when it can be done with 3 
(lui+slli.uw+addi).


When Zba is enabled, we can use lui+slli.uw as the slli.uw masks off the 
bits 32..63 before shifting, giving us the precise semantics we want.


I strongly suspect we'll want to do the same for a set of constants with 
lui+add.uw, lui+shNadd.uw, so you'll see the beginnings of generalizing 
support for lui followed by a "uw" instruction.


The new test just tests the set of cases that showed up while exploring 
a particular space of the constant synthesis problem.  It's not meant to 
be exhaustive (failure to use shadd when profitable).


Tested on rv64gc and rv32gcv.  OK for the trunk assuming it passes CI?

Assume I'll fix the two overly long lines pointed out by the linter :-)
jeff


[pushed] wwwdocs: gcc-14/porting_to: Improve markup.

2024-05-05 Thread Gerald Pfeifer
The key change is putting "GCC target" in  ... .

Pushed.

Gerald

---
 htdocs/gcc-14/porting_to.html | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html
index 13772080..db27f122 100644
--- a/htdocs/gcc-14/porting_to.html
+++ b/htdocs/gcc-14/porting_to.html
@@ -516,18 +516,17 @@ be included explicitly when compiling with GCC 14:
 
 Pragma GCC target now affects preprocessor symbols
 
-
-The behavior of pragma GCC target and specifically how it affects ISA
-macros has changed in GCC 14.  In GCC 13 and older, the GCC
+The behavior of pragma GCC target and specifically how
+it affects ISA macros has changed in GCC 14. Before the GCC
 target pragma defined and undefined corresponding ISA macros in
 C when using the integrated preprocessor during compilation but not
 when the preprocessor was invoked as a separate step or when using
 the -save-temps option.  In C++ the ISA macro definitions
-were performed in a way which did not have any actual effect.
+were performed in a way which did not have any actual effect.
 
-In GCC 14 C++ behaves like C with integrated preprocessing in earlier
+In GCC 14 C++ behaves like C with integrated preprocessing in earlier
 versions. Moreover, in both languages ISA macros are defined and
-undefined as expected when preprocessing separately from compilation.
+undefined as expected when preprocessing separately from compilation.
 
 
 This can lead to different behavior, especially in C++.  For example,
@@ -552,9 +551,8 @@ incorrect instruction set by GCC 14.
   which was not intended. */
 
 
-
-The fix in this case is to remember whether pop_options
-needs to be performed in a new user-defined macro.
+The fix in this case is to remember whether pop_options 
+needs to be performed in a new user-defined macro.
 
 
 
-- 
2.44.0


Re: [PATCH] libgfortran: Fix libgfortran.so versioning on Solaris with subdirs

2024-05-05 Thread FX Coudert
Hi Rainer,

> This patch fixes this by allowing for the new structure.
> Tested on i386-pc-solaris2.11 and sparc-sun-solaris2.11.
> 
> Ok for trunk?

OK to push, given it’s localised inside LIBGFOR_USE_SYMVER_SUN.

I find it weird though that .libs is harcoded there. If we look at all the 
lib*/Makefile.am in gcc, the only thing that ever needs to specify .libs is for 
Solaris versioning. It feels like it should be more generic, as you say (but 
that’s for longer term).

FX


[PATCH] libgfortran: Fix libgfortran.so versioning on Solaris with subdirs

2024-05-05 Thread Rainer Orth
The move of libgfortran objects to subdirectories completely broke the
creation of libgfortran.so on Solaris.  Since the gfortran.ver-sun rule
doesn't support that structure, no libtool objects are found, thus no
symbols exported from libgfortran.so, causing every link to fail.

This patch fixes this by allowing for the new structure.

Tested on i386-pc-solaris2.11 and sparc-sun-solaris2.11.

Ok for trunk?

Btw., I'm the first to admit the current way of performing those
filename/pathname transforms from libtool objects/archives to regular
objects/archives in the Makefiles is incredibly fragile.  It should be
handled in make_sunver.pl itself instead, but for now this needs a quick
fix.

Rainer

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


2024-05-05  Rainer Orth  

libgfortran:
* Makefile.am [LIBGFOR_USE_SYMVER_SUN] (gfortran.ver-sun): Handle
objects in subdirs.
* Makefile.in: Regenerate.

diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -29,7 +29,7 @@ gfortran.ver-sun : gfortran.ver \
 		$(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD)
 	perl $(top_srcdir)/../contrib/make_sunver.pl \
 	  gfortran.ver \
-	  $(libgfortran_la_OBJECTS:%.lo=.libs/%.o) \
+	  $(subst /,/.libs/,$(libgfortran_la_OBJECTS:.lo=.o)) \
 	 `echo $(libgfortran_la_LIBADD) | \
 	sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
 	 > $@ || (rm -f $@ ; exit 1)
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -4576,7 +4576,7 @@ uninstall-am: uninstall-cafexeclibLTLIBR
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@		$(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD)
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	perl $(top_srcdir)/../contrib/make_sunver.pl \
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	  gfortran.ver \
-@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	  $(libgfortran_la_OBJECTS:%.lo=.libs/%.o) \
+@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	  $(subst /,/.libs/,$(libgfortran_la_OBJECTS:.lo=.o)) \
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	 `echo $(libgfortran_la_LIBADD) | \
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
 @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@	 > $@ || (rm -f $@ ; exit 1)


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

2024-05-05 Thread Harald Anlauf

Hi Paul,

Am 05.05.24 um 18:48 schrieb Paul Richard Thomas:

Hi Harald,

Please do commit, with or without the extra bit for the function result.


I've committed the attached variant that excludes the case of a scalar
class(*) allocatable function result on the rhs, and added a TODO.


As well as having to get back to pr113363, I have patches in a complete
state for pr84006 and 98534. However they clash with yours. You arrived at
the head of the queue first and so after you :-)


Well, thanks for volunteering to clean up after me... ;-)

Cheers,
Harald


Regards

Paul

From 21e7aa5f3ea44ca2fef8deb8788edffc04901b5c Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Mon, 29 Apr 2024 19:52:52 +0200
Subject: [PATCH] Fortran: fix issues with class(*) assignment [PR114827]

gcc/fortran/ChangeLog:

	PR fortran/114827
	* trans-array.cc (gfc_alloc_allocatable_for_assignment): Take into
	account _len of unlimited polymorphic entities when calculating
	the effective element size for allocation size and array span.
	Set _len of lhs to _len of rhs.
	* trans-expr.cc (trans_class_assignment): Take into account _len
	of unlimited polymorphic entities for allocation size.

gcc/testsuite/ChangeLog:

	PR fortran/114827
	* gfortran.dg/asan/unlimited_polymorphic_34.f90: New test.
---
 gcc/fortran/trans-array.cc|  16 +++
 gcc/fortran/trans-expr.cc |  13 ++
 .../asan/unlimited_polymorphic_34.f90 | 135 ++
 3 files changed, 164 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/asan/unlimited_polymorphic_34.f90

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 30b84762346..7ec33fb1598 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -11278,6 +11278,19 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
 	gfc_add_modify (, linfo->delta[dim], tmp);
 }
 
+  /* Take into account _len of unlimited polymorphic entities, so that span
+ for array descriptors and allocation sizes are computed correctly.  */
+  if (UNLIMITED_POLY (expr2))
+{
+  tree len = gfc_class_len_get (TREE_OPERAND (desc2, 0));
+  len = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
+			 fold_convert (size_type_node, len),
+			 size_one_node);
+  elemsize2 = fold_build2_loc (input_location, MULT_EXPR,
+   gfc_array_index_type, elemsize2,
+   fold_convert (gfc_array_index_type, len));
+}
+
   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
 gfc_conv_descriptor_span_set (, desc, elemsize2);
 
@@ -11324,6 +11337,9 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
 	gfc_add_modify (, tmp,
 			fold_convert (TREE_TYPE (tmp),
 	  TYPE_SIZE_UNIT (type)));
+	  else if (UNLIMITED_POLY (expr2))
+	gfc_add_modify (, tmp,
+			gfc_class_len_get (TREE_OPERAND (desc2, 0)));
 	  else
 	gfc_add_modify (, tmp,
 			build_int_cst (TREE_TYPE (tmp), 0));
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 0280c441ced..bc8eb419cff 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -11991,6 +11991,19 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
 	old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
 
   size = gfc_vptr_size_get (rhs_vptr);
+
+  /* Take into account _len of unlimited polymorphic entities.
+	 TODO: handle class(*) allocatable function results on rhs.  */
+  if (UNLIMITED_POLY (rhs) && rhs->expr_type == EXPR_VARIABLE)
+	{
+	  tree len = trans_get_upoly_len (block, rhs);
+	  len = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
+ fold_convert (size_type_node, len),
+ size_one_node);
+	  size = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (size),
+  size, fold_convert (TREE_TYPE (size), len));
+	}
+
   tmp = lse->expr;
   class_han = GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
 	  ? gfc_class_data_get (tmp) : tmp;
diff --git a/gcc/testsuite/gfortran.dg/asan/unlimited_polymorphic_34.f90 b/gcc/testsuite/gfortran.dg/asan/unlimited_polymorphic_34.f90
new file mode 100644
index 000..c69158a1b55
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/asan/unlimited_polymorphic_34.f90
@@ -0,0 +1,135 @@
+! { dg-do run }
+! PR fortran/114827 - issues with class(*) assignment found by valgrind
+!
+! Contributed by Neil Carlson 
+
+program main
+  implicit none
+  call run
+  call run1
+  call run2
+contains
+  ! Scalar tests
+  subroutine run ()
+character(*),parameter :: c = 'fubarfubarfubarfubarfubarfu'
+character(*,kind=4), parameter :: d = 4_"abcdef"
+complex, parameter :: z = (1.,2.)
+class(*),  allocatable :: y
+
+call foo (c, y)
+select type (y)
+type is (character(*))
+!  print *, y(5:6)  ! ICE (-> pr114874)
+   if (y /= c) stop 1
+class default
+   stop 2
+end select
+
+call foo (z, y)
+select type (y)
+type is (complex)
+   if (y /= z) 

[PATCH v5 4/5] Add tests for C/C++ musttail attributes

2024-05-05 Thread Andi Kleen
Mostly adopted from the existing C musttail plugin tests.

gcc/testsuite/ChangeLog:

* c-c++-common/musttail1.c: New test.
* c-c++-common/musttail2.c: New test.
* c-c++-common/musttail3.c: New test.
* c-c++-common/musttail4.c: New test.
* c-c++-common/musttail5.c: New test.
---
 gcc/testsuite/c-c++-common/musttail1.c | 15 
 gcc/testsuite/c-c++-common/musttail2.c | 34 ++
 gcc/testsuite/c-c++-common/musttail3.c | 29 ++
 gcc/testsuite/c-c++-common/musttail4.c | 17 +
 gcc/testsuite/c-c++-common/musttail5.c | 28 +
 5 files changed, 123 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/musttail1.c
 create mode 100644 gcc/testsuite/c-c++-common/musttail2.c
 create mode 100644 gcc/testsuite/c-c++-common/musttail3.c
 create mode 100644 gcc/testsuite/c-c++-common/musttail4.c
 create mode 100644 gcc/testsuite/c-c++-common/musttail5.c

diff --git a/gcc/testsuite/c-c++-common/musttail1.c 
b/gcc/testsuite/c-c++-common/musttail1.c
new file mode 100644
index ..ac92f9f74616
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
+
+int __attribute__((noinline,noclone,noipa))
+callee (int i)
+{
+  return i * i;
+}
+
+int __attribute__((noinline,noclone,noipa))
+caller (int i)
+{
+  [[gnu::musttail]] return callee (i + 1);
+}
diff --git a/gcc/testsuite/c-c++-common/musttail2.c 
b/gcc/testsuite/c-c++-common/musttail2.c
new file mode 100644
index ..058329b69cc2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail2.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+
+struct box { char field[256]; int i; };
+
+int __attribute__((noinline,noclone,noipa))
+test_2_callee (int i, struct box b)
+{
+  if (b.field[0])
+return 5;
+  return i * i;
+}
+
+int __attribute__((noinline,noclone,noipa))
+test_2_caller (int i)
+{
+  struct box b;
+  [[gnu::musttail]] return test_2_callee (i + 1, b); /* { dg-error "cannot 
tail-call: " } */
+}
+
+extern void setjmp (void);
+void
+test_3 (void)
+{
+  [[gnu::musttail]] return setjmp (); /* { dg-error "cannot tail-call: " } */
+}
+
+typedef void (fn_ptr_t) (void);
+volatile fn_ptr_t fn_ptr;
+
+void
+test_5 (void)
+{
+  [[gnu::musttail]] return fn_ptr (); /* { dg-error "cannot tail-call: " } */
+}
diff --git a/gcc/testsuite/c-c++-common/musttail3.c 
b/gcc/testsuite/c-c++-common/musttail3.c
new file mode 100644
index ..ea9589c59ef2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail3.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+
+extern int foo2 (int x, ...);
+
+struct str
+{
+  int a, b;
+};
+
+struct str
+cstruct (int x)
+{
+  if (x < 10)
+[[clang::musttail]] return cstruct (x + 1);
+  return ((struct str){ x, 0 });
+}
+
+int
+foo (int x)
+{
+  if (x < 10)
+[[clang::musttail]] return foo2 (x, 29);
+  if (x < 100)
+{
+  int k = foo (x + 1);
+  [[clang::musttail]] return k;/* { dg-error "cannot tail-call: " } */
+}
+  return x;
+}
diff --git a/gcc/testsuite/c-c++-common/musttail4.c 
b/gcc/testsuite/c-c++-common/musttail4.c
new file mode 100644
index ..23f4b5e1cd68
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+
+struct box { char field[64]; int i; };
+
+struct box __attribute__((noinline,noclone,noipa))
+returns_struct (int i)
+{
+  struct box b;
+  b.i = i * i;
+  return b;
+}
+
+int __attribute__((noinline,noclone))
+test_1 (int i)
+{
+  [[gnu::musttail]] return returns_struct (i * 5).i; /* { dg-error "cannot 
tail-call: " } */
+}
diff --git a/gcc/testsuite/c-c++-common/musttail5.c 
b/gcc/testsuite/c-c++-common/musttail5.c
new file mode 100644
index ..7938e7ff80e4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail5.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23" { target c } } */
+/* { dg-options "-std=gnu++11" { target c++ } } */
+
+[[musttail]] int j; /* { dg-warning "attribute" } */
+__attribute__((musttail)) int k; /* { dg-warning "attribute" } */
+
+void foo(void)
+{
+  [[gnu::musttail]] j++; /* { dg-warning "attribute" } */
+  [[gnu::musttail]] if (k > 0) /* { dg-warning "attribute" } */
+[[gnu::musttail]] k++; /* { dg-warning "attribute" } */
+}
+
+int foo2(int p)
+{
+  [[gnu::musttail(1)]] return foo2(p + 1); /* { dg-error "attribute" } */
+}
+
+int i;
+
+int foo3(void)
+{
+  [[musttail]] i++; /* { dg-warning "attribute" } */
+  [[musttail]] if (i > 10) /* { dg-warning "attribute" } */
+[[musttail]] return foo2(i); /* { dg-warning "attribute" } */
+  return 0;
+}
-- 
2.44.0



[PATCH v5 2/5] C++: Support clang compatible [[musttail]] (PR83324)

2024-05-05 Thread Andi Kleen
This patch implements a clang compatible [[musttail]] attribute for
returns.

musttail is useful as an alternative to computed goto for interpreters.
With computed goto the interpreter function usually ends up very big
which causes problems with register allocation and other per function
optimizations not scaling. With musttail the interpreter can be instead
written as a sequence of smaller functions that call each other. To
avoid unbounded stack growth this requires forcing a sibling call, which
this attribute does. It guarantees an error if the call cannot be tail
called which allows the programmer to fix it instead of risking a stack
overflow. Unlike computed goto it is also type-safe.

It turns out that David Malcolm had already implemented middle/backend
support for a musttail attribute back in 2016, but it wasn't exposed
to any frontend other than a special plugin.

This patch adds a [[gnu::musttail]] attribute for C++ that can be added
to return statements. The return statement must be a direct call
(it does not follow dependencies), which is similar to what clang
implements. It then uses the existing must tail infrastructure.

For compatibility it also detects clang::musttail

One problem is that tree-tailcall usually fails when optimization
is disabled, which implies the attribute only really works with
optimization on. But that seems to be a reasonable limitation.

Passes bootstrap and full test

PR83324

gcc/cp/ChangeLog:

* cp-tree.h (finish_return_stmt): Add musttail_p.
(check_return_expr): Dito.
* parser.cc (cp_parser_statement): Handle [[musttail]].
(cp_parser_std_attribute): Dito.
(cp_parser_init_statement): Dito.
(cp_parser_jump_statement): Dito.
* semantics.cc (finish_return_stmt): Dito.
* typeck.cc (check_return_expr): Handle musttail_p flag.
---
 gcc/cp/cp-tree.h|  4 ++--
 gcc/cp/parser.cc| 30 --
 gcc/cp/semantics.cc |  6 +++---
 gcc/cp/typeck.cc| 20 ++--
 4 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 52d6841559ca..ef5f0039ece2 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7782,7 +7782,7 @@ extern void finish_while_stmt (tree);
 extern tree begin_do_stmt  (void);
 extern void finish_do_body (tree);
 extern void finish_do_stmt (tree, tree, bool, tree, bool);
-extern tree finish_return_stmt (tree);
+extern tree finish_return_stmt (tree, bool = false);
 extern tree begin_for_scope(tree *);
 extern tree begin_for_stmt (tree, tree);
 extern void finish_init_stmt   (tree);
@@ -8294,7 +8294,7 @@ extern tree composite_pointer_type(const 
op_location_t &,
 tsubst_flags_t);
 extern tree merge_types(tree, tree);
 extern tree strip_array_domain (tree);
-extern tree check_return_expr  (tree, bool *, bool *);
+extern tree check_return_expr  (tree, bool *, bool *, bool);
 extern tree spaceship_type (tree, tsubst_flags_t = 
tf_warning_or_error);
 extern tree genericize_spaceship   (location_t, tree, tree, tree);
 extern tree cp_build_binary_op  (const op_location_t &,
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 66ce161252c7..e1bf92628ac3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -2467,7 +2467,7 @@ static tree cp_parser_perform_range_for_lookup
 static tree cp_parser_range_for_member_function
   (tree, tree);
 static tree cp_parser_jump_statement
-  (cp_parser *);
+  (cp_parser *, bool = false);
 static void cp_parser_declaration_statement
   (cp_parser *);
 
@@ -12734,9 +12734,27 @@ cp_parser_statement (cp_parser* parser, tree 
in_statement_expr,
 NULL_TREE, false);
  break;
 
+   case RID_RETURN:
+ {
+   bool musttail_p = false;
+   std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
+   if (lookup_attribute ("gnu", "musttail", std_attrs))
+ {
+   musttail_p = true;
+   std_attrs = remove_attribute ("gnu", "musttail", std_attrs);
+ }
+   // support this for compatibility
+   if (lookup_attribute ("clang", "musttail", std_attrs))
+ {
+   musttail_p = true;
+   std_attrs = remove_attribute ("clang", "musttail", std_attrs);
+ }
+   statement = cp_parser_jump_statement (parser, musttail_p);
+ }
+ break;
+
case RID_BREAK:
case RID_CONTINUE:
-   case RID_RETURN:
case RID_CO_RETURN:
case RID_GOTO:
  std_attrs = process_stmt_hotness_attribute (std_attrs, 

[PATCH v5 5/5] Add documentation for musttail attribute

2024-05-05 Thread Andi Kleen
gcc/ChangeLog:

* doc/extend.texi: Document [[musttail]]
---
 gcc/doc/extend.texi | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e290265d68d3..deb100ad93b6 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9839,7 +9839,7 @@ same manner as the @code{deprecated} attribute.
 @section Statement Attributes
 @cindex Statement Attributes
 
-GCC allows attributes to be set on null statements.  @xref{Attribute Syntax},
+GCC allows attributes to be set on statements.  @xref{Attribute Syntax},
 for details of the exact syntax for using attributes.  Other attributes are
 available for functions (@pxref{Function Attributes}), variables
 (@pxref{Variable Attributes}), labels (@pxref{Label Attributes}), enumerators
@@ -9896,6 +9896,22 @@ foo (int x, int y)
 @code{y} is not actually incremented and the compiler can but does not
 have to optimize it to just @code{return 42 + 42;}.
 
+@cindex @code{musttail} statement attribute
+@item musttail
+
+The @code{gnu::musttail} or @code{clang::musttail} attribute
+can be applied to a @code{return} statement with a return-value expression
+that is a function call.  It asserts that the call must be a tail call that
+does not allocate extra stack space.
+
+@smallexample
+[[gnu::musttail]] return foo();
+@end smallexample
+
+If the compiler cannot generate a tail call it generates
+an error. Tail calls generally require enabling optimization.
+On some targets they may not be supported.
+
 @end table
 
 @node Attribute Syntax
@@ -10019,7 +10035,9 @@ the constant expression, if present.
 
 @subsubheading Statement Attributes
 In GNU C, an attribute specifier list may appear as part of a null
-statement.  The attribute goes before the semicolon.
+statement. The attribute goes before the semicolon.
+Some attributes in new style syntax are also supported
+on non-null statements.
 
 @subsubheading Type Attributes
 
-- 
2.44.0



[PATCH v5 3/5] C: Implement musttail attribute for returns

2024-05-05 Thread Andi Kleen
Implement a C23 clang compatible musttail attribute similar to the earlier
C++ implementation in the C parser.

PR83324

gcc/c/ChangeLog:

* c-parser.cc (struct attr_state): Define with musttail_p.
(c_parser_statement_after_labels): Handle [[musttail]]
(c_parser_std_attribute): Dito.
(c_parser_handle_musttail): Dito.
(c_parser_compound_statement_nostart): Dito.
(c_parser_all_labels): Dito.
(c_parser_statement): Dito.
* c-tree.h (c_finish_return): Add musttail_p flag.
* c-typeck.cc (c_finish_return): Handle musttail_p flag.
---
 gcc/c/c-parser.cc | 61 +--
 gcc/c/c-tree.h|  2 +-
 gcc/c/c-typeck.cc | 15 ++--
 3 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 00f8bf4376e5..9edadb0fee96 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1616,6 +1616,11 @@ struct omp_for_parse_data {
   bool fail : 1;
 };
 
+struct attr_state
+{
+  bool musttail_p; // parsed a musttail for return
+};
+
 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
  unsigned int);
 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
@@ -1660,7 +1665,7 @@ static location_t c_parser_compound_statement_nostart 
(c_parser *);
 static void c_parser_label (c_parser *, tree);
 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
 static void c_parser_statement_after_labels (c_parser *, bool *,
-vec * = NULL);
+vec * = NULL, attr_state = 
{});
 static tree c_parser_c99_block_statement (c_parser *, bool *,
  location_t * = NULL);
 static void c_parser_if_statement (c_parser *, bool *, vec *);
@@ -5756,6 +5761,8 @@ c_parser_std_attribute (c_parser *parser, bool for_tm)
}
   goto out;
 }
+  else if (is_attribute_p ("musttail", name))
+error ("% attribute has arguments");
   {
 location_t open_loc = c_parser_peek_token (parser)->location;
 matching_parens parens;
@@ -6941,6 +6948,28 @@ c_parser_handle_directive_omp_attributes (tree ,
 }
 }
 
+/* Check if STD_ATTR contains a musttail attribute and handle it
+   PARSER is the parser and A is the output attr_state.  */
+
+static tree
+c_parser_handle_musttail (c_parser *parser, tree std_attrs, attr_state )
+{
+  if (c_parser_next_token_is_keyword (parser, RID_RETURN))
+{
+  if (lookup_attribute ("gnu", "musttail", std_attrs))
+   {
+ std_attrs = remove_attribute ("gnu", "musttail", std_attrs);
+ a.musttail_p = true;
+   }
+  if (lookup_attribute ("clang", "musttail", std_attrs))
+   {
+ std_attrs = remove_attribute ("clang", "musttail", std_attrs);
+ a.musttail_p = true;
+   }
+}
+  return std_attrs;
+}
+
 /* Parse a compound statement except for the opening brace.  This is
used for parsing both compound statements and statement expressions
(which follow different paths to handling the opening).  */
@@ -6957,6 +6986,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
   bool in_omp_loop_block
 = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
   tree sl = NULL_TREE;
+  attr_state a = {};
 
   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
 {
@@ -7095,7 +7125,10 @@ c_parser_compound_statement_nostart (c_parser *parser)
= c_parser_nth_token_starts_std_attributes (parser, 1);
   tree std_attrs = NULL_TREE;
   if (have_std_attrs)
-   std_attrs = c_parser_std_attribute_specifier_sequence (parser);
+   {
+ std_attrs = c_parser_std_attribute_specifier_sequence (parser);
+ std_attrs = c_parser_handle_musttail (parser, std_attrs, a);
+   }
   if (c_parser_next_token_is_keyword (parser, RID_CASE)
  || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
  || (c_parser_next_token_is (parser, CPP_NAME)
@@ -7243,7 +7276,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
  last_stmt = true;
  mark_valid_location_for_stdc_pragma (false);
  if (!omp_for_parse_state)
-   c_parser_statement_after_labels (parser, NULL);
+   c_parser_statement_after_labels (parser, NULL, NULL, a);
  else
{
  /* In canonical loop nest form, nested loops can only appear
@@ -7285,15 +7318,18 @@ c_parser_compound_statement_nostart (c_parser *parser)
 /* Parse all consecutive labels, possibly preceded by standard
attributes.  In this context, a statement is required, not a
declaration, so attributes must be followed by a statement that is
-   not just a semicolon.  */
+   not just a semicolon.  Returns an attr_state.  */
 
-static void
+static attr_state
 c_parser_all_labels (c_parser *parser)
 {
+  attr_state a = {};
   

[PATCH v5 1/5] Improve must tail in RTL backend

2024-05-05 Thread Andi Kleen
- Give error messages for all causes of non sibling call generation
- Don't override choices of other non sibling call checks with
must tail. This causes ICEs. The must tail attribute now only
overrides flag_optimize_sibling_calls locally.
- Error out when tree-tailcall failed to mark a must-tail call
sibcall. In this case it doesn't know the true reason and only gives
a vague message (this could be improved, but it's already useful without
that) tree-tailcall usually fails without optimization, so must
adjust the existing must-tail plugin test to specify -O2.

PR83324

gcc/ChangeLog:

* calls.cc (expand_call): Fix mustcall implementation.

gcc/testsuite/ChangeLog:

* gcc.dg/plugin/must-tail-call-1.c: Adjust.
---
 gcc/calls.cc  | 30 ---
 .../gcc.dg/plugin/must-tail-call-1.c  |  1 +
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 21d78f9779fe..a6b8ee44cc29 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -2650,7 +2650,9 @@ expand_call (tree exp, rtx target, int ignore)
   /* The type of the function being called.  */
   tree fntype;
   bool try_tail_call = CALL_EXPR_TAILCALL (exp);
-  bool must_tail_call = CALL_EXPR_MUST_TAIL_CALL (exp);
+  /* tree-tailcall decided not to do tail calls. Error for the musttail case.  
*/
+  if (!try_tail_call)
+  maybe_complain_about_tail_call (exp, "other reasons");
   int pass;
 
   /* Register in which non-BLKmode value will be returned,
@@ -3022,10 +3024,22 @@ expand_call (tree exp, rtx target, int ignore)
  pushed these optimizations into -O2.  Don't try if we're already
  expanding a call, as that means we're an argument.  Don't try if
  there's cleanups, as we know there's code to follow the call.  */
-  if (currently_expanding_call++ != 0
-  || (!flag_optimize_sibling_calls && !CALL_FROM_THUNK_P (exp))
-  || args_size.var
-  || dbg_cnt (tail_call) == false)
+  if (currently_expanding_call++ != 0)
+{
+  maybe_complain_about_tail_call (exp, "inside another call");
+  try_tail_call = 0;
+}
+  if (!flag_optimize_sibling_calls
+   && !CALL_FROM_THUNK_P (exp)
+   && !CALL_EXPR_MUST_TAIL_CALL (exp))
+try_tail_call = 0;
+  if (args_size.var)
+{
+  /* ??? correct message?  */
+  maybe_complain_about_tail_call (exp, "stack space needed");
+  try_tail_call = 0;
+}
+  if (dbg_cnt (tail_call) == false)
 try_tail_call = 0;
 
   /* Workaround buggy C/C++ wrappers around Fortran routines with
@@ -3046,15 +3060,11 @@ expand_call (tree exp, rtx target, int ignore)
if (MEM_P (*iter))
  {
try_tail_call = 0;
+   maybe_complain_about_tail_call (exp, "hidden string length 
argument");
break;
  }
}
 
-  /* If the user has marked the function as requiring tail-call
- optimization, attempt it.  */
-  if (must_tail_call)
-try_tail_call = 1;
-
   /*  Rest of purposes for tail call optimizations to fail.  */
   if (try_tail_call)
 try_tail_call = can_implement_as_sibling_call_p (exp,
diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c 
b/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
index 3a6d4cceaba7..44af361e2925 100644
--- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile { target tail_call } } */
+/* { dg-options "-O2" } */
 /* { dg-options "-fdelayed-branch" { target sparc*-*-* } } */
 
 extern void abort (void);
-- 
2.44.0



[PATCH] testsuite: c++: Skip g++.dg/analyzer on Solaris [PR111475]

2024-05-05 Thread Rainer Orth
Rainer Orth  writes:

>> On Fri, May 03, 2024 at 09:31:08AM -0400, David Malcolm wrote:
>>> Jakub, Richi, Rainer: this is a non-trivial change that cleans up
>>> analyzer C++ testsuite results on Solaris, but has a slight risk of
>>> affecting analyzer behavior on other targets.  As such, I was thinking
>>> to hold off on backporting it to GCC 14 until after 14.1 is released.
>>> Is that a good plan?
>>
>> Agreed 14.2 is better target than 14.1 for this, especially if committed
>> shortly after 14.1 goes out.
>
> fully agreed: this is way too risky this close to the 14.1 release.  As
> a stop-gap measure, one might consider just skipping the C++ analyzer
> tests on Solaris to avoid the immense number of testsuite failures.

How about this?

Almost 1400 C++ analyzer tests FAIL on Solaris.  The patch is too risky
to apply so close to the GCC 14.1.0 release, so disable the tests on
Solaris instead to reduce the noise.

Tested on i386-pc-solaris2.11, sparc-sun-solaris2.11, and
x86_64-pc-linux-gnu.

Ok for gcc-14 branch?

Rainer

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


2024-05-05  Rainer Orth  

gcc/testsuite:
PR analyzer/111475
* g++.dg/analyzer/analyzer.exp: Disable on *-*-solaris2.*.

diff --git a/gcc/testsuite/g++.dg/analyzer/analyzer.exp b/gcc/testsuite/g++.dg/analyzer/analyzer.exp
--- a/gcc/testsuite/g++.dg/analyzer/analyzer.exp
+++ b/gcc/testsuite/g++.dg/analyzer/analyzer.exp
@@ -24,6 +24,11 @@ if { ![check_effective_target_analyzer] 
 return
 }
 
+# Disable on Solaris until PR analyzer/111475 is fixed.
+if { [istarget *-*-solaris2.*] } {
+return
+}
+
 if [info exists DEFAULT_CXXFLAGS] then {
   set save_default_cxxflags $DEFAULT_CXXFLAGS
 }


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

2024-05-05 Thread Paul Richard Thomas
Hi Harald,

Please do commit, with or without the extra bit for the function result.

As well as having to get back to pr113363, I have patches in a complete
state for pr84006 and 98534. However they clash with yours. You arrived at
the head of the queue first and so after you :-)

Regards

Paul


Re: [PATCH] Minor range type fixes for IPA in preparation for prange.

2024-05-05 Thread Aldy Hernandez
PING.

I can probably commit this patchlet as a ranger maintainer, but I'd
prefer a nod from a global or IPA maintainer.  It is the one patch
that's needed before I can throw the switch on prange support later
this week.

Thanks.
Aldy

On Sun, Apr 28, 2024 at 10:10 PM Aldy Hernandez  wrote:
>
> The polymorphic Value_Range object takes a tree type at construction
> so it can determine what type of range to use (currently irange or
> frange).  It seems a few of the types are slightly off.  This isn't a
> problem now, because IPA only cares about integers and pointers, which
> can both live in an irange.  However, with prange coming about, we
> need to get the type right, because you can't store an integer in a
> pointer range or vice versa.
>
> Also, in preparation for prange, the irange::supports_p() idiom will become:
>
>   irange::supports_p () || prange::supports_p()
>
> To avoid changing all these palces, I've added an inline function we
> can later change and change everything at once.
>
> Finally, there's a Value_Range::supports_type_p() &&
> irange::supports_p() in the code.  The latter is a subset of the
> former, so there's no need to check both.
>
> OK for trunk?
>
> gcc/ChangeLog:
>
> * ipa-cp.cc (ipa_vr_operation_and_type_effects): Use ipa_supports_p.
> (ipa_value_range_from_jfunc): Change Value_Range type.
> (propagate_vr_across_jump_function): Same.
> * ipa-cp.h (ipa_supports_p): New.
> * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Change 
> Value_Range type.
> * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Use 
> ipa_supports_p.
> (ipcp_get_parm_bits): Same.
> ---
>  gcc/ipa-cp.cc| 14 +++---
>  gcc/ipa-cp.h |  8 
>  gcc/ipa-fnsummary.cc |  2 +-
>  gcc/ipa-prop.cc  |  8 +++-
>  4 files changed, 19 insertions(+), 13 deletions(-)
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index a688dced5c9..5781f50c854 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -1649,7 +1649,7 @@ ipa_vr_operation_and_type_effects (vrange _vr,
>enum tree_code operation,
>tree dst_type, tree src_type)
>  {
> -  if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
> +  if (!ipa_supports_p (dst_type) || !ipa_supports_p (src_type))
>  return false;
>
>range_op_handler handler (operation);
> @@ -1720,7 +1720,7 @@ ipa_value_range_from_jfunc (vrange ,
>
>if (TREE_CODE_CLASS (operation) == tcc_unary)
> {
> - Value_Range res (vr_type);
> + Value_Range res (parm_type);
>
>   if (ipa_vr_operation_and_type_effects (res,
>  srcvr,
> @@ -1733,7 +1733,7 @@ ipa_value_range_from_jfunc (vrange ,
>   Value_Range op_res (vr_type);
>   Value_Range res (vr_type);
>   tree op = ipa_get_jf_pass_through_operand (jfunc);
> - Value_Range op_vr (vr_type);
> + Value_Range op_vr (TREE_TYPE (op));
>   range_op_handler handler (operation);
>
>   ipa_range_set_and_normalize (op_vr, op);
> @@ -2527,7 +2527,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, 
> ipa_jump_func *jfunc,
>if (src_lats->m_value_range.bottom_p ())
> return dest_lat->set_to_bottom ();
>
> -  Value_Range vr (operand_type);
> +  Value_Range vr (param_type);
>if (TREE_CODE_CLASS (operation) == tcc_unary)
> ipa_vr_operation_and_type_effects (vr,
>src_lats->m_value_range.m_vr,
> @@ -2540,16 +2540,16 @@ propagate_vr_across_jump_function (cgraph_edge *cs, 
> ipa_jump_func *jfunc,
> {
>   tree op = ipa_get_jf_pass_through_operand (jfunc);
>   Value_Range op_vr (TREE_TYPE (op));
> - Value_Range op_res (operand_type);
> + Value_Range op_res (param_type);
>   range_op_handler handler (operation);
>
>   ipa_range_set_and_normalize (op_vr, op);
>
>   if (!handler
> - || !op_res.supports_type_p (operand_type)
> + || !ipa_supports_p (operand_type)
>   || !handler.fold_range (op_res, operand_type,
>   src_lats->m_value_range.m_vr, op_vr))
> -   op_res.set_varying (operand_type);
> +   op_res.set_varying (param_type);
>
>   ipa_vr_operation_and_type_effects (vr,
>  op_res,
> diff --git a/gcc/ipa-cp.h b/gcc/ipa-cp.h
> index 7ff74fb5c98..abeaaa4053e 100644
> --- a/gcc/ipa-cp.h
> +++ b/gcc/ipa-cp.h
> @@ -291,4 +291,12 @@ public:
>
>  bool values_equal_for_ipcp_p (tree x, tree y);
>
> +/* Return TRUE if IPA supports ranges of TYPE.  */
> +
> +static inline bool
> +ipa_supports_p (tree type)
> +{
> +  return irange::supports_p (type);
> +}
> +
>  #endif /* IPA_CP_H */
> diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
> index