[gcc r15-2335] i386: Use BLKmode for {ld,st}tilecfg

2024-07-26 Thread Haochen Jiang via Gcc-cvs
https://gcc.gnu.org/g:f145f5411609dca5493a6709e8139609b584622f

commit r15-2335-gf145f5411609dca5493a6709e8139609b584622f
Author: Haochen Jiang 
Date:   Fri Jul 26 16:49:08 2024 +0800

i386: Use BLKmode for {ld,st}tilecfg

Hi all,

For AMX instructions related with memory, we will treat the memory
size as not specified since there won't be different size causing
confusion for memory.

This will change the output under Intel mode, which is broken for now when
using with assembler and aligns to current binutils behavior.

Bootstrapped and regtested on x86-64-pc-linux-gnu. Ok for trunk?

Thx,
Haochen

gcc/ChangeLog:

* config/i386/i386-expand.cc (ix86_expand_builtin): Change
from XImode to BLKmode.
* config/i386/i386.md (ldtilecfg): Change XI to BLK.
(sttilecfg): Ditto.

Diff:
---
 gcc/config/i386/i386-expand.cc |  2 +-
 gcc/config/i386/i386.md| 12 +---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 9a31e6df2aa2..d9ad06264aaf 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -14198,7 +14198,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx 
subtarget,
  op0 = convert_memory_address (Pmode, op0);
  op0 = copy_addr_to_reg (op0);
}
-  op0 = gen_rtx_MEM (XImode, op0);
+  op0 = gen_rtx_MEM (BLKmode, op0);
   if (fcode == IX86_BUILTIN_LDTILECFG)
icode = CODE_FOR_ldtilecfg;
   else
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6207036a2a01..fb10fdc9f96d 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -29032,24 +29032,22 @@
(set_attr "type" "other")])
 
 (define_insn "ldtilecfg"
-  [(unspec_volatile [(match_operand:XI 0 "memory_operand" "m")]
+  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
 UNSPECV_LDTILECFG)]
   "TARGET_AMX_TILE"
   "ldtilecfg\t%0"
   [(set_attr "type" "other")
(set_attr "prefix" "maybe_evex")
-   (set_attr "memory" "load")
-   (set_attr "mode" "XI")])
+   (set_attr "memory" "load")])
 
 (define_insn "sttilecfg"
-  [(set (match_operand:XI 0 "memory_operand" "=m")
-(unspec_volatile:XI [(const_int 0)] UNSPECV_STTILECFG))]
+  [(set (match_operand:BLK 0 "memory_operand" "=m")
+(unspec_volatile:BLK [(const_int 0)] UNSPECV_STTILECFG))]
   "TARGET_AMX_TILE"
   "sttilecfg\t%0"
   [(set_attr "type" "other")
(set_attr "prefix" "maybe_evex")
-   (set_attr "memory" "store")
-   (set_attr "mode" "XI")])
+   (set_attr "memory" "store")])
 
 (include "mmx.md")
 (include "sse.md")


[gcc r15-2336] middle-end: check for vector mode before calling get_mask_mode [PR116074]

2024-07-26 Thread Tamar Christina via Gcc-cvs
https://gcc.gnu.org/g:29e4e4bdb674118b898d50ce7751c183aa0a44ee

commit r15-2336-g29e4e4bdb674118b898d50ce7751c183aa0a44ee
Author: Tamar Christina 
Date:   Fri Jul 26 13:02:53 2024 +0100

middle-end: check for vector mode before calling get_mask_mode [PR116074]

For historical reasons AArch64 has TI mode vector types but does not 
consider
TImode a vector mode.

What's happening in the PR is that get_vectype_for_scalar_type is returning
vector(1) TImode for a TImode scalar.  This then fails when we call
targetm.vectorize.get_mask_mode (vecmode).exists (&) on the TYPE_MODE.

This checks for vector mode before using the results of
get_vectype_for_scalar_type.

gcc/ChangeLog:

PR target/116074
* tree-vect-patterns.cc (vect_recog_cond_store_pattern): Check 
vector mode.

gcc/testsuite/ChangeLog:

PR target/116074
* g++.target/aarch64/pr116074.C: New test.

Diff:
---
 gcc/testsuite/g++.target/aarch64/pr116074.C | 24 
 gcc/tree-vect-patterns.cc   |  3 ++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.target/aarch64/pr116074.C 
b/gcc/testsuite/g++.target/aarch64/pr116074.C
new file mode 100644
index ..54cf561510c4
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr116074.C
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+int m[40];
+
+template  struct j {
+  int length;
+  k *e;
+  void operator[](int) {
+if (length)
+  __builtin___memcpy_chk(m, m+3, sizeof (k), -1);
+  }
+};
+
+j> o;
+
+int *q;
+
+void ao(int i) {
+  for (; i > 0; i--) {
+o[1];
+*q = 1;
+  }
+}
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index b0821c74c1d8..5fbd1a4fa6b4 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -6624,7 +6624,8 @@ vect_recog_cond_store_pattern (vec_info *vinfo,
 
   machine_mode mask_mode;
   machine_mode vecmode = TYPE_MODE (vectype);
-  if (targetm.vectorize.conditional_operation_is_expensive (IFN_MASK_STORE)
+  if (!VECTOR_MODE_P (vecmode)
+  || targetm.vectorize.conditional_operation_is_expensive (IFN_MASK_STORE)
   || !targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode)
   || !can_vec_mask_load_store_p (vecmode, mask_mode, false))
 return NULL;


[gcc r15-2337] RISC-V: Work around bare apostrophe in error string.

2024-07-26 Thread Robin Dapp via Gcc-cvs
https://gcc.gnu.org/g:3f2bf415b447a0f6bc424c688b06e1f5946688a0

commit r15-2337-g3f2bf415b447a0f6bc424c688b06e1f5946688a0
Author: Robin Dapp 
Date:   Fri Jul 26 12:58:38 2024 +0200

RISC-V: Work around bare apostrophe in error string.

An unquoted apostrophe slipped through when testing the recent
V/M extension patch.  This, again, re-words the message to
"Currently the 'V' implementation requires the 'M' extension".

Going to commit as obvious after testing.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_override_options_internal):
Reword error string without apostrophe.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr116036.c: Adjust expected error
string.

Diff:
---
 gcc/config/riscv/riscv.cc  | 2 +-
 gcc/testsuite/gcc.target/riscv/rvv/base/pr116036.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 2bb7f2aace1b..a490b9598b04 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -9694,7 +9694,7 @@ riscv_override_options_internal (struct gcc_options *opts)
   /* We might use a multiplication to calculate the scalable vector length at
  runtime.  Therefore, require the M extension.  */
   if (TARGET_VECTOR && !TARGET_MUL)
