aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog54
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/c-family/ChangeLog15
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/cobol/ChangeLog10
-rw-r--r--gcc/cobol/cbldiag.h4
-rw-r--r--gcc/cobol/parse.y4
-rw-r--r--gcc/cobol/scan.l2
-rw-r--r--gcc/cobol/scan_ante.h2
-rw-r--r--gcc/cobol/show_parse.h2
-rw-r--r--gcc/cobol/util.cc4
-rw-r--r--gcc/cp/ChangeLog45
-rw-r--r--gcc/cp/call.cc22
-rw-r--r--gcc/testsuite/ChangeLog97
-rw-r--r--gcc/testsuite/c-c++-common/asan/pr121389-1.c23
-rw-r--r--gcc/testsuite/c-c++-common/asan/pr121389-2.c37
-rw-r--r--gcc/testsuite/c-c++-common/asan/pr121389-3.c130
-rw-r--r--gcc/testsuite/c-c++-common/asan/pr121389-4.c6
-rw-r--r--gcc/tree-tailcall.cc207
-rw-r--r--gcc/tree-vect-loop.cc13
-rw-r--r--gcc/tree-vect-stmts.cc17
21 files changed, 606 insertions, 96 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b600551..fab0d36 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,57 @@
+2025-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121414
+ * config/aarch64/aarch64.cc (aarch64_is_variant_pcs): New function,
+ split out from...
+ (aarch64_asm_output_variant_pcs): ...here. Handle various types
+ of SME function type.
+
+2025-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR rtl-optimization/120718
+ * simplify-rtx.cc (simplify_context::simplify_gen_subreg):
+ Remove MODE_COMPOSITE_P condition.
+
+2025-08-07 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/121405
+ * tree-ssa-sccvn.cc (visit_nary_op): Handle BIT_FIELD_REF
+ with reference def by looking up a combination of both.
+
+2025-08-07 Pengfei Li <Pengfei.Li2@arm.com>
+
+ * tree-vect-data-refs.cc (vect_compute_data_ref_alignment):
+ Allow DR target alignment to be a poly_int.
+ (vect_enhance_data_refs_alignment): Support peeling and
+ versioning for VLA modes.
+ * tree-vect-loop-manip.cc (get_misalign_in_elems): Remove
+ power-of-two rounding in peeling.
+ (vect_create_cond_for_align_checks): Update alignment check
+ logic for poly_int mask.
+ (vect_create_cond_for_vla_spec_read): New runtime checks.
+ (vect_loop_versioning): Support new runtime checks.
+ * tree-vect-loop.cc (_loop_vec_info::_loop_vec_info): Add a new
+ loop_vinfo field.
+ (vectorizable_induction): Fix wrong IV offset issue.
+ * tree-vect-stmts.cc (get_load_store_type): Refactor
+ vectorizable checks for speculative loads.
+ * tree-vectorizer.h (LOOP_VINFO_MAX_SPEC_READ_AMOUNT): New
+ macro for new runtime checks.
+ (LOOP_REQUIRES_VERSIONING_FOR_SPEC_READ): Likewise
+ (LOOP_REQUIRES_VERSIONING): Update macro for new runtime checks.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * doc/invoke.texi (Wkeyword-macro): Document.
+
+2025-08-07 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
+
+ * config/s390/s390.cc (print_operand): Allow arbitrary wide_int
+ constants for _BitInt.
+ (s390_bitint_type_info): Implement target hook
+ TARGET_C_BITINT_TYPE_INFO.
+
2025-08-06 Uros Bizjak <ubizjak@gmail.com>
PR target/96226
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index d4024d7..1f2f1bb 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250807
+20250808
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 2abe6df..ee84aa6 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,18 @@
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/117783
+ * c-cppbuiltin.cc (c_cpp_builtins): Change __cpp_structured_bindings
+ predefined value for C++26 from 202403L to 202411L.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * c.opt (Wkeyword-macro): New option.
+ * c.opt.urls: Regenerate.
+ * c-common.h (cxx_dialect): Comment formatting fix.
+ * c-opts.cc (c_common_post_options): Default to
+ -Wkeyword-macro for C++26 if pedantic.
+
2025-08-06 Alexandre Oliva <oliva@adacore.com>
* c-attribs.cc (handle_hardbool_attribute): Create distinct
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 2e5c896..87a18c9 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,9 @@
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * c-decl.cc (c_init_decl_processing): Mark cpp nodes corresponding
+ to keywords as NODE_WARN if warn_keyword_macro.
+
2025-08-06 Alexandre Oliva <oliva@adacore.com>
* c-tree.h (C_BOOLEAN_TYPE_P): Cover hardbools as well.
diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog
index 35d645c..8c47213 100644
--- a/gcc/cobol/ChangeLog
+++ b/gcc/cobol/ChangeLog
@@ -1,3 +1,13 @@
+2025-08-07 Robert Dubner <rdubner@symas.com>
+
+ * cbldiag.h (location_dump): Source code formatting.
+ * parse.y: error_msg formatting.
+ * scan.l: Remove UTF-8 character from regex pattern.
+ * scan_ante.h (numstr_of): error_msg formatting.
+ * show_parse.h (class ANALYZE): Suppress cppcheck error.
+ * util.cc (cbl_field_t::report_invalid_initial_value):
+ error_msg formatting.
+
2025-08-02 Jakub Jelinek <jakub@redhat.com>
* parse.y (intrinsic): Use %td format specifier with no cast on
diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h
index dd16190..2554deb 100644
--- a/gcc/cobol/cbldiag.h
+++ b/gcc/cobol/cbldiag.h
@@ -122,8 +122,8 @@ static void
location_dump( const char func[], int line, const char tag[], const LOC& loc) {
extern int yy_flex_debug; // cppcheck-suppress shadowVariable
if( yy_flex_debug ) {
- const char *detail = gcobol_getenv("update_location"); // cppcheck-suppress knownConditionTrueFalse
- if( detail ) {
+ const char *detail = gcobol_getenv("update_location");
+ if( detail ) { // cppcheck-suppress knownConditionTrueFalse
fprintf(stderr, "%s:%d: %s location (%d,%d) to (%d,%d)\n",
func, line, tag,
loc.first_line, loc.first_column, loc.last_line, loc.last_column);
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index fae96ed..59cc64d 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -10336,8 +10336,8 @@ intrinsic: function_udf
if( p != NULL ) {
auto loc = symbol_field_location(field_index(p->field));
error_msg(loc, "FUNCTION %qs has "
- "inconsistent parameter type %td (%qs)",
- keyword_str($1), p - args.data(), name_of(p->field) );
+ "inconsistent parameter type %ld (%qs)",
+ keyword_str($1), (long)(p - args.data()), name_of(p->field) );
YYERROR;
}
$$ = is_numeric(args[0].field)?
diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l
index ba4c044..5773f09 100644
--- a/gcc/cobol/scan.l
+++ b/gcc/cobol/scan.l
@@ -123,7 +123,7 @@ NUMEDCHAR [BPVZ90/,]+{COUNT}?
NUMEDCHARS {NUMEDCHAR}([.]?{NUMEDCHAR})*
NUMED ([+-]{NUMEDCHARS}+)|({NUMEDCHARS}+[+-])
CURRENCY [A-Zfhijklmoqtuwy\x80-\xFF]{-}[ABCDEGNPRSVXZ]
-NUMEDCUR (([.]?[-$0B/Z*+,P9()V+–]|{CURRENCY}+|{COUNT})+([.][$0B/Z*+P9()V+\–])*)+
+NUMEDCUR (([.]?[$0B/Z*+,P9()V+-]|{CURRENCY}+|{COUNT})+([.][$0B/Z*+P9()V+-])*)+
NUMEDITED {NUMED}|{NUMEDCUR}
EDITED {ALPHED}|{NUMED}|{NUMEDCUR}
diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index 31093a6..c00826d 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -149,7 +149,7 @@ numstr_of( const char string[], radix_t radix = decimal_e ) {
}
auto nx = std::count_if(input, p, fisdigit);
if( 36 < nx ) {
- error_msg(yylloc, "significand of %s has more than 36 digits (%td)", input, nx);
+ error_msg(yylloc, "significand of %s has more than 36 digits (%ld)", input, (long)nx);
return NO_CONDITION;
}
diff --git a/gcc/cobol/show_parse.h b/gcc/cobol/show_parse.h
index bd0e16f..e1a8cb2 100644
--- a/gcc/cobol/show_parse.h
+++ b/gcc/cobol/show_parse.h
@@ -500,7 +500,7 @@ class ANALYZE
int level;
inline static int analyze_level=1;
public:
- ANALYZE(const char *func_) : func(func_)
+ ANALYZE(const char *func_) : func(func_) // cppcheck-suppress noExplicitConstructor
{
level = 0;
if( getenv("Analyze") )
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index aed9483..2a7bf2b 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -1049,8 +1049,8 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const {
return TOUPPER(ch) == 'E';
} );
if( !has_exponent && data.precision() < pend - p ) {
- error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%td)",
- name, data.initial, '.', pend - p);
+ error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%ld)",
+ name, data.initial, '.', (long)(pend - p));
}
}
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8e9b8ea..061c4e4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,48 @@
+2025-08-07 Patrick Palka <ppalka@redhat.com>
+
+ * call.cc (extract_call_expr): Remove handling of C++20
+ rewritten comparison operators.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/117783
+ * parser.cc: Implement C++26 P1061R10 - Structured Bindings can
+ introduce a Pack.
+ (cp_parser_range_for): Also handle TREE_VEC as DECL_VALUE_EXPR
+ instead of ARRAY_REF.
+ (cp_parser_decomposition_declaration): Use sb-identifier-list instead
+ of identifier-list in comments. Parse structured bindings with
+ structured binding pack. Don't emit pedwarn about structured
+ binding attributes in structured bindings inside of a condition.
+ (cp_convert_omp_range_for): Also handle TREE_VEC as DECL_VALUE_EXPR
+ instead of ARRAY_REF.
+ * decl.cc (get_tuple_element_type): Change i argument type from
+ unsigned to unsigned HOST_WIDE_INT.
+ (get_tuple_decomp_init): Likewise.
+ (set_sb_pack_name): New function.
+ (cp_finish_decomp): Handle structured binding packs.
+ * pt.cc (tsubst_pack_expansion): Handle structured binding packs
+ and capture proxies for them. Formatting fixes.
+ (tsubst_decl): For structured binding packs don't tsubst TREE_TYPE
+ first, instead recreate the type after r is created.
+ (tsubst_omp_for_iterator): Also handle TREE_VEC as DECL_VALUE_EXPR
+ instead of ARRAY_REF.
+ (tsubst_expr): Handle sizeof... on non-dependent structure binding
+ packs.
+ (value_dependent_expression_p): Return false for sizeof... on
+ non-dependent structure binding packs.
+ (instantiation_dependent_r): Don't recurse on sizeof... on
+ non-dependent structure binding packs.
+ * constexpr.cc (potential_constant_expression_1): Also handle
+ TREE_VEC on DECL_VALUE_EXPR of structure binding packs.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * lex.cc (cxx_init): Mark cpp nodes corresponding
+ to keywords, identifiers with special meaning and standard
+ attribute identifiers as NODE_WARN if warn_keyword_macro.
+
2025-08-06 Patrick Palka <ppalka@redhat.com>
PR c++/121231
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 9283d97..63cad2a 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -7904,28 +7904,6 @@ extract_call_expr (tree call)
call = TREE_OPERAND (call, 0);
if (TREE_CODE (call) == TARGET_EXPR)
call = TARGET_EXPR_INITIAL (call);
- if (cxx_dialect >= cxx20)
- switch (TREE_CODE (call))
- {
- /* C++20 rewritten comparison operators. */
- case TRUTH_NOT_EXPR:
- call = TREE_OPERAND (call, 0);
- break;
- case LT_EXPR:
- case LE_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- case SPACESHIP_EXPR:
- {
- tree op0 = TREE_OPERAND (call, 0);
- if (integer_zerop (op0))
- call = TREE_OPERAND (call, 1);
- else
- call = op0;
- }
- break;
- default:;
- }
if (TREE_CODE (call) != CALL_EXPR
&& TREE_CODE (call) != AGGR_INIT_EXPR
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index df2c843..ee43695 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,100 @@
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/117783
+ * g++.dg/cpp26/decomp13.C: New test.
+ * g++.dg/cpp26/decomp14.C: New test.
+ * g++.dg/cpp26/decomp15.C: New test.
+ * g++.dg/cpp26/decomp16.C: New test.
+ * g++.dg/cpp26/decomp17.C: New test.
+ * g++.dg/cpp26/decomp18.C: New test.
+ * g++.dg/cpp26/decomp19.C: New test.
+ * g++.dg/cpp26/decomp20.C: New test.
+ * g++.dg/cpp26/decomp21.C: New test.
+ * g++.dg/cpp26/feat-cxx26.C (__cpp_structured_bindings): Expect
+ 202411 rather than 202403.
+
+2025-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121414
+ * gcc.target/aarch64/sme/pr121414_1.c: New test.
+
+2025-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR rtl-optimization/120718
+ * gcc.target/aarch64/sve/acle/general/pr120718.c: New test.
+
+2025-08-07 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/121405
+ * gcc.dg/tree-ssa/ssa-fre-107.c: New testcase.
+ * gcc.target/i386/pr90579.c: Adjust.
+
+2025-08-07 Pengfei Li <Pengfei.Li2@arm.com>
+
+ * gcc.target/aarch64/sve/peel_ind_11.c: New test.
+ * gcc.target/aarch64/sve/peel_ind_11_run.c: New test.
+ * gcc.target/aarch64/sve/peel_ind_12.c: New test.
+ * gcc.target/aarch64/sve/peel_ind_12_run.c: New test.
+ * gcc.target/aarch64/sve/peel_ind_13.c: New test.
+ * gcc.target/aarch64/sve/peel_ind_13_run.c: New test.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * g++.dg/DRs/dr2577-1.C: New test.
+ * g++.dg/DRs/dr2577-2.C: New test.
+ * g++.dg/DRs/dr2577-2.h: New file.
+ * g++.dg/DRs/dr2577-3.C: New test.
+ * g++.dg/DRs/dr2577-3.h: New file.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * g++.dg/DRs/dr2575.C: New test.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * g++.dg/DRs/dr2576.C: New test.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * gcc.dg/Wkeyword-macro-1.c: New test.
+ * gcc.dg/Wkeyword-macro-2.c: New test.
+ * gcc.dg/Wkeyword-macro-3.c: New test.
+ * gcc.dg/Wkeyword-macro-4.c: New test.
+ * gcc.dg/Wkeyword-macro-5.c: New test.
+ * gcc.dg/Wkeyword-macro-6.c: New test.
+ * gcc.dg/Wkeyword-macro-7.c: New test.
+ * gcc.dg/Wkeyword-macro-8.c: New test.
+ * gcc.dg/Wkeyword-macro-9.c: New test.
+ * g++.dg/warn/Wkeyword-macro-1.C: New test.
+ * g++.dg/warn/Wkeyword-macro-2.C: New test.
+ * g++.dg/warn/Wkeyword-macro-3.C: New test.
+ * g++.dg/warn/Wkeyword-macro-4.C: New test.
+ * g++.dg/warn/Wkeyword-macro-5.C: New test.
+ * g++.dg/warn/Wkeyword-macro-6.C: New test.
+ * g++.dg/warn/Wkeyword-macro-7.C: New test.
+ * g++.dg/warn/Wkeyword-macro-8.C: New test.
+ * g++.dg/warn/Wkeyword-macro-9.C: New test.
+ * g++.dg/warn/Wkeyword-macro-10.C: New test.
+ * g++.dg/opt/pr82577.C: Don't #define register to nothing for
+ C++17 and later. Instead define reg macro to nothing for C++17
+ and later or to register and use it instead of register.
+ * g++.dg/modules/atom-preamble-3.C: Add -Wno-keyword-macro to
+ dg-additional-options.
+ * g++.dg/template/sfinae17.C (static_assert): Rename macro to ...
+ (my_static_assert): ... this.
+ (main): Use my_static_assert instead of static_assert.
+
+2025-08-07 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
+
+ * gcc.target/s390/bitint-1.c: New test.
+ * gcc.target/s390/bitint-2.c: New test.
+ * gcc.target/s390/bitint-3.c: New test.
+ * gcc.target/s390/bitint-4.c: New test.
+
2025-08-06 Sam James <sam@gentoo.org>
* g++.dg/cpp26/constexpr-new3.C: Escape '[' and ']'.
diff --git a/gcc/testsuite/c-c++-common/asan/pr121389-1.c b/gcc/testsuite/c-c++-common/asan/pr121389-1.c
new file mode 100644
index 0000000..0116d7a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr121389-1.c
@@ -0,0 +1,23 @@
+// PR middle-end/121389
+// { dg-do compile { target musttail } }
+// { dg-options "-fsanitize=address" }
+
+int foo (void);
+int bar (void);
+int baz (unsigned *);
+
+int
+bar (void)
+{
+ do
+ {
+ unsigned t;
+ int u = baz (&t);
+ if (u == 42)
+ [[gnu::musttail]] return foo ();
+ if (u == -42)
+ break;
+ }
+ while (1);
+ return 42;
+}
diff --git a/gcc/testsuite/c-c++-common/asan/pr121389-2.c b/gcc/testsuite/c-c++-common/asan/pr121389-2.c
new file mode 100644
index 0000000..02914f8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr121389-2.c
@@ -0,0 +1,37 @@
+// PR middle-end/121389
+// { dg-do compile { target musttail } }
+// { dg-options "-fsanitize=address" }
+
+int foo (void);
+int bar (void);
+int baz (unsigned *);
+
+int
+bar (void)
+{
+ for (int a = 0; a < 420; ++a)
+ {
+ for (int b = 0; b < 420; ++b)
+ {
+ for (int c = 0; c < 420; ++c)
+ {
+ unsigned t;
+ int u = baz (&t);
+ if (u == 42)
+ [[gnu::musttail]] return foo ();
+ if (u == -42)
+ break;
+ if (u == 16)
+ goto l1;
+ if (u == 18)
+ goto l2;
+ if (u == 20)
+ goto l3;
+ }
+ l3:;
+ }
+ l2:;
+ }
+ l1:;
+ return 42;
+}
diff --git a/gcc/testsuite/c-c++-common/asan/pr121389-3.c b/gcc/testsuite/c-c++-common/asan/pr121389-3.c
new file mode 100644
index 0000000..5f71e06
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr121389-3.c
@@ -0,0 +1,130 @@
+// PR middle-end/121389
+// { dg-do compile { target musttail } }
+// { dg-options "-fsanitize=address" }
+
+int foo (void);
+int bar (void);
+int baz (unsigned *);
+
+int
+bar (void)
+{
+ for (int a = 0; a < 420; ++a)
+ {
+ for (int b = 0; b < 420; ++b)
+ {
+ for (int c = 0; c < 420; ++c)
+ {
+ unsigned t;
+ int u = baz (&t);
+ if (u == 42)
+ [[gnu::musttail]] return foo ();
+ if (u == -42)
+ break;
+ if (u == 16)
+ goto l1;
+ if (u == 18)
+ goto l2;
+ if (u == 20)
+ goto l3;
+ switch (u)
+ {
+ case 100: goto l100;
+ case 101: goto l101;
+ case 102: goto l102;
+ case 103: goto l103;
+ case 104: goto l104;
+ case 105: goto l105;
+ case 106: goto l106;
+ case 107: goto l107;
+ case 108: goto l108;
+ case 109: goto l109;
+ case 110: goto l110;
+ case 111: goto l111;
+ case 112: goto l112;
+ case 113: goto l113;
+ case 114: goto l114;
+ case 115: goto l115;
+ case 116: goto l116;
+ case 117: goto l117;
+ case 118: goto l118;
+ case 119: goto l119;
+ case 120: goto l120;
+ case 121: goto l121;
+ case 122: goto l122;
+ case 123: goto l123;
+ case 124: goto l124;
+ case 125: goto l125;
+ case 126: goto l126;
+ case 127: goto l127;
+ case 128: goto l128;
+ case 129: goto l129;
+ }
+ }
+ l3:;
+ foo ();
+ l100:
+ foo ();
+ l101:
+ foo ();
+ l102:
+ foo ();
+ l103:
+ foo ();
+ l104:
+ foo ();
+ l105:
+ foo ();
+ l106:
+ foo ();
+ l107:
+ foo ();
+ l108:
+ foo ();
+ l109:;
+ }
+ l2:;
+ foo ();
+ l110:
+ foo ();
+ l111:
+ foo ();
+ l112:
+ foo ();
+ l113:
+ foo ();
+ l114:
+ foo ();
+ l115:
+ foo ();
+ l116:
+ foo ();
+ l117:
+ foo ();
+ l118:
+ foo ();
+ l119:;
+ }
+ l1:;
+ foo ();
+ l120:
+ foo ();
+ l121:
+ foo ();
+ l122:
+ foo ();
+ l123:
+ foo ();
+ l124:
+ foo ();
+ l125:
+ foo ();
+ l126:
+ foo ();
+ l127:
+ foo ();
+ l128:
+ foo ();
+ l129:;
+ return 42;
+}
diff --git a/gcc/testsuite/c-c++-common/asan/pr121389-4.c b/gcc/testsuite/c-c++-common/asan/pr121389-4.c
new file mode 100644
index 0000000..2f7b410
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr121389-4.c
@@ -0,0 +1,6 @@
+// PR middle-end/121389
+// { dg-do compile { target musttail } }
+// { dg-options "-fsanitize=address -fdisable-tree-switchlower_O0" }
+// { dg-skip-if "" { *-*-* } { "*" } { "-O0" } }
+
+#include "pr121389-3.c"
diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc
index c80145d..d04394f 100644
--- a/gcc/tree-tailcall.cc
+++ b/gcc/tree-tailcall.cc
@@ -605,6 +605,12 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
&& (stmt = last_nondebug_stmt (bb))
&& gimple_code (stmt) == GIMPLE_COND)
;
+ else if (esucc
+ && cfun->has_musttail
+ && diag_musttail
+ && (stmt = last_nondebug_stmt (bb))
+ && gimple_code (stmt) == GIMPLE_SWITCH)
+ ;
/* If there is an abnormal edge assume it's the only extra one.
Tolerate that case so that we can give better error messages
for musttail later. */
@@ -668,7 +674,7 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
else
goto <bb 6>; [INV]
When walking backwards, ESUCC is the edge we are coming from,
- depending on its EDGE_TRUE_FLAG, == vs. != for the comparison
+ depending on its EDGE_TRUE_FLAG, comparison code
and value compared against try to find out through which edge
we need to go and which edge should be ignored. The code handles
both INTEGER_CST PHI arguments and SSA_NAMEs set to constants
@@ -677,19 +683,16 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
&& diag_musttail
&& esucc
&& gimple_code (stmt) == GIMPLE_COND
- && (gimple_cond_code (stmt) == EQ_EXPR
- || gimple_cond_code (stmt) == NE_EXPR)
&& TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
&& TREE_CODE (gimple_cond_rhs (stmt)) == INTEGER_CST
&& INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
- && (integer_zerop (gimple_cond_rhs (stmt))
- || integer_onep (gimple_cond_rhs (stmt))))
+ && tree_int_cst_sgn (gimple_cond_rhs (stmt)) >= 0)
{
tree lhs = gimple_cond_lhs (stmt);
- bool rhsv = integer_onep (gimple_cond_rhs (stmt));
- if (((esucc->flags & EDGE_TRUE_VALUE) != 0)
- ^ (gimple_cond_code (stmt) == EQ_EXPR))
- rhsv = !rhsv;
+ tree_code ccode = gimple_cond_code (stmt);
+ tree rhsv = gimple_cond_rhs (stmt);
+ if ((esucc->flags & EDGE_FALSE_VALUE) != 0)
+ ccode = invert_tree_comparison (ccode, false);
if (!ignored_edges)
{
ignored_edges = new hash_set<edge>;
@@ -700,8 +703,10 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
&& (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (lhs))
== INTEGER_CST))
{
- tree rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhs));
- if (rhsv ? integer_onep (rhs) : integer_zerop (rhs))
+ tree lhsv = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhs));
+
+ if (const_binop (ccode, boolean_type_node, lhsv, rhsv)
+ == boolean_true_node)
continue;
}
else if (gimple_code (SSA_NAME_DEF_STMT (lhs)) == GIMPLE_PHI)
@@ -712,15 +717,62 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
edge_iterator ei;
FOR_EACH_EDGE (e, ei, pbb->preds)
{
- tree rhs = gimple_phi_arg_def_from_edge (phi, e);
- if (TREE_CODE (rhs) == SSA_NAME
- && is_gimple_assign (SSA_NAME_DEF_STMT (rhs))
- && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (rhs))
+ tree lhsv = gimple_phi_arg_def_from_edge (phi, e);
+ if (TREE_CODE (lhsv) == SSA_NAME
+ && is_gimple_assign (SSA_NAME_DEF_STMT (lhsv))
+ && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (lhsv))
== INTEGER_CST))
- rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs));
- if (!(rhsv ? integer_onep (rhs) : integer_zerop (rhs)))
+ lhsv = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhsv));
+ if (TREE_CODE (lhsv) != INTEGER_CST
+ || const_binop (ccode, boolean_type_node,
+ lhsv, rhsv) != boolean_true_node)
ignored_edges->add (e);
}
+ continue;
+ }
+ }
+ if (cfun->has_musttail
+ && diag_musttail
+ && esucc
+ && gimple_code (stmt) == GIMPLE_SWITCH
+ && (TREE_CODE (gimple_switch_index (as_a <gswitch *> (stmt)))
+ == SSA_NAME))
+ {
+ gswitch *swtch = as_a <gswitch *> (stmt);
+ tree idx = gimple_switch_index (swtch);
+ if (!ignored_edges)
+ {
+ ignored_edges = new hash_set<edge>;
+ must_see_bbs = new hash_set<basic_block>;
+ delete_ignored_edges = true;
+ }
+ if (is_gimple_assign (SSA_NAME_DEF_STMT (idx))
+ && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (idx))
+ == INTEGER_CST))
+ {
+ tree val = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (idx));
+ if (find_taken_edge_switch_expr (swtch, val) == esucc)
+ continue;
+ }
+ else if (gimple_code (SSA_NAME_DEF_STMT (idx)) == GIMPLE_PHI)
+ {
+ gimple *phi = SSA_NAME_DEF_STMT (idx);
+ basic_block pbb = gimple_bb (phi);
+ must_see_bbs->add (pbb);
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, pbb->preds)
+ {
+ tree val = gimple_phi_arg_def_from_edge (phi, e);
+ if (TREE_CODE (val) == SSA_NAME
+ && is_gimple_assign (SSA_NAME_DEF_STMT (val))
+ && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (val))
+ == INTEGER_CST))
+ val = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val));
+ if (TREE_CODE (val) != INTEGER_CST
+ || find_taken_edge_switch_expr (swtch, val) != esucc)
+ ignored_edges->add (e);
+ }
+ continue;
}
}
@@ -1138,47 +1190,67 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
if (ignored_edges)
{
if (is_gimple_assign (stmt)
- && gimple_assign_rhs_code (stmt) == INTEGER_CST)
+ && gimple_assign_rhs_code (stmt) == INTEGER_CST
+ && tree_int_cst_sgn (gimple_assign_rhs1 (stmt)) >= 0)
{
use_operand_p use_p;
- gimple *use_stmt;
- if ((integer_zerop (gimple_assign_rhs1 (stmt))
- || integer_onep (gimple_assign_rhs1 (stmt)))
- && single_imm_use (gimple_assign_lhs (stmt), &use_p,
- &use_stmt))
+ imm_use_iterator imm_iter;
+ bool bad_p = false;
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter,
+ gimple_assign_lhs (stmt))
{
- if (gimple_code (use_stmt) == GIMPLE_COND)
- continue;
- if (gimple_code (use_stmt) == GIMPLE_PHI
- && single_imm_use (gimple_phi_result (use_stmt),
- &use_p, &use_stmt)
- && gimple_code (use_stmt) == GIMPLE_COND)
+ gimple *use_stmt = USE_STMT (use_p);
+ if (is_gimple_debug (use_stmt)
+ || gimple_code (use_stmt) == GIMPLE_COND
+ || gimple_code (use_stmt) == GIMPLE_SWITCH)
continue;
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
+ {
+ use_operand_p use_p2;
+ imm_use_iterator imm_iter2;
+ FOR_EACH_IMM_USE_FAST (use_p2, imm_iter2,
+ gimple_phi_result (use_stmt))
+ {
+ gimple *use_stmt2 = USE_STMT (use_p2);
+ if (is_gimple_debug (use_stmt2)
+ || gimple_code (use_stmt2) == GIMPLE_COND
+ || gimple_code (use_stmt2) == GIMPLE_SWITCH)
+ continue;
+ bad_p = true;
+ break;
+ }
+ if (bad_p)
+ break;
+ }
+ else
+ {
+ bad_p = true;
+ break;
+ }
}
+ if (!bad_p)
+ continue;
}
if (gimple_code (stmt) == GIMPLE_COND
- && (gimple_cond_code (stmt) == EQ_EXPR
- || gimple_cond_code (stmt) == NE_EXPR)
&& TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
&& TREE_CODE (gimple_cond_rhs (stmt)) == INTEGER_CST
&& INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
- && (integer_zerop (gimple_cond_rhs (stmt))
- || integer_onep (gimple_cond_rhs (stmt))))
+ && tree_int_cst_sgn (gimple_cond_rhs (stmt)) >= 0)
{
edge e = NULL, et, ef;
+ enum tree_code ccode = gimple_cond_code (stmt);
tree lhs = gimple_cond_lhs (stmt);
- bool rhsv = integer_onep (gimple_cond_rhs (stmt));
- if (gimple_cond_code (stmt) == NE_EXPR)
- rhsv = !rhsv;
+ tree rhsv = gimple_cond_rhs (stmt);
extract_true_false_edges_from_block (gimple_bb (stmt), &et, &ef);
if (is_gimple_assign (SSA_NAME_DEF_STMT (lhs))
&& (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (lhs))
== INTEGER_CST))
{
- tree rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhs));
- if (rhsv ? integer_onep (rhs) : integer_zerop (rhs))
+ tree lhsv = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (lhs));
+ tree r = const_binop (ccode, boolean_type_node, lhsv, rhsv);
+ if (r == boolean_true_node)
e = et;
- else if (rhsv ? integer_zerop (rhs) : integer_onep (rhs))
+ else if (r == boolean_false_node)
e = ef;
}
else if (gimple_code (SSA_NAME_DEF_STMT (lhs)) == GIMPLE_PHI)
@@ -1188,16 +1260,17 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
for (edge e2 : edges)
if (e2->dest == pbb)
{
- tree rhs = gimple_phi_arg_def_from_edge (phi, e2);
- if (TREE_CODE (rhs) == SSA_NAME)
- if (gimple *g = SSA_NAME_DEF_STMT (rhs))
+ tree lhsv = gimple_phi_arg_def_from_edge (phi, e2);
+ if (TREE_CODE (lhsv) == SSA_NAME)
+ if (gimple *g = SSA_NAME_DEF_STMT (lhsv))
if (is_gimple_assign (g)
&& gimple_assign_rhs_code (g) == INTEGER_CST)
- rhs = gimple_assign_rhs1 (g);
- if (rhsv ? integer_onep (rhs) : integer_zerop (rhs))
+ lhsv = gimple_assign_rhs1 (g);
+ tree r = const_binop (ccode, boolean_type_node,
+ lhsv, rhsv);
+ if (r == boolean_true_node)
e = et;
- else if (rhsv ? integer_zerop (rhs)
- : integer_onep (rhs))
+ else if (r == boolean_false_node)
e = ef;
break;
}
@@ -1212,6 +1285,48 @@ find_tail_calls (basic_block bb, edge esucc, struct tailcall **ret,
goto new_bb;
}
}
+ if (gimple_code (stmt) == GIMPLE_SWITCH
+ && (TREE_CODE (gimple_switch_index (as_a <gswitch *> (stmt)))
+ == SSA_NAME))
+ {
+ edge e = NULL;
+ gswitch *swtch = as_a <gswitch *> (stmt);
+ tree idx = gimple_switch_index (swtch);
+ if (is_gimple_assign (SSA_NAME_DEF_STMT (idx))
+ && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (idx))
+ == INTEGER_CST))
+ {
+ tree val = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (idx));
+ e = find_taken_edge_switch_expr (swtch, val);
+ }
+ else if (gimple_code (SSA_NAME_DEF_STMT (idx)) == GIMPLE_PHI)
+ {
+ gimple *phi = SSA_NAME_DEF_STMT (idx);
+ basic_block pbb = gimple_bb (phi);
+ for (edge e2 : edges)
+ if (e2->dest == pbb)
+ {
+ tree val = gimple_phi_arg_def_from_edge (phi, e2);
+ if (TREE_CODE (val) == SSA_NAME)
+ if (gimple *g = SSA_NAME_DEF_STMT (val))
+ if (is_gimple_assign (g)
+ && gimple_assign_rhs_code (g) == INTEGER_CST)
+ val = gimple_assign_rhs1 (g);
+ if (TREE_CODE (val) == INTEGER_CST)
+ e = find_taken_edge_switch_expr (swtch, val);
+ break;
+ }
+ }
+ if (e)
+ {
+ ass_var = propagate_through_phis (ass_var, e);
+ if (!ass_var || ignored_edges)
+ edges.safe_push (e);
+ abb = e->dest;
+ agsi = gsi_start_bb (abb);
+ goto new_bb;
+ }
+ }
}
if (gimple_code (stmt) != GIMPLE_ASSIGN)
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 55a8495..cab503c 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -4957,8 +4957,9 @@ have_whole_vector_shift (machine_mode mode)
See vect_emulate_mixed_dot_prod for the actual sequence used. */
static bool
-vect_is_emulated_mixed_dot_prod (stmt_vec_info stmt_info)
+vect_is_emulated_mixed_dot_prod (slp_tree slp_node)
{
+ stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (slp_node);
gassign *assign = dyn_cast<gassign *> (stmt_info->stmt);
if (!assign || gimple_assign_rhs_code (assign) != DOT_PROD_EXPR)
return false;
@@ -4970,7 +4971,7 @@ vect_is_emulated_mixed_dot_prod (stmt_vec_info stmt_info)
gcc_assert (STMT_VINFO_REDUC_VECTYPE_IN (stmt_info));
return !directly_supported_p (DOT_PROD_EXPR,
- STMT_VINFO_VECTYPE (stmt_info),
+ SLP_TREE_VECTYPE (slp_node),
STMT_VINFO_REDUC_VECTYPE_IN (stmt_info),
optab_vector_mixed_sign);
}
@@ -7119,13 +7120,13 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
vectype_in);
gcc_assert (ncopies_for_cost >= 1);
- if (vect_is_emulated_mixed_dot_prod (stmt_info))
+ if (vect_is_emulated_mixed_dot_prod (slp_node))
{
/* We need extra two invariants: one that contains the minimum signed
value and one that contains half of its negative. */
int prologue_stmts = 2;
unsigned cost = record_stmt_cost (cost_vec, prologue_stmts,
- scalar_to_vec, stmt_info, 0,
+ scalar_to_vec, slp_node, 0,
vect_prologue);
if (dump_enabled_p ())
dump_printf (MSG_NOTE, "vectorizable_lane_reducing: "
@@ -7135,7 +7136,7 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
ncopies_for_cost *= 4;
}
- record_stmt_cost (cost_vec, (int) ncopies_for_cost, vector_stmt, stmt_info,
+ record_stmt_cost (cost_vec, (int) ncopies_for_cost, vector_stmt, slp_node,
0, vect_body);
if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo))
@@ -8421,7 +8422,7 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
}
}
- bool emulated_mixed_dot_prod = vect_is_emulated_mixed_dot_prod (stmt_info);
+ bool emulated_mixed_dot_prod = vect_is_emulated_mixed_dot_prod (slp_node);
unsigned num = vec_oprnds[reduc_index == 0 ? 1 : 0].length ();
unsigned mask_index = 0;
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index dbeb8bd..eff5e88 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -929,8 +929,7 @@ vect_model_simple_cost (vec_info *, int n, slp_tree node,
is true the stmt is doing widening arithmetic. */
static void
-vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
- enum vect_def_type *dt,
+vect_model_promotion_demotion_cost (slp_tree slp_node,
unsigned int ncopies, int pwr,
stmt_vector_for_cost *cost_vec,
bool widen_arith)
@@ -943,16 +942,10 @@ vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
inside_cost += record_stmt_cost (cost_vec, ncopies,
widen_arith
? vector_stmt : vec_promote_demote,
- stmt_info, 0, vect_body);
+ slp_node, 0, vect_body);
ncopies *= 2;
}
- /* FORNOW: Assuming maximum 2 args per stmts. */
- for (i = 0; i < 2; i++)
- if (dt[i] == vect_constant_def || dt[i] == vect_external_def)
- prologue_cost += record_stmt_cost (cost_vec, 1, vector_stmt,
- stmt_info, 0, vect_prologue);
-
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"vect_model_promotion_demotion_cost: inside_cost = %d, "
@@ -5386,7 +5379,7 @@ vectorizable_conversion (vec_info *vinfo,
SLP_TREE_TYPE (slp_node) = type_demotion_vec_info_type;
/* The final packing step produces one vector result per copy. */
unsigned int nvectors = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
- vect_model_promotion_demotion_cost (stmt_info, dt, nvectors,
+ vect_model_promotion_demotion_cost (slp_node, nvectors,
multi_step_cvt, cost_vec,
widen_arith);
}
@@ -5398,7 +5391,7 @@ vectorizable_conversion (vec_info *vinfo,
so >> MULTI_STEP_CVT divides by 2^(number of steps - 1). */
unsigned int nvectors
= SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) >> multi_step_cvt;
- vect_model_promotion_demotion_cost (stmt_info, dt, nvectors,
+ vect_model_promotion_demotion_cost (slp_node, nvectors,
multi_step_cvt, cost_vec,
widen_arith);
}
@@ -7777,7 +7770,7 @@ vectorizable_store (vec_info *vinfo,
return false;
}
- tree vectype = SLP_TREE_VECTYPE (stmt_info), rhs_vectype = NULL_TREE;
+ tree vectype = SLP_TREE_VECTYPE (slp_node), rhs_vectype = NULL_TREE;
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
if (loop_vinfo)