[gcc r15-2335] i386: Use BLKmode for {ld,st}tilecfg
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]
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.
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
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
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
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
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
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]
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
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
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
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
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
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
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
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]
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
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)
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
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)