-sorry ("GCC's current % implementation requires the % extension");
+sorry ("Currently the % implementation requires the % extension");
 
   /* Likewise floating-point division and square root.  */
   if ((TARGET_HARD_FLOAT_OPTS_P (opts) || TARGET_ZFINX_OPTS_P (opts))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116036.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116036.c
index a72209593f39..7b39291a91ad 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116036.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116036.c
@@ -8,4 +8,4 @@ void init() {
   a[i_0][i_1] = 1;
 }
 
-/* { dg-excess-errors "sorry, unimplemented: GCC's current 'V' implementation 
requires the 'M' extension" } */
+/* { dg-excess-errors "sorry, unimplemented: Currently the 'V' implementation 
requires the 'M' extension" } */


[gcc r15-2338] MAINTAINERS: Add myself to write after approval

2024-07-26 Thread Sam James via Gcc-cvs
https://gcc.gnu.org/g:7ad6b912d9ebd1f85afb725c8de05b27a97674ea

commit r15-2338-g7ad6b912d9ebd1f85afb725c8de05b27a97674ea
Author: Sam James 
Date:   Fri Jul 26 16:57:42 2024 +0100

MAINTAINERS: Add myself to write after approval

ChangeLog:

* MAINTAINERS: Add myself.

Diff:
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 542d058d727c..595140b6f64f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -550,6 +550,7 @@ Andreas Jaeger  aj  

 Harsha Jagasia  hjagasia
 Fariborz Jahanian   -   
 Martin Jambor   jamborm 
+Sam James   sjames  
 Surya Kumari Jangalajskumari
 Jakub Jelinek   jakub   
 Andrew Jenner   andrewjenner


[gcc r15-2339] PR116080: Fix tail call dejagnu checks

2024-07-26 Thread Andi Kleen via Gcc-cvs
https://gcc.gnu.org/g:ee41cd863b7c38ee3bc415ea7154954aa6facca3

commit r15-2339-gee41cd863b7c38ee3bc415ea7154954aa6facca3
Author: Andi Kleen 
Date:   Wed Jul 24 20:18:56 2024 -0700

PR116080: Fix tail call dejagnu checks

- Run the target_effective tail_call checks without optimization to
match the actual test cases.
- Add an extra check for external tail calls to handle targets like
powerpc that cannot tail call between different object files.
This one will also cover templates.

gcc/testsuite/ChangeLog:

PR testsuite/116080
* g++.dg/musttail10.C: Use external tail call target check.
* g++.dg/musttail6.C: Dito.
* lib/target-supports.exp: Add external_tail_call. Disable
optimization for tail call checks.

Diff:
---
 gcc/testsuite/g++.dg/musttail10.C |  2 +-
 gcc/testsuite/g++.dg/musttail6.C  |  2 +-
 gcc/testsuite/lib/target-supports.exp | 14 +++---
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/g++.dg/musttail10.C 
b/gcc/testsuite/g++.dg/musttail10.C
index ff7fcc7d8755..bd75affa2220 100644
--- a/gcc/testsuite/g++.dg/musttail10.C
+++ b/gcc/testsuite/g++.dg/musttail10.C
@@ -8,7 +8,7 @@ double g() { [[gnu::musttail]] return f(); } /* { dg-error 
"cannot tail-cal
 
 template 
 __attribute__((noinline, noclone, noipa))
-T g1() { [[gnu::musttail]] return f(); } /* { dg-error "target is not able" 
"" { target powerpc*-*-* } } */
+T g1() { [[gnu::musttail]] return f(); } /* { dg-error "target is not able" 
"" { target { external_tail_call } } } */
 
 template 
 __attribute__((noinline, noclone, noipa))
diff --git a/gcc/testsuite/g++.dg/musttail6.C b/gcc/testsuite/g++.dg/musttail6.C
index 5c6f69407ddb..81f6d9f3ca77 100644
--- a/gcc/testsuite/g++.dg/musttail6.C
+++ b/gcc/testsuite/g++.dg/musttail6.C
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { struct_tail_call } } } */
+/* { dg-require-effective-target external_tail_call } */
 /* A lot of architectures will not build this due to PR115606 and PR115607 */
-/* { dg-skip-if "powerpc does not support sibcall to templates" { powerpc*-*-* 
} } */
 /* { dg-options "-std=gnu++11" } */
 /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
 
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index d368251ef9a4..0a3946e82d4b 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12741,7 +12741,15 @@ proc check_effective_target_tail_call { } {
 return [check_no_messages_and_pattern tail_call ",SIBCALL" rtl-expand {
__attribute__((__noipa__)) void foo (void) { }
__attribute__((__noipa__)) void bar (void) { foo(); }
-} {-O2 -fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed 
dump.
+} {-fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed dump.
+}
+
+# Return 1 if the target can perform tail-calls for externals
+proc check_effective_target_external_tail_call { } {
+return [check_no_messages_and_pattern tail_call ",SIBCALL" rtl-expand {
+   extern __attribute__((__noipa__)) void foo (void);
+   __attribute__((__noipa__)) void bar (void) { foo(); }
+} {-fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed dump.
 }
 
 # Return 1 if the target can perform tail-call optimizations for structures
@@ -12751,9 +12759,9 @@ proc check_effective_target_struct_tail_call { } {
 return [check_no_messages_and_pattern tail_call ",SIBCALL" rtl-expand {
// C++
struct foo { int a, b; };
-   __attribute__((__noipa__)) struct foo foo (void) { return {}; }
+   extern __attribute__((__noipa__)) struct foo foo (void);
__attribute__((__noipa__)) struct foo bar (void) { return foo(); }
-} {-O2 -fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed 
dump.
+} {-fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed dump.
 }
 
 # Return 1 if the target's calling sequence or its ABI


[gcc r15-2340] PR116019: Improve tail call error message

2024-07-26 Thread Andi Kleen via Gcc-cvs
https://gcc.gnu.org/g:899ee4815424a73a2b9d899591fab3fcc4520b61

commit r15-2340-g899ee4815424a73a2b9d899591fab3fcc4520b61
Author: Andi Kleen 
Date:   Thu Jul 25 13:54:50 2024 -0700

PR116019: Improve tail call error message

The "tail call must be the same type" message is common on some
targets with C++, or without optimization. It is generated
when gcc believes there is an access of the return value
after the call. However usually it does not actually corespond
to a type mismatch, but can be caused for other reasons.

Make it slightly more vague to be less misleading.

gcc/ChangeLog:

PR c++/116019
* tree-tailcall.cc (find_tail_calls): Change tail call
error message.

Diff:
---
 gcc/tree-tailcall.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc
index a68079d4f507..1901b1a13f99 100644
--- a/gcc/tree-tailcall.cc
+++ b/gcc/tree-tailcall.cc
@@ -632,7 +632,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret, 
bool only_musttail,
   && may_be_aliased (result_decl)
   && ref_maybe_used_by_stmt_p (call, result_decl, false))
 {
-  maybe_error_musttail (call, _("tail call must be same type"));
+  maybe_error_musttail (call, _("return value used after call"));
   return;
 }


[gcc r15-2341] isel: Move duplicate comparisons to its own function

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:9e7b2ad4abae69e6348220b7c5ad2fb8e3d52c83

commit r15-2341-g9e7b2ad4abae69e6348220b7c5ad2fb8e3d52c83
Author: Andrew Pinski 
Date:   Thu Jul 25 16:17:15 2024 -0700

isel: Move duplicate comparisons to its own function

This is just a small cleanup to isel and no functional changes just.
The loop inside pass_gimple_isel::execute looked was getting too
deap so let's fix that by moving it to its own function.

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

gcc/ChangeLog:

* gimple-isel.cc (pass_gimple_isel::execute): Factor out
duplicate comparisons out to ...
(duplicate_comparison): New function.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/gimple-isel.cc | 66 +-
 1 file changed, 35 insertions(+), 31 deletions(-)

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index 57f7281bb508..327a78ea408e 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -395,6 +395,40 @@ gimple_expand_vec_cond_expr (struct function *fun, 
gimple_stmt_iterator *gsi,
 5, op0a, op0b, op1, op2, tcode_tree);
 }
 
+/* Duplicate COND_EXPR condition defs of STMT located in BB when they are
+   comparisons so RTL expansion with the help of TER
+   can perform better if conversion.  */
+static void
+duplicate_comparison (gassign *stmt, basic_block bb)
+{
+  imm_use_iterator imm_iter;
+  use_operand_p use_p;
+  auto_vec cond_exprs;
+  unsigned cnt = 0;
+  tree lhs = gimple_assign_lhs (stmt);
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
+{
+  if (is_gimple_debug (USE_STMT (use_p)))
+   continue;
+  cnt++;
+  if (gimple_bb (USE_STMT (use_p)) == bb
+ && is_gimple_assign (USE_STMT (use_p))
+ && gimple_assign_rhs1_ptr (USE_STMT (use_p)) == use_p->use
+ && gimple_assign_rhs_code (USE_STMT (use_p)) == COND_EXPR)
+   cond_exprs.safe_push (as_a  (USE_STMT (use_p)));
+  }
+  for (unsigned i = cond_exprs.length () == cnt ? 1 : 0;
+   i < cond_exprs.length (); ++i)
+{
+  gassign *copy = as_a  (gimple_copy (stmt));
+  tree new_def = duplicate_ssa_name (lhs, copy);
+  gimple_assign_set_lhs (copy, new_def);
+  auto gsi2 = gsi_for_stmt (cond_exprs[i]);
+  gsi_insert_before (&gsi2, copy, GSI_SAME_STMT);
+  gimple_assign_set_rhs1 (cond_exprs[i], new_def);
+  update_stmt (cond_exprs[i]);
+}
+}
 
 
 namespace {
@@ -469,37 +503,7 @@ pass_gimple_isel::execute (struct function *fun)
  tree lhs = gimple_assign_lhs (stmt);
  if (TREE_CODE_CLASS (code) == tcc_comparison
  && !has_single_use (lhs))
-   {
- /* Duplicate COND_EXPR condition defs when they are
-comparisons so RTL expansion with the help of TER
-can perform better if conversion.  */
- imm_use_iterator imm_iter;
- use_operand_p use_p;
- auto_vec cond_exprs;
- unsigned cnt = 0;
- FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
-   {
- if (is_gimple_debug (USE_STMT (use_p)))
-   continue;
- cnt++;
- if (gimple_bb (USE_STMT (use_p)) == bb
- && is_gimple_assign (USE_STMT (use_p))
- && gimple_assign_rhs1_ptr (USE_STMT (use_p)) == use_p->use
- && gimple_assign_rhs_code (USE_STMT (use_p)) == COND_EXPR)
-   cond_exprs.safe_push (as_a  (USE_STMT (use_p)));
-   }
- for (unsigned i = cond_exprs.length () == cnt ? 1 : 0;
-  i < cond_exprs.length (); ++i)
-   {
- gassign *copy = as_a  (gimple_copy (stmt));
- tree new_def = duplicate_ssa_name (lhs, copy);
- gimple_assign_set_lhs (copy, new_def);
- auto gsi2 = gsi_for_stmt (cond_exprs[i]);
- gsi_insert_before (&gsi2, copy, GSI_SAME_STMT);
- gimple_assign_set_rhs1 (cond_exprs[i], new_def);
- update_stmt (cond_exprs[i]);
-   }
-   }
+   duplicate_comparison (stmt, bb);
}
 }


[gcc r15-2342] isel: Small cleanup of duplicating comparisons

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:db74887097272a8390e33eba47c6fb8f50b64f5c

commit r15-2342-gdb74887097272a8390e33eba47c6fb8f50b64f5c
Author: Andrew Pinski 
Date:   Thu Jul 25 17:07:28 2024 -0700

isel: Small cleanup of duplicating comparisons

This is a small cleanup of the duplicating comparison code.
There is code generation difference but only for -O0 and -fno-tree-ter
(both of which will be fixed in a later patch).
The difference is instead of skipping the first use if the
comparison uses are only in cond_expr we skip the last use.
Also we go through the uses list in the opposite order now too.

The cleanups are the following:
* Don't call has_single_use as we will do the loop anyways
* Change the order of the checks slightly, it is better
  to check for cond_expr earlier
* Use cond_exprs as a stack and pop from it.
  Skipping the top if the use is only from cond_expr.

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

gcc/ChangeLog:

* gimple-isel.cc (duplicate_comparison): Rename to ...
(maybe_duplicate_comparison): This. Add check for use here
rather than in its caller.
(pass_gimple_isel::execute): Don't check how many uses the
comparison had and call maybe_duplicate_comparison instead of
duplicate_comparison.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/gimple-isel.cc | 38 --
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index 327a78ea408e..99bfc937bd55 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -399,34 +399,46 @@ gimple_expand_vec_cond_expr (struct function *fun, 
gimple_stmt_iterator *gsi,
comparisons so RTL expansion with the help of TER
can perform better if conversion.  */
 static void
-duplicate_comparison (gassign *stmt, basic_block bb)
+maybe_duplicate_comparison (gassign *stmt, basic_block bb)
 {
   imm_use_iterator imm_iter;
   use_operand_p use_p;
   auto_vec cond_exprs;
-  unsigned cnt = 0;
   tree lhs = gimple_assign_lhs (stmt);
+  unsigned cnt = 0;
+
   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
 {
   if (is_gimple_debug (USE_STMT (use_p)))
continue;
   cnt++;
+  /* Add the use statement if it was a cond_expr.  */
   if (gimple_bb (USE_STMT (use_p)) == bb
  && is_gimple_assign (USE_STMT (use_p))
- && gimple_assign_rhs1_ptr (USE_STMT (use_p)) == use_p->use
- && gimple_assign_rhs_code (USE_STMT (use_p)) == COND_EXPR)
+ && gimple_assign_rhs_code (USE_STMT (use_p)) == COND_EXPR
+ && gimple_assign_rhs1_ptr (USE_STMT (use_p)) == use_p->use)
cond_exprs.safe_push (as_a  (USE_STMT (use_p)));
-  }
-  for (unsigned i = cond_exprs.length () == cnt ? 1 : 0;
-   i < cond_exprs.length (); ++i)
+}
+
+  /* If the comparison has 0 or 1 uses, no reason to do anything. */
+  if (cnt <= 1)
+return;
+
+  /* If we only use the expression inside cond_exprs in that BB, we don't
+ need to duplicate for one of them so pop the top. */
+  if (cond_exprs.length () == cnt)
+cond_exprs.pop();
+
+  while (!cond_exprs.is_empty())
 {
+  auto old_top = cond_exprs.pop();
   gassign *copy = as_a  (gimple_copy (stmt));
   tree new_def = duplicate_ssa_name (lhs, copy);
   gimple_assign_set_lhs (copy, new_def);
-  auto gsi2 = gsi_for_stmt (cond_exprs[i]);
+  auto gsi2 = gsi_for_stmt (old_top);
   gsi_insert_before (&gsi2, copy, GSI_SAME_STMT);
-  gimple_assign_set_rhs1 (cond_exprs[i], new_def);
-  update_stmt (cond_exprs[i]);
+  gimple_assign_set_rhs1 (old_top, new_def);
+  update_stmt (old_top);
 }
 }
 
@@ -500,10 +512,8 @@ pass_gimple_isel::execute (struct function *fun)
continue;
 
  tree_code code = gimple_assign_rhs_code (stmt);
- tree lhs = gimple_assign_lhs (stmt);
- if (TREE_CODE_CLASS (code) == tcc_comparison
- && !has_single_use (lhs))
-   duplicate_comparison (stmt, bb);
+ if (TREE_CODE_CLASS (code) == tcc_comparison)
+   maybe_duplicate_comparison (stmt, bb);
}
 }


[gcc r15-2343] isel: Don't duplicate comparisons for -O0 nor -fno-tree-ter [PR116101]

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:9fe53beacfc5c01e24690dc70d7599db084cc8b4

commit r15-2343-g9fe53beacfc5c01e24690dc70d7599db084cc8b4
Author: Andrew Pinski 
Date:   Thu Jul 25 17:43:07 2024 -0700

isel: Don't duplicate comparisons for -O0 nor -fno-tree-ter [PR116101]

While doing cleanups on this code I noticed that we do the duplicate
of comparisons at -O0. For C and C++ code this makes no difference as
the gimplifier never produces COND_EXPR. But it could make a difference
for other front-ends.
Oh and for -fno-tree-ter, duplicating the comparison is just a waste
as it is never used for expand.

I also decided to add a few testcases so this is checked in the future.
Even added one for the duplication itself.

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

PR tree-optimization/116101

gcc/ChangeLog:

* gimple-isel.cc (maybe_duplicate_comparison): Don't
do anything for -O0 or -fno-tree-ter.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/dup_compare_cond-1.c: New test.
* gcc.dg/tree-ssa/dup_compare_cond-2.c: New test.
* gcc.dg/tree-ssa/dup_compare_cond-3.c: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/gimple-isel.cc |  5 +
 gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-1.c | 19 +++
 gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-2.c | 19 +++
 gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-3.c | 19 +++
 4 files changed, 62 insertions(+)

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index 99bfc937bd55..2817ab659af1 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -407,6 +407,11 @@ maybe_duplicate_comparison (gassign *stmt, basic_block bb)
   tree lhs = gimple_assign_lhs (stmt);
   unsigned cnt = 0;
 
+  /* This is should not be used for -O0 nor it is not useful
+ when ter is turned off. */
+  if (!optimize || !flag_tree_ter)
+return;
+
   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
 {
   if (is_gimple_debug (USE_STMT (use_p)))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-1.c
new file mode 100644
index ..0321a60b34f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O0 -fdump-tree-optimized " } */
+/* PR tree-optimization/116101 */
+
+int __GIMPLE() f(int a, int b, int c, int d, int e)
+{
+  _Bool t;
+  int ff;
+  int gg;
+  int res;
+  t = a == b;
+  ff = t ? a : e;
+  gg = t ? d : b;
+  res = ff+gg;
+  return res;
+}
+
+/* At -O0 we should not duplicate the comparison. */
+/* { dg-final { scan-tree-dump-times " == " 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-2.c
new file mode 100644
index ..07e2175c612e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O2 -fdump-tree-optimized " } */
+/* PR middle-end/105715 */
+
+int __GIMPLE() f(int a, int b, int c, int d, int e)
+{
+  _Bool t;
+  int ff;
+  int gg;
+  int res;
+  t = a == b;
+  ff = t ? a : e;
+  gg = t ? d : b;
+  res = ff+gg;
+  return res;
+}
+
+/* At -O2 we should have duplicate the comparison. */
+/* { dg-final { scan-tree-dump-times " == " 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-3.c 
b/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-3.c
new file mode 100644
index ..88bf19795e04
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dup_compare_cond-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O2 -fno-tree-ter -fdump-tree-optimized " } */
+/* PR tree-optimization/116101 */
+
+int __GIMPLE() f(int a, int b, int c, int d, int e)
+{
+  _Bool t;
+  int ff;
+  int gg;
+  int res;
+  t = a == b;
+  ff = t ? a : e;
+  gg = t ? d : b;
+  res = ff+gg;
+  return res;
+}
+
+/* With -fno-tree-ter it is not useful to duplicate the comparison. */
+/* { dg-final { scan-tree-dump-times " == " 1 "optimized" } } */


[gcc r15-2344] aarch64: Fix target/optimize option handling with transiting between O1 to O2

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:8a5f528fba788f2af40a15a999bb63a2a0f6f455

commit r15-2344-g8a5f528fba788f2af40a15a999bb63a2a0f6f455
Author: Andrew Pinski 
Date:   Thu Jul 25 09:37:49 2024 -0700

aarch64: Fix target/optimize option handling with transiting between O1 to 
O2

The problem here is the aarch64 backend enables -mearly-ra at -O2 and above 
but
it is not marked as an Optimization in the .opt file so enabling it 
sometimes
reset the target options when going from -O1 to -O2 for the first time.

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

PR target/116065

gcc/ChangeLog:

* config/aarch64/aarch64.opt (mearly-ra=): Mark as Optimization 
rather
than Save.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/sve/target_optimization-1.c: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/config/aarch64/aarch64.opt   |  2 +-
 .../gcc.target/aarch64/sve/target_optimization-1.c   | 16 
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 2f90f10352af..6229bcb371e3 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -256,7 +256,7 @@ EnumValue
 Enum(early_ra_scope) String(none) Value(AARCH64_EARLY_RA_NONE)
 
 mearly-ra=
-Target RejectNegative Joined Enum(early_ra_scope) Var(aarch64_early_ra) 
Init(AARCH64_EARLY_RA_NONE) Save
+Target RejectNegative Joined Enum(early_ra_scope) Var(aarch64_early_ra) 
Init(AARCH64_EARLY_RA_NONE) Optimization
 Specify when to enable an early register allocation pass.  The possibilities
 are: all functions, functions that have access to strided multi-register
 instructions, and no functions.
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/target_optimization-1.c 
b/gcc/testsuite/gcc.target/aarch64/sve/target_optimization-1.c
new file mode 100644
index ..3010f0c4189d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/target_optimization-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include 
+
+/* Turn off SVE overall */
+#pragma GCC target("+nosve")
+
+/* But the function turns it on again so it should work.
+   Even if changing the optimization level from O1 to O2. */
+int __attribute__((target ("+sve"), optimize(2)))
+bar (void)
+{
+  svfloat32_t xseg;
+  return svlen_f32(xseg);
+}


[gcc r15-2345] aarch64: Rename bic/orn patterns to iorn/andn for vector modes

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:245187de498887072c20d4d9fa55491b3e947cdf

commit r15-2345-g245187de498887072c20d4d9fa55491b3e947cdf
Author: Andrew Pinski 
Date:   Mon Jul 22 11:19:11 2024 -0700

aarch64: Rename bic/orn patterns to iorn/andn for vector modes

This renames the patterns orn3 to iorn3 so it
matches the new optab that was added with r15-1890-gf379596e0ba99d.
Likewise for bic3 to andn3.

Note the operand 1 and operand 2 are swapped from the original
patterns to match the optab now.

Built and tested for aarch64-linux-gnu with no regression.

gcc/ChangeLog:

* config/aarch64/aarch64-simd.md
(bic3): Rename to ...
(andn3): This. Also swap operands.
(orn3): Rename to ...
(iorn3): This. Also swap operands.
(vec_cmp): Update orn call to iorn
and swap the last two arguments.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/vect_cmp-1.C: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/config/aarch64/aarch64-simd.md| 20 +++
 gcc/testsuite/g++.target/aarch64/vect_cmp-1.C | 37 +++
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index bbeee221f37c..459e11b09a19 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -322,21 +322,21 @@
   [(set_attr "length" "4")]
 )
 
-(define_insn "orn3"
+(define_insn "iorn3"
  [(set (match_operand:VDQ_I 0 "register_operand" "=w")
-   (ior:VDQ_I (not:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w"))
-   (match_operand:VDQ_I 2 "register_operand" "w")))]
+   (ior:VDQ_I (not:VDQ_I (match_operand:VDQ_I 2 "register_operand" "w"))
+   (match_operand:VDQ_I 1 "register_operand" "w")))]
  "TARGET_SIMD"
- "orn\t%0., %2., %1."
+ "orn\t%0., %1., %2."
   [(set_attr "type" "neon_logic")]
 )
 
-(define_insn "bic3"
+(define_insn "andn3"
  [(set (match_operand:VDQ_I 0 "register_operand" "=w")
-   (and:VDQ_I (not:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w"))
-   (match_operand:VDQ_I 2 "register_operand" "w")))]
+   (and:VDQ_I (not:VDQ_I (match_operand:VDQ_I 2 "register_operand" "w"))
+   (match_operand:VDQ_I 1 "register_operand" "w")))]
  "TARGET_SIMD"
- "bic\t%0., %2., %1."
+ "bic\t%0., %1., %2."
   [(set_attr "type" "neon_logic")]
 )
 
@@ -4064,7 +4064,7 @@
   tmp0, mode),
   lowpart_subreg (mode,
   tmp1, mode)));
-   emit_insn (gen_orn3 (operands[0], tmp2, operands[0]));
+   emit_insn (gen_iorn3 (operands[0], operands[0], tmp2));
   }
   break;
 
@@ -4111,7 +4111,7 @@
   else if (code == UNEQ)
{
  emit_insn (gen_aarch64_cmeq (tmp, operands[2], operands[3]));
- emit_insn (gen_orn3 (operands[0], operands[0], tmp));
+ emit_insn (gen_iorn3 (operands[0], tmp, operands[0]));
}
   break;
 
diff --git a/gcc/testsuite/g++.target/aarch64/vect_cmp-1.C 
b/gcc/testsuite/g++.target/aarch64/vect_cmp-1.C
new file mode 100644
index ..b82d87827d30
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/vect_cmp-1.C
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+#pragma GCC target "+nosve"
+
+#define vect8 __attribute__((vector_size(8) ))
+
+/**
+**bar1:
+** fcmgt   v([0-9]+).2s, v[0-9]+.2s, v[0-9]+.2s
+** bic v0.8b, v2.8b, v\1.8b
+** ret
+*/
+extern "C"
+vect8 int bar1(vect8 float a, vect8 float b, vect8 int c)
+{
+  return (a > b) ? 0 : c;
+}
+
+/**
+**bar2:
+** fcmgt   v([0-9]+).2s, v[0-9]+.2s, v[0-9]+.2s
+** orn v0.8b, v2.8b, v\1.8b
+** ret
+*/
+extern "C"
+vect8 int bar2(vect8 float a, vect8 float b, vect8 int c)
+{
+  return (a > b) ? c : -1;
+}
+
+// We should produce a BIT_ANDC and BIT_IORC here.
+
+// { dg-final { scan-tree-dump ".BIT_ANDN " "optimized" } }
+// { dg-final { scan-tree-dump ".BIT_IORN " "optimized" } }
+


[gcc r15-2347] aarch64: sve: Rename aarch64_bic to standard pattern, andn

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:795021d9bc8546ccc51bacc899b6077c6928067b

commit r15-2347-g795021d9bc8546ccc51bacc899b6077c6928067b
Author: Andrew Pinski 
Date:   Mon Jul 22 15:39:37 2024 -0700

aarch64: sve: Rename aarch64_bic to standard pattern, andn

Now there is an optab for bic, andn since r15-1890-gf379596e0ba99d.
This moves aarch64_bic for sve over to use it instead.

Note unlike the simd bic patterns, the operands were already
in the order that was expected for the optab so no swapping
was needed.

Built and tested on aarch64-linux-gnu with no regressions.

gcc/ChangeLog:

* config/aarch64/aarch64-sve-builtins-base.cc (svbic_impl::expand): 
Update
to use andn optab instead of using code_for_aarch64_bic.
* config/aarch64/aarch64-sve.md (@aarch64_bic): Rename to ...
(andn3): This.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/config/aarch64/aarch64-sve-builtins-base.cc | 2 +-
 gcc/config/aarch64/aarch64-sve.md   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc 
b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index aa26370d397f..a2268353ae31 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -271,7 +271,7 @@ public:
   }
 
 if (e.pred == PRED_x)
-  return e.use_unpred_insn (code_for_aarch64_bic (e.vector_mode (0)));
+  return e.use_unpred_insn (e.direct_optab_handler (andn_optab));
 
 return e.use_cond_insn (code_for_cond_bic (e.vector_mode (0)));
   }
diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index 5331e7121d55..c3ed5075c4ed 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -4641,8 +4641,8 @@
 ;; - BIC
 ;; -
 
-;; Unpredicated BIC.
-(define_expand "@aarch64_bic"
+;; Unpredicated BIC; andn named pattern.
+(define_expand "andn3"
   [(set (match_operand:SVE_I 0 "register_operand")
(and:SVE_I
  (unspec:SVE_I


[gcc r15-2346] aarch64: Use iorn and andn standard pattern names for scalar modes

2024-07-26 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:7e8e8a745a0f3389c2ef7de5798932f5ac0f8c9d

commit r15-2346-g7e8e8a745a0f3389c2ef7de5798932f5ac0f8c9d
Author: Andrew Pinski 
Date:   Mon Jul 22 16:18:47 2024 -0700

aarch64: Use iorn and andn standard pattern names for scalar modes

Since r15-1890-gf379596e0ba99d, these are the new optabs.
So let's use these names for them. These will be used to
generate during expand from gimple in the next few patches.

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

gcc/ChangeLog:

* config/aarch64/aarch64.md (*_one_cmpl3): 
Rename to ...
(n3): This.
(*_one_cmplsidi3_ze): Rename to ...
(*nsidi3_ze): This.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/config/aarch64/aarch64.md | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 94ff0eefa77f..ed29127dafbe 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5069,18 +5069,18 @@
 
 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
 
-(define_insn "*_one_cmpl3"
+(define_insn "n3"
   [(set (match_operand:GPI 0 "register_operand")
-   (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand"))
-(match_operand:GPI 2 "register_operand")))]
+   (NLOGICAL:GPI (not:GPI (match_operand:GPI 2 "register_operand"))
+(match_operand:GPI 1 "register_operand")))]
   ""
   {@ [ cons: =0 , 1 , 2 ; attrs: type , arch  ]
- [ r, r , r ; logic_reg   , * ] \t%0, 
%2, %1
- [ w, w , w ; neon_logic  , simd  ] 
\t%0., %2., %1.
+ [ r, r , r ; logic_reg   , * ] \t%0, 
%1, %2
+ [ w, w , w ; neon_logic  , simd  ] 
\t%0., %1., %2.
   }
 )
 
-(define_insn "*_one_cmplsidi3_ze"
+(define_insn "*nsidi3_ze"
   [(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
  (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))


[gcc r15-2348] gimple-ssa-sprintf: Fix typo in range check

2024-07-26 Thread Siddhesh Poyarekar via Gcc-cvs
https://gcc.gnu.org/g:6fe1e1fad120350b9a392a7afb728d8418e79110

commit r15-2348-g6fe1e1fad120350b9a392a7afb728d8418e79110
Author: Siddhesh Poyarekar 
Date:   Thu Jul 25 19:30:38 2024 -0400

gimple-ssa-sprintf: Fix typo in range check

The code to scale ranges for wide chars in format_string incorrectly
checks range.likely to scale range.unlikely, which is a copy-paste typo
from the immediate previous condition.

gcc/ChangeLog:

* gimple-ssa-sprintf.cc (format_string): Fix type in range check
for UNLIKELY for wide chars.

Signed-off-by: Siddhesh Poyarekar 

Diff:
---
 gcc/gimple-ssa-sprintf.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
index 025b0fbff6f9..0900710647c4 100644
--- a/gcc/gimple-ssa-sprintf.cc
+++ b/gcc/gimple-ssa-sprintf.cc
@@ -2623,7 +2623,7 @@ format_string (const directive &dir, tree arg, 
pointer_query &ptr_qry)
  if (slen.range.likely < target_int_max ())
slen.range.likely *= 2;
 
- if (slen.range.likely < target_int_max ())
+ if (slen.range.unlikely < target_int_max ())
slen.range.unlikely *= target_mb_len_max ();
 
  /* A non-empty wide character conversion may fail.  */


[gcc r15-2349] testsuite: Add dg-do run to even more tests

2024-07-26 Thread Sam James via Gcc-cvs
https://gcc.gnu.org/g:a75c6295252d0d998a18927dc7510fac965134c4

commit r15-2349-ga75c6295252d0d998a18927dc7510fac965134c4
Author: Sam James 
Date:   Thu Jul 18 08:27:29 2024 +0100

testsuite: Add dg-do run to even more tests

All of these are for wrong-code bugs. Confirmed to be used before but
with no execution.

Tested on x86_64-pc-linux-gnu and checked test logs before/after.

2024-07-26  Sam James  

PR target/7559
PR c++/9704
PR c++/16115
PR c++/19317
PR rtl-optimization/11536
PR target/20322
PR tree-optimization/31966
PR rtl-optimization/41033
PR tree-optimization/67947
* g++.dg/cpp1z/byte1.C: Add dg-do run directive.
* g++.dg/init/call1.C: Ditto.
* g++.dg/init/copy5.C: Ditto.
* g++.dg/opt/nrv9.C: Ditto.
* gcc.dg/20021006-1.c: Ditto.
* gcc.dg/20030721-1.c: Ditto.
* gcc.dg/20050307-1.c: Ditto.
* gcc.dg/pr41033.c: Ditto.
* gcc.dg/torture/pr67947.c: Ditto.
* gcc.dg/tree-ssa/pr31966.c: Ditto.
* gcc.dg/tree-ssa/tailcall-3.c: Ditto.
* gcc.dg/tree-ssa/vrp74.c: Ditto.
* gcc.target/nvptx/abort.c: Fix whitespace in dg directive.

Diff:
---
 gcc/testsuite/g++.dg/cpp1z/byte1.C | 2 +-
 gcc/testsuite/g++.dg/init/call1.C  | 1 +
 gcc/testsuite/g++.dg/init/copy5.C  | 1 +
 gcc/testsuite/g++.dg/opt/nrv9.C| 1 +
 gcc/testsuite/gcc.dg/20021006-1.c  | 1 +
 gcc/testsuite/gcc.dg/20030721-1.c  | 3 ++-
 gcc/testsuite/gcc.dg/20050307-1.c  | 1 +
 gcc/testsuite/gcc.dg/pr41033.c | 3 ++-
 gcc/testsuite/gcc.dg/torture/pr67947.c | 1 +
 gcc/testsuite/gcc.dg/tree-ssa/pr31966.c| 1 +
 gcc/testsuite/gcc.dg/tree-ssa/tailcall-3.c | 2 +-
 gcc/testsuite/gcc.dg/tree-ssa/vrp74.c  | 1 +
 gcc/testsuite/gcc.target/nvptx/abort.c | 2 +-
 13 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/g++.dg/cpp1z/byte1.C 
b/gcc/testsuite/g++.dg/cpp1z/byte1.C
index 631b18d126c6..e4e3b6e95ac9 100644
--- a/gcc/testsuite/g++.dg/cpp1z/byte1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/byte1.C
@@ -1,5 +1,5 @@
 // Test for std::byte aliasing properties.
-// { dg-do compile { target c++17 } }
+// { dg-do run { target c++17 } }
 // { dg-options "-O3" }
 
 #include 
diff --git a/gcc/testsuite/g++.dg/init/call1.C 
b/gcc/testsuite/g++.dg/init/call1.C
index d44b6dddc953..548d59cc80f4 100644
--- a/gcc/testsuite/g++.dg/init/call1.C
+++ b/gcc/testsuite/g++.dg/init/call1.C
@@ -1,4 +1,5 @@
 // Bug c++/16115
+// { dg-do run }
 // { dg-options "-O2" }
 
 extern "C" void abort(); 
diff --git a/gcc/testsuite/g++.dg/init/copy5.C 
b/gcc/testsuite/g++.dg/init/copy5.C
index cef5a2950ef1..26e3bf81d83f 100644
--- a/gcc/testsuite/g++.dg/init/copy5.C
+++ b/gcc/testsuite/g++.dg/init/copy5.C
@@ -1,3 +1,4 @@
+// { dg-do run }
 // { dg-options "-O2" }
 
 struct BOOL {
diff --git a/gcc/testsuite/g++.dg/opt/nrv9.C b/gcc/testsuite/g++.dg/opt/nrv9.C
index 462506867d43..08bcde8827dd 100644
--- a/gcc/testsuite/g++.dg/opt/nrv9.C
+++ b/gcc/testsuite/g++.dg/opt/nrv9.C
@@ -1,4 +1,5 @@
 // PR c++/19317
+// { dg-do run }
 // If we do both NRV and caller-side return slot opt for ga = f()
 // constructing la sets ga.i to 0 too soon.
 
diff --git a/gcc/testsuite/gcc.dg/20021006-1.c 
b/gcc/testsuite/gcc.dg/20021006-1.c
index 92df2c57f6ef..7904b9f99626 100644
--- a/gcc/testsuite/gcc.dg/20021006-1.c
+++ b/gcc/testsuite/gcc.dg/20021006-1.c
@@ -1,6 +1,7 @@
 /* PR target/7559
This testcase was miscompiled on x86-64 due to wrong access to the struct
members.  */
+/* { dg-do run } */
 
 extern void abort(void);
 
diff --git a/gcc/testsuite/gcc.dg/20030721-1.c 
b/gcc/testsuite/gcc.dg/20030721-1.c
index 5e8ed0b434ad..52be42fc59df 100644
--- a/gcc/testsuite/gcc.dg/20030721-1.c
+++ b/gcc/testsuite/gcc.dg/20030721-1.c
@@ -1,5 +1,6 @@
-/* { dg-options "-O2" } */
 /* PR optimization/11536 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
 /* Origin: sa...@kam.mff.cuni.cz  */
 /* Testcase by Andrew Pinski  */
 
diff --git a/gcc/testsuite/gcc.dg/20050307-1.c 
b/gcc/testsuite/gcc.dg/20050307-1.c
index 0e8dac69a65f..b370a571acac 100644
--- a/gcc/testsuite/gcc.dg/20050307-1.c
+++ b/gcc/testsuite/gcc.dg/20050307-1.c
@@ -1,4 +1,5 @@
 /* PR target/20322 */
+/* { dg-do run } */
 
 extern void abort (void);
 
diff --git a/gcc/testsuite/gcc.dg/pr41033.c b/gcc/testsuite/gcc.dg/pr41033.c
index 5043be2d1191..4c1863c750aa 100644
--- a/gcc/testsuite/gcc.dg/pr41033.c
+++ b/gcc/testsuite/gcc.dg/pr41033.c
@@ -1,5 +1,6 @@
-/* { dg-options "-O1 -fno-strict-aliasing" } */
 /* PR rtl-optimization/41033 */
+/* { dg-do run } */
+/* { dg-options "-O1 -fno-strict-aliasing" } */
 
 struct X {
   int i;
diff --git a/gcc/testsuite/gcc.dg/torture/pr67947.c 
b/gcc/testsuite/gcc.dg/torture/pr67947.c
index 5664c48390af..368a8b20cbf0 100644
--- a/gcc/

[gcc r15-2350] testsuite: Fix up ucn-1.C for C++26

2024-07-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:2fb5bbe5ee9c148cd7d1068b18be66cc52054812

commit r15-2350-g2fb5bbe5ee9c148cd7d1068b18be66cc52054812
Author: Jakub Jelinek 
Date:   Fri Jul 26 21:01:03 2024 +0200

testsuite: Fix up ucn-1.C for C++26

On Fri, Jul 26, 2024 at 11:43:13AM -0400, Jason Merrill wrote:
> I'm now seeing a -std=c++26 failure on g++.dg/cpp/ucn-1.C.

I don't remember seeing it when I wrote the patch, but today I see it as
well.

2024-07-26  Jakub Jelinek  

* g++.dg/cpp/ucn-1.C (main): Expect error on c\u0024c identifier 
also
for C++26.

Diff:
---
 gcc/testsuite/g++.dg/cpp/ucn-1.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/cpp/ucn-1.C b/gcc/testsuite/g++.dg/cpp/ucn-1.C
index 9596a4296505..8277d2effd52 100644
--- a/gcc/testsuite/g++.dg/cpp/ucn-1.C
+++ b/gcc/testsuite/g++.dg/cpp/ucn-1.C
@@ -9,7 +9,7 @@ int main()
 
   int c\u0041c;// { dg-error "not valid in an identifier" }
// $ is OK on most targets; not part of basic source char set
-  int c\u0024c;// { dg-error "not valid in an identifier" "" { target 
{ powerpc-ibm-aix* } } }
+  int c\u0024c;// { dg-error "not valid in an identifier" "" { target 
{ { powerpc-ibm-aix* } || c++26 } } }
 
   U"\uD800"; // { dg-error "not a valid universal character" }


[gcc r15-2351] c++: trait as typename scope [PR116052]

2024-07-26 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:ea381d87ecc711d0003ae6841477ae8000894844

commit r15-2351-gea381d87ecc711d0003ae6841477ae8000894844
Author: Jason Merrill 
Date:   Thu Jul 25 23:09:31 2024 -0400

c++: trait as typename scope [PR116052]

The stdexec library currently wrongly ends up using __decay as the scope of
a typename, which leads to a crash.  Let's give an error instead.

PR c++/116052

gcc/cp/ChangeLog:

* mangle.cc (write_prefix): Handle TRAIT_EXPR.

gcc/testsuite/ChangeLog:

* g++.dg/ext/decay1.C: New test.

Diff:
---
 gcc/cp/mangle.cc  |  3 ++-
 gcc/testsuite/g++.dg/ext/decay1.C | 16 
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index a04bc584586f..e73912202344 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -1300,7 +1300,8 @@ write_prefix (const tree node)
 
   MANGLE_TRACE_TREE ("prefix", node);
 
-  if (TREE_CODE (node) == DECLTYPE_TYPE)
+  if (TREE_CODE (node) == DECLTYPE_TYPE
+  || TREE_CODE (node) == TRAIT_TYPE)
 {
   write_type (node);
   return;
diff --git a/gcc/testsuite/g++.dg/ext/decay1.C 
b/gcc/testsuite/g++.dg/ext/decay1.C
new file mode 100644
index ..dd457ba307cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/decay1.C
@@ -0,0 +1,16 @@
+// PR c++/116052
+// { dg-do compile { target c++11 } }
+
+template  using decay_t = __decay(T);
+template  void g(typename decay_t::foo); // { dg-error "built-in" }
+template  void f()
+{
+  g(0);
+}
+
+struct A { using foo = int; };
+
+int main()
+{
+  f();
+}


[gcc r15-2352] [RISC-V][target/116085] Fix rv64 minmax extension avoidance splitter

2024-07-26 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:6e5aae47e3b910f9af6983f744d7a3e2dcecba1d

commit r15-2352-g6e5aae47e3b910f9af6983f744d7a3e2dcecba1d
Author: Jeff Law 
Date:   Fri Jul 26 17:30:08 2024 -0600

[RISC-V][target/116085] Fix rv64 minmax extension avoidance splitter

A patch introduced a pattern to avoid unnecessary extensions when doing a
min/max operation where one of the values is a 32 bit positive constant.

> (define_insn_and_split "*minmax"
>   [(set (match_operand:DI 0 "register_operand" "=r")
> (sign_extend:DI
>   (subreg:SI
> (bitmanip_minmax:DI (zero_extend:DI (match_operand:SI 1 
"register_operand" "r"))
> (match_operand:DI 2 
"immediate_operand" "i"))
>0)))
>(clobber (match_scratch:DI 3 "=&r"))
>(clobber (match_scratch:DI 4 "=&r"))]
>   "TARGET_64BIT && TARGET_ZBB && sext_hwi (INTVAL (operands[2]), 32) >= 0"
>   "#"
>   "&& reload_completed"
>   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
>(set (match_dup 4) (match_dup 2))
>(set (match_dup 0) (:DI (match_dup 3) (match_dup 4)))]

Lots going on in here.  The key is the nonconstant value is zero extended 
from
SI to DI in the original RTL and we know the constant value is unchanged if 
we
were to sign extend it from 32 to 64 bits.

We change the extension of the nonconstant operand from zero to sign 
extension.
I'm pretty confident the goal there is take advantage of the fact that SI
values are kept sign extended and will often be optimized away.

The problem occurs when the nonconstant operand has the SI sign bit set.  
As an
example:

smax (0x800, 0x7)  resulting in 0x8000

The split RTL will generate
smax (sign_extend (0x8000), 0x7))

smax (0x8000, 0x7) resulting in 0x7

Opps.

We really needed to change the opcode to umax for this transformation to 
work.
That's easy enough.  But there's further improvements we can make.

First the pattern is a define_and_split with a post-reload split condition. 
 It
would be better implemented as a 4->3 define_split so that the costing model
just works.  Second, if operands[1] is a suitably promoted subreg, then we 
can
elide the sign extension when we generate the split code, so often it'll be 
a
4->2 split, again with the cost model working with no adjustments needed.

Tested on rv32 and rv64 in my tester.  I'll wait for the pre-commit tester 
to
spin it as well.

PR target/116085
gcc/
* config/riscv/bitmanip.md (minmax extension avoidance splitter):
Rewrite as a simpler define_split.  Adjust the opcode appropriately.
Avoid emitting sign extension if it's clearly not needed.
* config/riscv/iterators.md (minmax_optab): Rename to uminmax_optab
and map everything to unsigned variants.

gcc/testsuite/
* gcc.target/riscv/pr116085.c: New test.

Diff:
---
 gcc/config/riscv/bitmanip.md  | 38 +++
 gcc/config/riscv/iterators.md |  9 
 gcc/testsuite/gcc.target/riscv/pr116085.c | 29 +++
 3 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 9fc5215d6e35..b19295cd9424 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -549,23 +549,33 @@
 
 ;; Optimize the common case of a SImode min/max against a constant
 ;; that is safe both for sign- and zero-extension.
-(define_insn_and_split "*minmax"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+(define_split
+  [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
  (subreg:SI
-   (bitmanip_minmax:DI (zero_extend:DI (match_operand:SI 1 
"register_operand" "r"))
-   (match_operand:DI 2 
"immediate_operand" "i"))
-  0)))
-   (clobber (match_scratch:DI 3 "=&r"))
-   (clobber (match_scratch:DI 4 "=&r"))]
+   (bitmanip_minmax:DI (zero_extend:DI
+ (match_operand:SI 1 "register_operand"))
+   (match_operand:DI 2 "immediate_operand")) 0)))
+   (clobber (match_operand:DI 3 "register_operand"))
+   (clobber (match_operand:DI 4 "register_operand"))]
   "TARGET_64BIT && TARGET_ZBB && sext_hwi (INTVAL (operands[2]), 32) >= 0"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
-   (set (match_dup 4) (match_dup 2))
-   (set (match_dup 0) (:DI (match_dup 3) (match_dup 4)))]
-  ""
-  [(set_attr "type" "bitmanip")])
+  [(set (match_dup 0) (:DI (match_dup 4) (match_dup 3)))]
+  "
+{
+  /* Load the constant into a register.  */
+  emit_move_insn (operands[3], operands[2]);
+
+  /* If operands[1] is a sign

[gcc r15-2354] diagnostics: SARIF output: capture #include information (PR 107941; §3.34)

2024-07-26 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:4d1f71d49e396cb879d43dc96dc591079af66bbe

commit r15-2354-g4d1f71d49e396cb879d43dc96dc591079af66bbe
Author: David Malcolm 
Date:   Fri Jul 26 20:37:31 2024 -0400

diagnostics: SARIF output: capture #include information (PR 107941; §3.34)

This patch extends our SARIF output to capture relationships between
locations within a result (§3.34).  In particular, this captures
chains of #includes relating to diagnostics and to events within
diagnostic paths.

For example, consider:

include-chain-1.c:

  #include "include-chain-1.h"

include-chain-1.h:

  /* First set of decls, which will be referenced in notes.  */
  #include "include-chain-1-1.h"

  /* Second set of decls, which will trigger the errors.  */
  #include "include-chain-1-2.h"

include-chain-1-1.h:

  int p;
  int q;

include-chain-1-1.h:

  char p;
  char q;

GCC's textual output emits:

  In file included from PATH/include-chain-1.h:5,
   from PATH/include-chain-1.c:30:
  PATH/include-chain-1-2.h:1:6: error: conflicting types for 'p'; have 
'char'
  1 | char p;
|  ^
  In file included from PATH/include-chain-1.h:2:
  PATH/include-chain-1-1.h:1:5: note: previous declaration of 'p' with type 
'int'
  1 | int p;
| ^
  PATH/include-chain-1-2.h:2:6: error: conflicting types for 'q'; have 
'char'
  2 | char q;
|  ^
  PATH/include-chain-1-1.h:2:5: note: previous declaration of 'q' with type 
'int'
  2 | int q;
| ^

With this patch, the SARIF output captures the include information for
the two results, so that e.g. result[0]'s location[0] has:

  "relationships": [{"target": 0,
 "kinds": ["isIncludedBy"]}],
  "id": 0

and the "note" in relatedLocations[0] has:

  "message": {"text": "previous declaration of 'q' with type 'int'"},
  "relationships": [{"target": 2,
"kinds": ["isIncludedBy"]}],
  "id": 2},

where these reference new locations within relatedLocations, such as this 
for
the "#include "include-chain-1-1.h" line in include-chain-1.h:

  {"physicalLocation": {"artifactLocation": {"uri": include-chain-1.h",
 "uriBaseId": "PWD"},
"region": {"startLine": 5},
"contextRegion": {"startLine": 5,
  "snippet": {"text": "#include 
\"include-chain-1-2.h\"\n"}}},
   "id": 1,
   "relationships": [{"target": 0,
  "kinds": ["includes"]},
 {"target": 4,
  "kinds": ["isIncludedBy"]}]},

effectively capturing the inclusion digraph in SARIF form:

 +---+ +--+
 |"id": 0| |"id": 2   |
 | error: "conflicting types for 'p';| | note: previous declaration of 'p'|
 |  have 'char'"|| | with type 'int'")|
 | in include-chain-1-2.h| | in include-chain-1-1.h   |
 +---+ +--+
   |  |
   | included-by  | included-by
   V  V
  ++++
  |"id": 1 ||"id": 3 |
  | #include "include-chain-1-2.h" || #include "include-chain-1-1.h" |
  | in include-chain-1.h   || in include-chain-1.h   |
  ++++
 |  |
 | included-by  | included-by
 V  V
  ++
  |"id": 4 |
  | The  #include "include-chain-1.h"  |
  | in include-chain-1.c   |
  ++

Locations only gain "id" fields if they need one, and the precise
numbering of the IDs within a result is an implementation detail (the
order in which references to the locations are made).

To test all this non-trivial JSON from DejaGnu I needed to adapt the
python testing code used by gcov, adding a new run-sarif-pytest based
on run-gcov-pytest.

gcc/ChangeLog:
PR middle-end/107941
* diagno

[gcc r15-2355] Match: Support .SAT_SUB with IMM op for form 1-4

2024-07-26 Thread Pan Li via Gcc-cvs
https://gcc.gnu.org/g:6d79d53eed82b1df378998bd4ced88644dcde200

commit r15-2355-g6d79d53eed82b1df378998bd4ced88644dcde200
Author: Pan Li 
Date:   Fri Jul 26 17:00:13 2024 +0800

Match: Support .SAT_SUB with IMM op for form 1-4

This patch would like to support .SAT_SUB when one of the op
is IMM.  Aka below 1-4 forms.

Form 1:
 #define DEF_SAT_U_SUB_IMM_FMT_1(T, IMM) \
 T __attribute__((noinline)) \
 sat_u_sub_imm##IMM##_##T##_fmt_1 (T y)  \
 {   \
   return IMM >= y ? IMM - y : 0;\
 }

Form 2:
  #define DEF_SAT_U_SUB_IMM_FMT_2(T, IMM) \
  T __attribute__((noinline)) \
  sat_u_sub_imm##IMM##_##T##_fmt_2 (T y)  \
  {   \
return IMM > y ? IMM - y : 0; \
  }

Form 3:
  #define DEF_SAT_U_SUB_IMM_FMT_3(T, IMM) \
  T __attribute__((noinline)) \
  sat_u_sub_imm##IMM##_##T##_fmt_3 (T x)  \
  {   \
return x >= IMM ? x - IMM : 0;\
  }

Form 4:
  #define DEF_SAT_U_SUB_IMM_FMT_4(T, IMM) \
  T __attribute__((noinline)) \
  sat_u_sub_imm##IMM##_##T##_fmt_4 (T x)  \
  {   \
return x > IMM ? x - IMM : 0; \
  }

Take below form 1 as example:

DEF_SAT_U_SUB_OP0_IMM_FMT_1(uint32_t, 11)

Before this patch:
   4   │ __attribute__((noinline))
   5   │ uint64_t sat_u_sub_imm11_uint64_t_fmt_1 (uint64_t y)
   6   │ {
   7   │   uint64_t _1;
   8   │   uint64_t _3;
   9   │
  10   │ ;;   basic block 2, loop depth 0
  11   │ ;;pred:   ENTRY
  12   │   if (y_2(D) <= 11)
  13   │ goto ; [50.00%]
  14   │   else
  15   │ goto ; [50.00%]
  16   │ ;;succ:   3
  17   │ ;;4
  18   │
  19   │ ;;   basic block 3, loop depth 0
  20   │ ;;pred:   2
  21   │   _3 = 11 - y_2(D);
  22   │ ;;succ:   4
  23   │
  24   │ ;;   basic block 4, loop depth 0
  25   │ ;;pred:   2
  26   │ ;;3
  27   │   # _1 = PHI <0(2), _3(3)>
  28   │   return _1;
  29   │ ;;succ:   EXIT
  30   │
  31   │ }

After this patch:
   4   │ __attribute__((noinline))
   5   │ uint64_t sat_u_sub_imm11_uint64_t_fmt_1 (uint64_t y)
   6   │ {
   7   │   uint64_t _1;
   8   │
   9   │ ;;   basic block 2, loop depth 0
  10   │ ;;pred:   ENTRY
  11   │   _1 = .SAT_SUB (11, y_2(D)); [tail call]
  12   │   return _1;
  13   │ ;;succ:   EXIT
  14   │
  15   │ }

The below test suites are passed for this patch:
1. The rv64gcv fully regression tests.
2. The x86 bootstrap tests.
3. The x86 fully regression tests.

gcc/ChangeLog:

* match.pd: Add case 9 and case 10 for .SAT_SUB when one
of the op is IMM.

Signed-off-by: Pan Li 

Diff:
---
 gcc/match.pd | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index cf359b0ec0f0..b2e7d61790df 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3234,6 +3234,41 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
   && types_match (type, @0, @1
 
+/* Unsigned saturation sub with op_0 imm, case 9 (branch with gt):
+   SAT_U_SUB = IMM > Y  ? (IMM - Y) : 0.
+ = IMM >= Y ? (IMM - Y) : 0.  */
+(match (unsigned_integer_sat_sub @0 @1)
+ (cond^ (le @1 INTEGER_CST@2) (minus INTEGER_CST@0 @1) integer_zerop)
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+ && types_match (type, @1))
+ (with
+  {
+   unsigned precision = TYPE_PRECISION (type);
+   wide_int max = wi::mask (precision, false, precision);
+   wide_int c0 = wi::to_wide (@0);
+   wide_int c2 = wi::to_wide (@2);
+   wide_int c2_add_1 = wi::add (c2, wi::uhwi (1, precision));
+   bool equal_p = wi::eq_p (c0, c2);
+   bool less_than_1_p = !wi::eq_p (c2, max) && wi::eq_p (c2_add_1, c0);
+  }
+  (if (equal_p || less_than_1_p)
+
+/* Unsigned saturation sub with op_1 imm, case 10:
+   SAT_U_SUB = X > IMM  ? (X - IMM) : 0.
+ = X >= IMM ? (X - IMM) : 0.  */
+(match (unsigned_integer_sat_sub @0 @1)
+ (plus (max @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+ && types_match (type, @1))
+ (with
+  {
+   unsigned precision = TYPE_PRECISION (type);
+   wide_int c1 = wi::to_wide (@1);
+   wide_int c2 = wi::to_wide (@2);
+   wide_int sum = wi::add (c1, c2);
+  }
+  (if (wi::eq_p (sum, wi::uhwi (0, precision)))
+
 /* Unsigned saturation truncate, case 1, sizeof (WT) > sizeof (NT).
SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1))).  */
 (match (unsigned_integer_sat_trunc @0)