From 820f0940d7ace1306430a9dcf1bd9577508a7a7e Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 24 Aug 2021 10:49:11 -0600 Subject: Reset PHI base0 flag if it's clear in any argument [PR101977, ...] Resolves: PR middle-end/101600 - Spurious -Warray-bounds downcasting a polymorphic pointer PR middle-end/101977 - bogus -Warray-bounds on a negative index into a parameter in conditional with null gcc/ChangeLog: PR middle-end/101600 PR middle-end/101977 * gimple-ssa-warn-access.cc (maybe_warn_for_bound): Tighten up the phrasing of a warning. (check_access): Use the remaining size after subtracting any offset rather than the whole object size. * pointer-query.cc (access_ref::get_ref): Clear BASE0 flag if it's clear for any nonnull PHI argument. (compute_objsize): Clear argument. gcc/testsuite/ChangeLog: PR middle-end/101600 PR middle-end/101977 * g++.dg/pr100574.C: Prune out valid warning. * gcc.dg/pr20126.c: Same. * gcc.dg/Wstringop-overread.c: Adjust text of expected warnings. Add new instances. * gcc.dg/warn-strnlen-no-nul.c: Same. * g++.dg/warn/Warray-bounds-26.C: New test. * gcc.dg/Warray-bounds-88.c: New test. --- gcc/gimple-ssa-warn-access.cc | 20 +++- gcc/pointer-query.cc | 105 ++++++++++++--------- gcc/testsuite/g++.dg/pr100574.C | 4 + gcc/testsuite/g++.dg/warn/Warray-bounds-26.C | 27 ++++++ gcc/testsuite/gcc.dg/Warray-bounds-88.c | 134 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/Wstringop-overread.c | 32 +++---- gcc/testsuite/gcc.dg/pr20126.c | 6 ++ gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c | 39 ++++---- 8 files changed, 286 insertions(+), 81 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Warray-bounds-26.C create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-88.c (limited to 'gcc') diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index 4a2dd9a..5df97a6 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -704,6 +704,15 @@ maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func, if (opt == OPT_Wstringop_overread) { bool maybe = pad && pad->src.phi (); + if (maybe) + { + /* Issue a "maybe" warning only if the PHI refers to objects + at least one of which has more space remaining than the bound. + Otherwise, if the bound is greater, use the definitive form. */ + offset_int remmax = pad->src.size_remaining (); + if (remmax < wi::to_offset (bndrng[0])) + maybe = false; + } if (tree_int_cst_lt (maxobjsize, bndrng[0])) { @@ -788,6 +797,15 @@ maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func, } bool maybe = pad && pad->dst.phi (); + if (maybe) + { + /* Issue a "maybe" warning only if the PHI refers to objects + at least one of which has more space remaining than the bound. + Otherwise, if the bound is greater, use the definitive form. */ + offset_int remmax = pad->dst.size_remaining (); + if (remmax < wi::to_offset (bndrng[0])) + maybe = false; + } if (tree_int_cst_lt (maxobjsize, bndrng[0])) { if (bndrng[0] == bndrng[1]) @@ -1418,7 +1436,7 @@ check_access (GimpleOrTree exp, tree dstwrite, location_t loc = get_location (exp); tree size = dstsize; if (pad && pad->mode == access_read_only) - size = wide_int_to_tree (sizetype, pad->src.sizrng[1]); + size = wide_int_to_tree (sizetype, pad->src.size_remaining ()); if (range[0] && maxread && tree_fits_uhwi_p (size)) { diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 99caf78..ba8f8a9 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -634,10 +634,10 @@ access_ref::phi () const return as_a (def_stmt); } -/* Determine and return the largest object to which *THIS. If *THIS - refers to a PHI and PREF is nonnull, fill *PREF with the details - of the object determined by compute_objsize(ARG, OSTYPE) for each - PHI argument ARG. */ +/* Determine and return the largest object to which *THIS refers. If + *THIS refers to a PHI and PREF is nonnull, fill *PREF with the details + of the object determined by compute_objsize(ARG, OSTYPE) for each PHI + argument ARG. */ tree access_ref::get_ref (vec *all_refs, @@ -659,21 +659,25 @@ access_ref::get_ref (vec *all_refs, if (!psnlim->visit_phi (ref)) return NULL_TREE; - /* Reflects the range of offsets of all PHI arguments refer to the same - object (i.e., have the same REF). */ - access_ref same_ref; - /* The conservative result of the PHI reflecting the offset and size - of the largest PHI argument, regardless of whether or not they all - refer to the same object. */ pointer_query empty_qry; if (!qry) qry = &empty_qry; + /* The conservative result of the PHI reflecting the offset and size + of the largest PHI argument, regardless of whether or not they all + refer to the same object. */ access_ref phi_ref; if (pref) { + /* The identity of the object has not been determined yet but + PREF->REF is set by the caller to the PHI for convenience. + The size is negative/invalid and the offset is zero (it's + updated only after the identity of the object has been + established). */ + gcc_assert (pref->sizrng[0] < 0); + gcc_assert (pref->offrng[0] == 0 && pref->offrng[1] == 0); + phi_ref = *pref; - same_ref = *pref; } /* Set if any argument is a function array (or VLA) parameter not @@ -682,8 +686,6 @@ access_ref::get_ref (vec *all_refs, /* The size of the smallest object referenced by the PHI arguments. */ offset_int minsize = 0; const offset_int maxobjsize = wi::to_offset (max_object_size ()); - /* The offset of the PHI, not reflecting those of its arguments. */ - const offset_int orng[2] = { phi_ref.offrng[0], phi_ref.offrng[1] }; const unsigned nargs = gimple_phi_num_args (phi_stmt); for (unsigned i = 0; i < nargs; ++i) @@ -695,28 +697,31 @@ access_ref::get_ref (vec *all_refs, /* A PHI with all null pointer arguments. */ return NULL_TREE; - /* Add PREF's offset to that of the argument. */ - phi_arg_ref.add_offset (orng[0], orng[1]); if (TREE_CODE (arg) == SSA_NAME) qry->put_ref (arg, phi_arg_ref); if (all_refs) all_refs->safe_push (phi_arg_ref); - const bool arg_known_size = (phi_arg_ref.sizrng[0] != 0 - || phi_arg_ref.sizrng[1] != maxobjsize); - parmarray |= phi_arg_ref.parmarray; const bool nullp = integer_zerop (arg) && (i || i + 1 < nargs); if (phi_ref.sizrng[0] < 0) { + /* If PHI_REF doesn't contain a meaningful result yet set it + to the result for the first argument. */ if (!nullp) - same_ref = phi_arg_ref; - phi_ref = phi_arg_ref; + phi_ref = phi_arg_ref; + + /* Set if the current argument refers to one or more objects of + known size (or range of sizes), as opposed to referring to + one or more unknown object(s). */ + const bool arg_known_size = (phi_arg_ref.sizrng[0] != 0 + || phi_arg_ref.sizrng[1] != maxobjsize); if (arg_known_size) minsize = phi_arg_ref.sizrng[0]; + continue; } @@ -740,8 +745,10 @@ access_ref::get_ref (vec *all_refs, offset_int phirem[2]; phirem[1] = phi_ref.size_remaining (phirem); - if (phi_arg_ref.ref != same_ref.ref) - same_ref.ref = NULL_TREE; + /* Reset the PHI's BASE0 flag if any of the nonnull arguments + refers to an object at an unknown offset. */ + if (!phi_arg_ref.base0) + phi_ref.base0 = false; if (phirem[1] < argrem[1] || (phirem[1] == argrem[1] @@ -749,32 +756,13 @@ access_ref::get_ref (vec *all_refs, /* Use the argument with the most space remaining as the result, or the larger one if the space is equal. */ phi_ref = phi_arg_ref; - - /* Set SAME_REF.OFFRNG to the maximum range of all arguments. */ - if (phi_arg_ref.offrng[0] < same_ref.offrng[0]) - same_ref.offrng[0] = phi_arg_ref.offrng[0]; - if (same_ref.offrng[1] < phi_arg_ref.offrng[1]) - same_ref.offrng[1] = phi_arg_ref.offrng[1]; } - if (!same_ref.ref && same_ref.offrng[0] != 0) - /* Clear BASE0 if not all the arguments refer to the same object and - if not all their offsets are zero-based. This allows the final - PHI offset to out of bounds for some arguments but not for others - (or negative even of all the arguments are BASE0), which is overly - permissive. */ - phi_ref.base0 = false; - - if (same_ref.ref) - phi_ref = same_ref; - else - { - /* Replace the lower bound of the largest argument with the size - of the smallest argument, and set PARMARRAY if any argument - was one. */ - phi_ref.sizrng[0] = minsize; - phi_ref.parmarray = parmarray; - } + /* Replace the lower bound of the largest argument with the size + of the smallest argument, and set PARMARRAY if any argument + was one. */ + phi_ref.sizrng[0] = minsize; + phi_ref.parmarray = parmarray; if (phi_ref.sizrng[0] < 0) { @@ -804,6 +792,14 @@ access_ref::size_remaining (offset_int *pmin /* = NULL */) const if (!pmin) pmin = &minbuf; + if (sizrng[0] < 0) + { + /* If the identity of the object hasn't been determined return + the maximum size range. */ + *pmin = 0; + return wi::to_offset (max_object_size ()); + } + /* add_offset() ensures the offset range isn't inverted. */ gcc_checking_assert (offrng[0] <= offrng[1]); @@ -1597,6 +1593,11 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref, { pref->ref = ptr; + /* Reset the offset in case it was set by a prior call and not + cleared by the caller. The offset is only adjusted after + the identity of the object has been determined. */ + pref->offrng[0] = pref->offrng[1] = 0; + if (!addr && POINTER_TYPE_P (TREE_TYPE (ptr))) { /* Set the maximum size if the reference is to the pointer @@ -1607,6 +1608,9 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref, return true; } + /* Valid offsets into the object are nonnegative. */ + pref->base0 = true; + if (tree size = decl_init_size (ptr, false)) if (TREE_CODE (size) == INTEGER_CST) { @@ -1960,6 +1964,11 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, { pointer_query qry; qry.rvals = rvals; + + /* Clear and invalidate in case *PREF is being reused. */ + pref->offrng[0] = pref->offrng[1] = 0; + pref->sizrng[0] = pref->sizrng[1] = -1; + ssa_name_limit_t snlim; if (!compute_objsize_r (ptr, ostype, pref, snlim, &qry)) return NULL_TREE; @@ -1982,6 +1991,10 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, pointer_query *ptr_qry) else ptr_qry = &qry; + /* Clear and invalidate in case *PREF is being reused. */ + pref->offrng[0] = pref->offrng[1] = 0; + pref->sizrng[0] = pref->sizrng[1] = -1; + ssa_name_limit_t snlim; if (!compute_objsize_r (ptr, ostype, pref, snlim, ptr_qry)) return NULL_TREE; diff --git a/gcc/testsuite/g++.dg/pr100574.C b/gcc/testsuite/g++.dg/pr100574.C index 42ba040..0df62aa 100644 --- a/gcc/testsuite/g++.dg/pr100574.C +++ b/gcc/testsuite/g++.dg/pr100574.C @@ -40,6 +40,8 @@ template template void vector<_Tp, _Alloc>::_M_realloc_insert() { __alloc_traits::pointer __trans_tmp_5; + /* __len is used uninitialized below, which might trigger warnings, + even without -Wall (and other than -Wuninitialized). */ long __len(__len || max_size()), __elems_before; __trans_tmp_5 = _M_allocate___n ? __alloc_traits::allocate(_M_impl, _M_allocate___n) @@ -62,3 +64,5 @@ void ReadTrackChunk() case MIDIST_PITCHBEND: block.data.push_back(); } + +// { dg-prune-output "warning" } diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-26.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-26.C new file mode 100644 index 0000000..f72ac9d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-26.C @@ -0,0 +1,27 @@ +/* PR middle-end/101600 - Spurious -Warray-bounds downcasting a polymorphic + pointer + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct S1 { virtual ~S1(); }; +struct S2 { int m; }; +struct S3 { virtual ~S3(); }; +struct S4: S1, S2, S3 {}; + +int f1 (); + +void f2 (S3 *); + +void f3 (S2 *p) +{ + for (int i = f1 (); f1 (); ) + { + if (i == 0) + { + p = 0; + break; + } + } + + f2 (static_cast(p)); // { dg-bogus "-Warray-bounds" } +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-88.c b/gcc/testsuite/gcc.dg/Warray-bounds-88.c new file mode 100644 index 0000000..8cee8d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-88.c @@ -0,0 +1,134 @@ +/* PR middle-end/101977 - bogus -Warray-bounds on a negative index into + a parameter in conditional with null + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct A { int i; }; +struct B { struct A a1; struct A a2; }; + + +void nowarn_p_0_0 (struct A *p, int i) +{ + struct A *q = i < 0 ? p : 0 < i ? (struct A*)0 : 0; + struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2)); + r->a1.i = 0; +} + +void nowarn_0_p_0 (struct A *p, int i) +{ + struct A *q = i < 0 ? 0 : 0 < i ? p : 0; + struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2)); + r->a1.i = 0; // { dg-bogus "-Warray-bounds" } +} + +void nowarn_0_0_p (struct A *p, int i) +{ + struct A *q = i < 0 ? 0 : 0 < i ? 0 : p; + struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2)); + r->a1.i = 0; // { dg-bogus "-Warray-bounds" } +} + + +void nowarn_p_q_0 (struct A *p, struct A *q, int i) +{ + struct A *r = i < 0 ? p : 0 < i ? q : 0; + struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2)); + s->a1.i = 0; // { dg-bogus "-Warray-bounds" } +} + +void nowarn_p_0_q (struct A *p, struct A *q, int i) +{ + struct A *r = i < 0 ? p : 0 < i ? 0 : q; + struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2)); + s->a1.i = 0; // { dg-bogus "-Warray-bounds" } +} + +void nowarn_0_p_q (struct A *p, struct A *q, int i) +{ + struct A *r = i < 0 ? 0 : 0 < i ? p : q; + struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2)); + s->a1.i = 0; +} + + +void nowarn_p_q_r (struct A *p, struct A *q, struct A *r, int i) +{ + struct A *s = i < 0 ? p : 0 < i ? q : r; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + + +extern struct B b1, b2, b3; + +void nowarn_p_b1_0 (struct A *p, int i) +{ + struct A *r = i < 0 ? p : 0 < i ? &b1.a2 : 0; + struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2)); + s->a1.i = 0; // { dg-bogus "-Warray-bounds" } +} + +void nowarn_p_0_b1 (struct A *p, int i) +{ + struct A *r = i < 0 ? p : 0 < i ? 0 : &b1.a2; + struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2)); + s->a1.i = 0; // { dg-bogus "-Warray-bounds" } +} + +void nowarn_0_p_b1 (struct A *p, int i) +{ + struct A *r = i < 0 ? 0 : 0 < i ? p : &b1.a2; + struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2)); + s->a1.i = 0; +} + + +void nowarn_p_b1_b2 (struct A *p, int i) +{ + struct A *s = i < 0 ? p : 0 < i ? &b1.a2 : &b2.a2; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + +void nowarn_b1_p_b2 (struct A *p, int i) +{ + struct A *s = i < 0 ? &b1.a2 : 0 < i ? p : &b2.a2; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + +void nowarn_b1_b2_p (struct A *p, int i) +{ + struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : p; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + +void nowarn_b1_b2_b3 (struct A *p, int i) +{ + struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : &b3.a2; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + + +void nowarn_0_b1_b2 (int i) +{ + struct A *s = i < 0 ? 0 : 0 < i ? &b1.a2 : &b2.a2; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + +void warn_b1_0_b2 (int i) +{ + struct A *s = i < 0 ? &b1.a2 : 0 < i ? 0 : &b2.a2; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} + +void warn_b1_b2_0 (int i) +{ + struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : 0; + struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2)); + t->a1.i = 0; +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread.c b/gcc/testsuite/gcc.dg/Wstringop-overread.c index 0343e43..7db7402 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overread.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overread.c @@ -317,9 +317,9 @@ void test_strnlen_array (int i, int i0, unsigned n) T (strnlen (a1, n)); T (strnlen (a1 + 1, 0)); - T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" } + T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" } T (strnlen (a1 + 1, i0)); - T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" } + T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' specified bound \\\[1, \\d+] exceeds source size 0" } T (strnlen (a1 + 1, n)); T (strnlen (a1 + i, 0)); T (strnlen (a1 + i, 1)); @@ -335,7 +335,7 @@ void test_strnlen_array (int i, int i0, unsigned n) T (strnlen (a1 + i0, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" } T (strnlen (a1 + i0, n)); T (strnlen (a1 + i0 + 1, 0)); - T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" } + T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" } T (strnlen (a1 + i0 + 1, n)); T (strnlen (a2, 0)); @@ -344,10 +344,10 @@ void test_strnlen_array (int i, int i0, unsigned n) T (strnlen (a2, n)); T (strnlen (a2 + 1, 0)); T (strnlen (a2 + 1, 1)); - T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" { xfail *-*-* } } + T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" } T (strnlen (a2 + 1, n)); T (strnlen (a2 + 2, 0)); - T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" } + T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" } T (strnlen (a2 + 2, n)); T (strnlen (a2 + i, 0)); T (strnlen (a2 + i, 1)); @@ -365,13 +365,13 @@ void test_strnlen_array (int i, int i0, unsigned n) T (strnlen (a2 + i0 + 1, 0)); T (strnlen (a2 + i0 + 1, 1)); - T (strnlen (a2 + i0 + 1, 2)); + T (strnlen (a2 + i0 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" } T (strnlen (a2 + i0 + 1, n)); T (strnlen (a2 + i0 + 2, 0)); - T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" } + T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" } T (strnlen (a2 + i0 + 2, i0)); - T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" } + T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' specified bound \\\[1, \\d+] exceeds source size 0" } T (strnlen (a2 + i0 + 2, n)); } @@ -512,9 +512,9 @@ void test_strndup_array (int i, int i0, unsigned n) T (strndup (a1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" } T (strndup (a1, n)); T (strndup (a1 + 1, 0)); - T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" } + T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" } T (strndup (a1 + 1, i0)); - T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" } + T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' specified bound \\\[1, \\d+] exceeds source size 0" } T (strndup (a1 + 1, n)); T (strndup (a1 + i, 0)); T (strndup (a1 + i, 1)); @@ -529,7 +529,7 @@ void test_strndup_array (int i, int i0, unsigned n) T (strndup (a1 + i0, 1)); T (strndup (a1 + i0, n)); T (strndup (a1 + i0 + 1, 0)); - T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" } + T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" } T (strndup (a1 + i0 + 1, n)); T (strndup (a2, 0)); @@ -538,10 +538,10 @@ void test_strndup_array (int i, int i0, unsigned n) T (strndup (a2, n)); T (strndup (a2 + 1, 0)); T (strndup (a2 + 1, 1)); - T (strndup (a2 + 1, 2)); + T (strndup (a2 + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" } T (strndup (a2 + 1, n)); T (strndup (a2 + 2, 0)); - T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" } + T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" } T (strndup (a2 + 2, n)); T (strndup (a2 + i, 0)); T (strndup (a2 + i, 1)); @@ -559,13 +559,13 @@ void test_strndup_array (int i, int i0, unsigned n) T (strndup (a2 + i0 + 1, 0)); T (strndup (a2 + i0 + 1, 1)); - T (strndup (a2 + i0 + 1, 2)); + T (strndup (a2 + i0 + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" } T (strndup (a2 + i0 + 1, n)); T (strndup (a2 + i0 + 2, 0)); - T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" } + T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" } T (strndup (a2 + i0 + 2, i0)); - T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" } + T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' specified bound \\\[1, \\d+] exceeds source size 0" } T (strndup (a2 + i0 + 2, n)); } diff --git a/gcc/testsuite/gcc.dg/pr20126.c b/gcc/testsuite/gcc.dg/pr20126.c index a421ce1..10aeec7 100644 --- a/gcc/testsuite/gcc.dg/pr20126.c +++ b/gcc/testsuite/gcc.dg/pr20126.c @@ -34,6 +34,10 @@ foo (S *x, S *y) while (e <= g) { const char *t = e + 1; + /* The pointer E below increases but the bound H stays constant, + letting the latter exceed the size remaining in the argument + pointed to by the formed, which might be detected by + -Wstringop-overread. */ if (__builtin_memcmp (e, f, h) == 0) return 1; e = t; @@ -48,3 +52,5 @@ main (void) abort (); return 0; } + +/* { dg-prune-output "-Wstringop-overread" } */ diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c index 2afd2b5..846e930 100644 --- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c +++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c @@ -143,14 +143,17 @@ T (v0 ? b[1] : "", bsz); T (v0 ? b[2] : "", bsz); T (v0 ? b[3] : "", bsz); -T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */ -T (v0 ? "" : b[1], bsz + 1); -T (v0 ? "" : b[2], bsz + 1); -T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ -T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */ -T (v0 ? b[1] : "", bsz + 1); -T (v0 ? b[2] : "", bsz + 1); -T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ +/* The warnings below are strictly correct but the strnlen calls are safe + because the reads are bounded by the length of the constant arguments. + It might make sense to relax the warning to avoid triggering for them. */ +T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? "" : b[1], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? "" : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[1] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[2] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ T (v0 ? "" : b[i0], bsz); T (v0 ? "" : b[i1], bsz); @@ -164,11 +167,11 @@ T (v0 ? b[i3] : "", bsz); T (v0 ? "" : b[i0], bsz + 1); T (v0 ? "" : b[i1], bsz + 1); T (v0 ? "" : b[i2], bsz + 1); -T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ +T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */ T (v0 ? b[i0] : "", bsz + 1); T (v0 ? b[i1] : "", bsz + 1); T (v0 ? b[i2] : "", bsz + 1); -T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ +T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */ T (v0 ? "1234" : b[3], bsz); T (v0 ? "1234" : b[i3], bsz); @@ -180,15 +183,15 @@ T (v0 ? b[0] : b[2], bsz); T (v0 ? b[2] : b[3], bsz); T (v0 ? b[3] : b[2], bsz); -T (v0 ? "1234" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ -T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ -T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ -T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ +T (v0 ? "1234" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ -T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" { xfail *-*-*} } */ -T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" } */ -T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ -T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */ +T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ +T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */ struct A { char a[5], b[5]; }; -- cgit v1.1 From 3c496e92d795a8fe5c527e3c5b5a6606669ae50d Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 24 Aug 2021 18:02:18 +0100 Subject: nvptx: Add a __PTX_SM__ predefined macro based on target ISA. This patch adds a __PTX_SM__ predefined macro to the nvptx backend that allows code to check the compute model being targeted by the compiler. This is equivalent to the __CUDA_ARCH__ macro defined by CUDA's nvcc compiler, but to avoid causing problems for source code that checks for that compiler, this macro uses GCC's nomenclature; it's easy enough for users to "#define __CUDA_ARCH__ __PTX_SM__". What might have been a four line patch is actually a little more complicated, as this patch takes the opportunity to upgrade the nvptx backend to use the now preferred nvptx-c.c idiom. 2021-08-24 Roger Sayle Tom de Vries gcc/ChangeLog * config.gcc (nvptx-*-*): Define {c,c++}_target_objs. * config/nvptx/nvptx-protos.h (nvptx_cpu_cpp_builtins): Prototype. * config/nvptx/nvptx.h (TARGET_CPU_CPP_BUILTINS): Implement with a call to the new nvptx_cpu_cpp_builtins function in nvptx-c.c. * config/nvptx/t-nvptx (nvptx-c.o): New rule. * config/nvptx/nvptx-c.c: New source file. (nvptx_cpu_cpp_builtins): Move implementation here. --- gcc/config.gcc | 2 ++ gcc/config/nvptx/nvptx-c.c | 47 +++++++++++++++++++++++++++++++++++++++++ gcc/config/nvptx/nvptx-protos.h | 1 + gcc/config/nvptx/nvptx.h | 12 +---------- gcc/config/nvptx/t-nvptx | 4 ++++ 5 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 gcc/config/nvptx/nvptx-c.c (limited to 'gcc') diff --git a/gcc/config.gcc b/gcc/config.gcc index 94199d7..0ff5cac 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -468,6 +468,8 @@ nios2-*-*) ;; nvptx-*-*) cpu_type=nvptx + c_target_objs="nvptx-c.o" + cxx_target_objs="nvptx-c.o" ;; or1k*-*-*) cpu_type=or1k diff --git a/gcc/config/nvptx/nvptx-c.c b/gcc/config/nvptx/nvptx-c.c new file mode 100644 index 0000000..72594a82e --- /dev/null +++ b/gcc/config/nvptx/nvptx-c.c @@ -0,0 +1,47 @@ +/* Subroutines for the C front end on the NVPTX architecture. + * Copyright (C) 2021 Free Software Foundation, Inc. + * + * This file is part of GCC. + * + * GCC is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 3, or (at your + * option) any later version. + * + * GCC is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GCC; see the file COPYING3. If not see + * . */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "c-family/c-common.h" +#include "memmodel.h" +#include "tm_p.h" +#include "c-family/c-pragma.h" + +/* Function to tell the preprocessor about the defines for the target. */ +void +nvptx_cpu_cpp_builtins (void) +{ + cpp_assert (parse_in, "machine=nvptx"); + cpp_assert (parse_in, "cpu=nvptx"); + cpp_define (parse_in, "__nvptx__"); + if (TARGET_SOFT_STACK) + cpp_define (parse_in, "__nvptx_softstack__"); + if (TARGET_UNIFORM_SIMT) + cpp_define (parse_in,"__nvptx_unisimt__"); + if (TARGET_SM35) + cpp_define (parse_in, "__PTX_SM__=350"); + else + cpp_define (parse_in,"__PTX_SM__=300"); +} + diff --git a/gcc/config/nvptx/nvptx-protos.h b/gcc/config/nvptx/nvptx-protos.h index b7e6ae2..b29ddc9 100644 --- a/gcc/config/nvptx/nvptx-protos.h +++ b/gcc/config/nvptx/nvptx-protos.h @@ -40,6 +40,7 @@ extern void nvptx_output_aligned_decl (FILE *file, const char *name, extern void nvptx_function_end (FILE *); extern void nvptx_output_skip (FILE *, unsigned HOST_WIDE_INT); extern void nvptx_output_ascii (FILE *, const char *, unsigned HOST_WIDE_INT); +extern void nvptx_cpu_cpp_builtins (void); extern void nvptx_register_pragmas (void); extern unsigned int nvptx_data_alignment (const_tree, unsigned int); diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h index fdaacdd..d367174 100644 --- a/gcc/config/nvptx/nvptx.h +++ b/gcc/config/nvptx/nvptx.h @@ -34,17 +34,7 @@ nvptx-as. */ #define ASM_SPEC "%{misa=*:-m %*; :-m sm_35}" -#define TARGET_CPU_CPP_BUILTINS() \ - do \ - { \ - builtin_assert ("machine=nvptx"); \ - builtin_assert ("cpu=nvptx"); \ - builtin_define ("__nvptx__"); \ - if (TARGET_SOFT_STACK) \ - builtin_define ("__nvptx_softstack__"); \ - if (TARGET_UNIFORM_SIMT) \ - builtin_define ("__nvptx_unisimt__"); \ - } while (0) +#define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins () /* Avoid the default in ../../gcc.c, which adds "-pthread", which is not supported for nvptx. */ diff --git a/gcc/config/nvptx/t-nvptx b/gcc/config/nvptx/t-nvptx index 6c1010d..d33bacd 100644 --- a/gcc/config/nvptx/t-nvptx +++ b/gcc/config/nvptx/t-nvptx @@ -1,3 +1,7 @@ +nvptx-c.o: $(srcdir)/config/nvptx/nvptx-c.c + $(COMPILE) $< + $(POSTCOMPILE) + CFLAGS-mkoffload.o += $(DRIVER_DEFINES) \ -DGCC_INSTALL_NAME=\"$(GCC_INSTALL_NAME)\" mkoffload.o: $(srcdir)/config/nvptx/mkoffload.c -- cgit v1.1 From 2ed356a4c9af0629d9d5fd30969e432de6302cb3 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Tue, 24 Aug 2021 10:01:47 -0500 Subject: rs6000: Add Power9 builtins 2021-08-24 Bill Schmidt gcc/ * config/rs6000/rs6000-builtin-new.def: Add power9-vector, power9, and power9-64 stanzas. --- gcc/config/rs6000/rs6000-builtin-new.def | 368 +++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) (limited to 'gcc') diff --git a/gcc/config/rs6000/rs6000-builtin-new.def b/gcc/config/rs6000/rs6000-builtin-new.def index 2a2c913..0462797 100644 --- a/gcc/config/rs6000/rs6000-builtin-new.def +++ b/gcc/config/rs6000/rs6000-builtin-new.def @@ -2438,3 +2438,371 @@ const double __builtin_vsx_xscvspdpn (vf); XSCVSPDPN vsx_xscvspdpn {} + + +; Power9 vector builtins. +[power9-vector] + const vss __builtin_altivec_convert_4f32_8f16 (vf, vf); + CONVERT_4F32_8F16 convert_4f32_8f16 {} + + const vss __builtin_altivec_convert_4f32_8i16 (vf, vf); + CONVERT_4F32_8I16 convert_4f32_8i16 {} + + const signed int __builtin_altivec_first_match_index_v16qi (vsc, vsc); + VFIRSTMATCHINDEX_V16QI first_match_index_v16qi {} + + const signed int __builtin_altivec_first_match_index_v8hi (vss, vss); + VFIRSTMATCHINDEX_V8HI first_match_index_v8hi {} + + const signed int __builtin_altivec_first_match_index_v4si (vsi, vsi); + VFIRSTMATCHINDEX_V4SI first_match_index_v4si {} + + const signed int __builtin_altivec_first_match_or_eos_index_v16qi (vsc, vsc); + VFIRSTMATCHOREOSINDEX_V16QI first_match_or_eos_index_v16qi {} + + const signed int __builtin_altivec_first_match_or_eos_index_v8hi (vss, vss); + VFIRSTMATCHOREOSINDEX_V8HI first_match_or_eos_index_v8hi {} + + const signed int __builtin_altivec_first_match_or_eos_index_v4si (vsi, vsi); + VFIRSTMATCHOREOSINDEX_V4SI first_match_or_eos_index_v4si {} + + const signed int __builtin_altivec_first_mismatch_index_v16qi (vsc, vsc); + VFIRSTMISMATCHINDEX_V16QI first_mismatch_index_v16qi {} + + const signed int __builtin_altivec_first_mismatch_index_v8hi (vss, vss); + VFIRSTMISMATCHINDEX_V8HI first_mismatch_index_v8hi {} + + const signed int __builtin_altivec_first_mismatch_index_v4si (vsi, vsi); + VFIRSTMISMATCHINDEX_V4SI first_mismatch_index_v4si {} + + const signed int __builtin_altivec_first_mismatch_or_eos_index_v16qi (vsc, vsc); + VFIRSTMISMATCHOREOSINDEX_V16QI first_mismatch_or_eos_index_v16qi {} + + const signed int __builtin_altivec_first_mismatch_or_eos_index_v8hi (vss, vss); + VFIRSTMISMATCHOREOSINDEX_V8HI first_mismatch_or_eos_index_v8hi {} + + const signed int __builtin_altivec_first_mismatch_or_eos_index_v4si (vsi, vsi); + VFIRSTMISMATCHOREOSINDEX_V4SI first_mismatch_or_eos_index_v4si {} + + const vsc __builtin_altivec_vadub (vsc, vsc); + VADUB vaduv16qi3 {} + + const vss __builtin_altivec_vaduh (vss, vss); + VADUH vaduv8hi3 {} + + const vsi __builtin_altivec_vaduw (vsi, vsi); + VADUW vaduv4si3 {} + + const vsll __builtin_altivec_vbpermd (vsll, vsc); + VBPERMD altivec_vbpermd {} + + const signed int __builtin_altivec_vclzlsbb_v16qi (vsc); + VCLZLSBB_V16QI vclzlsbb_v16qi {} + + const signed int __builtin_altivec_vclzlsbb_v4si (vsi); + VCLZLSBB_V4SI vclzlsbb_v4si {} + + const signed int __builtin_altivec_vclzlsbb_v8hi (vss); + VCLZLSBB_V8HI vclzlsbb_v8hi {} + + const vsc __builtin_altivec_vctzb (vsc); + VCTZB ctzv16qi2 {} + + const vsll __builtin_altivec_vctzd (vsll); + VCTZD ctzv2di2 {} + + const vss __builtin_altivec_vctzh (vss); + VCTZH ctzv8hi2 {} + + const vsi __builtin_altivec_vctzw (vsi); + VCTZW ctzv4si2 {} + + const signed int __builtin_altivec_vctzlsbb_v16qi (vsc); + VCTZLSBB_V16QI vctzlsbb_v16qi {} + + const signed int __builtin_altivec_vctzlsbb_v4si (vsi); + VCTZLSBB_V4SI vctzlsbb_v4si {} + + const signed int __builtin_altivec_vctzlsbb_v8hi (vss); + VCTZLSBB_V8HI vctzlsbb_v8hi {} + + const signed int __builtin_altivec_vcmpaeb_p (vsc, vsc); + VCMPAEB_P vector_ae_v16qi_p {} + + const signed int __builtin_altivec_vcmpaed_p (vsll, vsll); + VCMPAED_P vector_ae_v2di_p {} + + const signed int __builtin_altivec_vcmpaedp_p (vd, vd); + VCMPAEDP_P vector_ae_v2df_p {} + + const signed int __builtin_altivec_vcmpaefp_p (vf, vf); + VCMPAEFP_P vector_ae_v4sf_p {} + + const signed int __builtin_altivec_vcmpaeh_p (vss, vss); + VCMPAEH_P vector_ae_v8hi_p {} + + const signed int __builtin_altivec_vcmpaew_p (vsi, vsi); + VCMPAEW_P vector_ae_v4si_p {} + + const vsc __builtin_altivec_vcmpneb (vsc, vsc); + VCMPNEB vcmpneb {} + + const signed int __builtin_altivec_vcmpneb_p (vsc, vsc); + VCMPNEB_P vector_ne_v16qi_p {} + + const signed int __builtin_altivec_vcmpned_p (vsll, vsll); + VCMPNED_P vector_ne_v2di_p {} + + const signed int __builtin_altivec_vcmpnedp_p (vd, vd); + VCMPNEDP_P vector_ne_v2df_p {} + + const signed int __builtin_altivec_vcmpnefp_p (vf, vf); + VCMPNEFP_P vector_ne_v4sf_p {} + + const vss __builtin_altivec_vcmpneh (vss, vss); + VCMPNEH vcmpneh {} + + const signed int __builtin_altivec_vcmpneh_p (vss, vss); + VCMPNEH_P vector_ne_v8hi_p {} + + const vsi __builtin_altivec_vcmpnew (vsi, vsi); + VCMPNEW vcmpnew {} + + const signed int __builtin_altivec_vcmpnew_p (vsi, vsi); + VCMPNEW_P vector_ne_v4si_p {} + + const vsc __builtin_altivec_vcmpnezb (vsc, vsc); + CMPNEZB vcmpnezb {} + + const signed int __builtin_altivec_vcmpnezb_p (signed int, vsc, vsc); + VCMPNEZB_P vector_nez_v16qi_p {pred} + + const vss __builtin_altivec_vcmpnezh (vss, vss); + CMPNEZH vcmpnezh {} + + const signed int __builtin_altivec_vcmpnezh_p (signed int, vss, vss); + VCMPNEZH_P vector_nez_v8hi_p {pred} + + const vsi __builtin_altivec_vcmpnezw (vsi, vsi); + CMPNEZW vcmpnezw {} + + const signed int __builtin_altivec_vcmpnezw_p (signed int, vsi, vsi); + VCMPNEZW_P vector_nez_v4si_p {pred} + + const signed int __builtin_altivec_vextublx (signed int, vsc); + VEXTUBLX vextublx {} + + const signed int __builtin_altivec_vextubrx (signed int, vsc); + VEXTUBRX vextubrx {} + + const signed int __builtin_altivec_vextuhlx (signed int, vss); + VEXTUHLX vextuhlx {} + + const signed int __builtin_altivec_vextuhrx (signed int, vss); + VEXTUHRX vextuhrx {} + + const signed int __builtin_altivec_vextuwlx (signed int, vsi); + VEXTUWLX vextuwlx {} + + const signed int __builtin_altivec_vextuwrx (signed int, vsi); + VEXTUWRX vextuwrx {} + + const vsq __builtin_altivec_vmsumudm (vsll, vsll, vsq); + VMSUMUDM altivec_vmsumudm {} + + const vsll __builtin_altivec_vprtybd (vsll); + VPRTYBD parityv2di2 {} + + const vsq __builtin_altivec_vprtybq (vsq); + VPRTYBQ parityv1ti2 {} + + const vsi __builtin_altivec_vprtybw (vsi); + VPRTYBW parityv4si2 {} + + const vsll __builtin_altivec_vrldmi (vsll, vsll, vsll); + VRLDMI altivec_vrldmi {} + + const vsll __builtin_altivec_vrldnm (vsll, vsll); + VRLDNM altivec_vrldnm {} + + const vsi __builtin_altivec_vrlwmi (vsi, vsi, vsi); + VRLWMI altivec_vrlwmi {} + + const vsi __builtin_altivec_vrlwnm (vsi, vsi); + VRLWNM altivec_vrlwnm {} + + const vsll __builtin_altivec_vsignextsb2d (vsc); + VSIGNEXTSB2D vsignextend_qi_v2di {} + + const vsi __builtin_altivec_vsignextsb2w (vsc); + VSIGNEXTSB2W vsignextend_qi_v4si {} + + const vsll __builtin_altivec_visgnextsh2d (vss); + VSIGNEXTSH2D vsignextend_hi_v2di {} + + const vsi __builtin_altivec_vsignextsh2w (vss); + VSIGNEXTSH2W vsignextend_hi_v4si {} + + const vsll __builtin_altivec_vsignextsw2d (vsi); + VSIGNEXTSW2D vsignextend_si_v2di {} + + const vsc __builtin_altivec_vslv (vsc, vsc); + VSLV vslv {} + + const vsc __builtin_altivec_vsrv (vsc, vsc); + VSRV vsrv {} + + const signed int __builtin_scalar_byte_in_range (signed int, signed int); + CMPRB cmprb {} + + const signed int __builtin_scalar_byte_in_either_range (signed int, signed int); + CMPRB2 cmprb2 {} + + const vsll __builtin_vsx_extract4b (vsc, const int[0,12]); + EXTRACT4B extract4b {} + + const vd __builtin_vsx_extract_exp_dp (vd); + VEEDP xvxexpdp {} + + const vf __builtin_vsx_extract_exp_sp (vf); + VEESP xvxexpsp {} + + const vd __builtin_vsx_extract_sig_dp (vd); + VESDP xvxsigdp {} + + const vf __builtin_vsx_extract_sig_sp (vf); + VESSP xvxsigsp {} + + const vsc __builtin_vsx_insert4b (vsi, vsc, const int[0,12]); + INSERT4B insert4b {} + + const vd __builtin_vsx_insert_exp_dp (vd, vd); + VIEDP xviexpdp {} + + const vf __builtin_vsx_insert_exp_sp (vf, vf); + VIESP xviexpsp {} + + const signed int __builtin_vsx_scalar_cmp_exp_dp_eq (double, double); + VSCEDPEQ xscmpexpdp_eq {} + + const signed int __builtin_vsx_scalar_cmp_exp_dp_gt (double, double); + VSCEDPGT xscmpexpdp_gt {} + + const signed int __builtin_vsx_scalar_cmp_exp_dp_lt (double, double); + VSCEDPLT xscmpexpdp_lt {} + + const signed int __builtin_vsx_scalar_cmp_exp_dp_unordered (double, double); + VSCEDPUO xscmpexpdp_unordered {} + + const signed int __builtin_vsx_scalar_test_data_class_dp (double, const int<7>); + VSTDCDP xststdcdp {} + + const signed int __builtin_vsx_scalar_test_data_class_sp (float, const int<7>); + VSTDCSP xststdcsp {} + + const signed int __builtin_vsx_scalar_test_neg_dp (double); + VSTDCNDP xststdcnegdp {} + + const signed int __builtin_vsx_scalar_test_neg_sp (float); + VSTDCNSP xststdcnegsp {} + + const vsll __builtin_vsx_test_data_class_dp (vd, const int<7>); + VTDCDP xvtstdcdp {} + + const vsi __builtin_vsx_test_data_class_sp (vf, const int<7>); + VTDCSP xvtstdcsp {} + + const vf __builtin_vsx_vextract_fp_from_shorth (vss); + VEXTRACT_FP_FROM_SHORTH vextract_fp_from_shorth {} + + const vf __builtin_vsx_vextract_fp_from_shortl (vss); + VEXTRACT_FP_FROM_SHORTL vextract_fp_from_shortl {} + + const vd __builtin_vsx_xxbrd_v2df (vd); + XXBRD_V2DF p9_xxbrd_v2df {} + + const vsll __builtin_vsx_xxbrd_v2di (vsll); + XXBRD_V2DI p9_xxbrd_v2di {} + + const vss __builtin_vsx_xxbrh_v8hi (vss); + XXBRH_V8HI p9_xxbrh_v8hi {} + + const vsc __builtin_vsx_xxbrq_v16qi (vsc); + XXBRQ_V16QI p9_xxbrq_v16qi {} + + const vsq __builtin_vsx_xxbrq_v1ti (vsq); + XXBRQ_V1TI p9_xxbrq_v1ti {} + + const vf __builtin_vsx_xxbrw_v4sf (vf); + XXBRW_V4SF p9_xxbrw_v4sf {} + + const vsi __builtin_vsx_xxbrw_v4si (vsi); + XXBRW_V4SI p9_xxbrw_v4si {} + + +; Miscellaneous P9 functions +[power9] + signed long long __builtin_darn (); + DARN darn {} + + signed int __builtin_darn_32 (); + DARN_32 darn_32 {} + + signed long long __builtin_darn_raw (); + DARN_RAW darn_raw {} + + double __builtin_mffsl (); + MFFSL rs6000_mffsl {} + + const signed int __builtin_dtstsfi_eq_dd (const int<6>, _Decimal64); + TSTSFI_EQ_DD dfptstsfi_eq_dd {} + + const signed int __builtin_dtstsfi_eq_td (const int<6>, _Decimal128); + TSTSFI_EQ_TD dfptstsfi_eq_td {} + + const signed int __builtin_dtstsfi_gt_dd (const int<6>, _Decimal64); + TSTSFI_GT_DD dfptstsfi_gt_dd {} + + const signed int __builtin_dtstsfi_gt_td (const int<6>, _Decimal128); + TSTSFI_GT_TD dfptstsfi_gt_td {} + + const signed int __builtin_dtstsfi_lt_dd (const int<6>, _Decimal64); + TSTSFI_LT_DD dfptstsfi_lt_dd {} + + const signed int __builtin_dtstsfi_lt_td (const int<6>, _Decimal128); + TSTSFI_LT_TD dfptstsfi_lt_td {} + + const signed int __builtin_dtstsfi_ov_dd (const int<6>, _Decimal64); + TSTSFI_OV_DD dfptstsfi_unordered_dd {} + + const signed int __builtin_dtstsfi_ov_td (const int<6>, _Decimal128); + TSTSFI_OV_TD dfptstsfi_unordered_td {} + + +[power9-64] + void __builtin_altivec_xst_len_r (vsc, void *, long); + XST_LEN_R xst_len_r {} + + void __builtin_altivec_stxvl (vsc, void *, long); + STXVL stxvl {} + + const signed int __builtin_scalar_byte_in_set (signed int, signed long long); + CMPEQB cmpeqb {} + + pure vsc __builtin_vsx_lxvl (const void *, signed long); + LXVL lxvl {} + + const signed long __builtin_vsx_scalar_extract_exp (double); + VSEEDP xsxexpdp {} + + const signed long __builtin_vsx_scalar_extract_sig (double); + VSESDP xsxsigdp {} + + const double __builtin_vsx_scalar_insert_exp (unsigned long long, unsigned long long); + VSIEDP xsiexpdp {} + + const double __builtin_vsx_scalar_insert_exp_dp (double, unsigned long long); + VSIEDPF xsiexpdpf {} + + pure vsc __builtin_vsx_xl_len_r (void *, signed long); + XL_LEN_R xl_len_r {} -- cgit v1.1 From 19b7bf620cd4e610bb91b5d2ae5446a2b73b6308 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Tue, 24 Aug 2021 11:50:09 -0500 Subject: rs6000: Add more type nodes to support builtin processing 2021-08-24 Bill Schmidt gcc/ * config/rs6000/rs6000-call.c (rs6000_init_builtins): Initialize various pointer type nodes. * config/rs6000/rs6000.h (rs6000_builtin_type_index): Add enum values for various pointer types. (ptr_V16QI_type_node): New macro. (ptr_V1TI_type_node): New macro. (ptr_V2DI_type_node): New macro. (ptr_V2DF_type_node): New macro. (ptr_V4SI_type_node): New macro. (ptr_V4SF_type_node): New macro. (ptr_V8HI_type_node): New macro. (ptr_unsigned_V16QI_type_node): New macro. (ptr_unsigned_V1TI_type_node): New macro. (ptr_unsigned_V8HI_type_node): New macro. (ptr_unsigned_V4SI_type_node): New macro. (ptr_unsigned_V2DI_type_node): New macro. (ptr_bool_V16QI_type_node): New macro. (ptr_bool_V8HI_type_node): New macro. (ptr_bool_V4SI_type_node): New macro. (ptr_bool_V2DI_type_node): New macro. (ptr_bool_V1TI_type_node): New macro. (ptr_pixel_type_node): New macro. (ptr_intQI_type_node): New macro. (ptr_uintQI_type_node): New macro. (ptr_intHI_type_node): New macro. (ptr_uintHI_type_node): New macro. (ptr_intSI_type_node): New macro. (ptr_uintSI_type_node): New macro. (ptr_intDI_type_node): New macro. (ptr_uintDI_type_node): New macro. (ptr_intTI_type_node): New macro. (ptr_uintTI_type_node): New macro. (ptr_long_integer_type_node): New macro. (ptr_long_unsigned_type_node): New macro. (ptr_float_type_node): New macro. (ptr_double_type_node): New macro. (ptr_long_double_type_node): New macro. (ptr_dfloat64_type_node): New macro. (ptr_dfloat128_type_node): New macro. (ptr_ieee128_type_node): New macro. (ptr_ibm128_type_node): New macro. (ptr_vector_pair_type_node): New macro. (ptr_vector_quad_type_node): New macro. (ptr_long_long_integer_type_node): New macro. (ptr_long_long_unsigned_type_node): New macro. --- gcc/config/rs6000/rs6000-call.c | 148 +++++++++++++++++++++++++++++++++++++++- gcc/config/rs6000/rs6000.h | 82 ++++++++++++++++++++++ 2 files changed, 228 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c index 3c3108a..fd7f24d 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ b/gcc/config/rs6000/rs6000-call.c @@ -13294,6 +13294,7 @@ rs6000_init_builtins (void) { tree tdecl; tree ftype; + tree t; machine_mode mode; if (TARGET_DEBUG_BUILTIN) @@ -13304,25 +13305,63 @@ rs6000_init_builtins (void) V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long" : "__vector long long", long_long_integer_type_node, 2); + ptr_V2DI_type_node + = build_pointer_type (build_qualified_type (V2DI_type_node, + TYPE_QUAL_CONST)); + V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2); + ptr_V2DF_type_node + = build_pointer_type (build_qualified_type (V2DF_type_node, + TYPE_QUAL_CONST)); + V4SI_type_node = rs6000_vector_type ("__vector signed int", intSI_type_node, 4); + ptr_V4SI_type_node + = build_pointer_type (build_qualified_type (V4SI_type_node, + TYPE_QUAL_CONST)); + V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4); + ptr_V4SF_type_node + = build_pointer_type (build_qualified_type (V4SF_type_node, + TYPE_QUAL_CONST)); + V8HI_type_node = rs6000_vector_type ("__vector signed short", intHI_type_node, 8); + ptr_V8HI_type_node + = build_pointer_type (build_qualified_type (V8HI_type_node, + TYPE_QUAL_CONST)); + V16QI_type_node = rs6000_vector_type ("__vector signed char", intQI_type_node, 16); + ptr_V16QI_type_node + = build_pointer_type (build_qualified_type (V16QI_type_node, + TYPE_QUAL_CONST)); unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char", unsigned_intQI_type_node, 16); + ptr_unsigned_V16QI_type_node + = build_pointer_type (build_qualified_type (unsigned_V16QI_type_node, + TYPE_QUAL_CONST)); + unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short", unsigned_intHI_type_node, 8); + ptr_unsigned_V8HI_type_node + = build_pointer_type (build_qualified_type (unsigned_V8HI_type_node, + TYPE_QUAL_CONST)); + unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int", unsigned_intSI_type_node, 4); + ptr_unsigned_V4SI_type_node + = build_pointer_type (build_qualified_type (unsigned_V4SI_type_node, + TYPE_QUAL_CONST)); + unsigned_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector unsigned long" : "__vector unsigned long long", long_long_unsigned_type_node, 2); + ptr_unsigned_V2DI_type_node + = build_pointer_type (build_qualified_type (unsigned_V2DI_type_node, + TYPE_QUAL_CONST)); opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4); @@ -13336,9 +13375,15 @@ rs6000_init_builtins (void) { V1TI_type_node = rs6000_vector_type ("__vector __int128", intTI_type_node, 1); + ptr_V1TI_type_node + = build_pointer_type (build_qualified_type (V1TI_type_node, + TYPE_QUAL_CONST)); unsigned_V1TI_type_node = rs6000_vector_type ("__vector unsigned __int128", unsigned_intTI_type_node, 1); + ptr_unsigned_V1TI_type_node + = build_pointer_type (build_qualified_type (unsigned_V1TI_type_node, + TYPE_QUAL_CONST)); } /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...' @@ -13372,6 +13417,76 @@ rs6000_init_builtins (void) dfloat128_type_internal_node = dfloat128_type_node; void_type_internal_node = void_type_node; + ptr_intQI_type_node + = build_pointer_type (build_qualified_type (intQI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_uintQI_type_node + = build_pointer_type (build_qualified_type (uintQI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_intHI_type_node + = build_pointer_type (build_qualified_type (intHI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_uintHI_type_node + = build_pointer_type (build_qualified_type (uintHI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_intSI_type_node + = build_pointer_type (build_qualified_type (intSI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_uintSI_type_node + = build_pointer_type (build_qualified_type (uintSI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_intDI_type_node + = build_pointer_type (build_qualified_type (intDI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_uintDI_type_node + = build_pointer_type (build_qualified_type (uintDI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_intTI_type_node + = build_pointer_type (build_qualified_type (intTI_type_internal_node, + TYPE_QUAL_CONST)); + ptr_uintTI_type_node + = build_pointer_type (build_qualified_type (uintTI_type_internal_node, + TYPE_QUAL_CONST)); + + t = build_qualified_type (long_integer_type_internal_node, TYPE_QUAL_CONST); + ptr_long_integer_type_node = build_pointer_type (t); + + t = build_qualified_type (long_unsigned_type_internal_node, TYPE_QUAL_CONST); + ptr_long_unsigned_type_node = build_pointer_type (t); + + ptr_float_type_node + = build_pointer_type (build_qualified_type (float_type_internal_node, + TYPE_QUAL_CONST)); + ptr_double_type_node + = build_pointer_type (build_qualified_type (double_type_internal_node, + TYPE_QUAL_CONST)); + ptr_long_double_type_node + = build_pointer_type (build_qualified_type (long_double_type_internal_node, + TYPE_QUAL_CONST)); + if (dfloat64_type_node) + { + t = build_qualified_type (dfloat64_type_internal_node, TYPE_QUAL_CONST); + ptr_dfloat64_type_node = build_pointer_type (t); + } + else + ptr_dfloat64_type_node = NULL; + + if (dfloat128_type_node) + { + t = build_qualified_type (dfloat128_type_internal_node, TYPE_QUAL_CONST); + ptr_dfloat128_type_node = build_pointer_type (t); + } + else + ptr_dfloat128_type_node = NULL; + + t = build_qualified_type (long_long_integer_type_internal_node, + TYPE_QUAL_CONST); + ptr_long_long_integer_type_node = build_pointer_type (t); + + t = build_qualified_type (long_long_unsigned_type_internal_node, + TYPE_QUAL_CONST); + ptr_long_long_unsigned_type_node = build_pointer_type (t); + /* 128-bit floating point support. KFmode is IEEE 128-bit floating point. IFmode is the IBM extended 128-bit format that is a pair of doubles. TFmode will be either IEEE 128-bit floating point or the IBM double-double @@ -13399,7 +13514,8 @@ rs6000_init_builtins (void) SET_TYPE_MODE (ibm128_float_type_node, IFmode); layout_type (ibm128_float_type_node); } - + t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST); + ptr_ibm128_float_type_node = build_pointer_type (t); lang_hooks.types.register_builtin_type (ibm128_float_type_node, "__ibm128"); @@ -13407,7 +13523,8 @@ rs6000_init_builtins (void) ieee128_float_type_node = long_double_type_node; else ieee128_float_type_node = float128_type_node; - + t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST); + ptr_ieee128_float_type_node = build_pointer_type (t); lang_hooks.types.register_builtin_type (ieee128_float_type_node, "__ieee128"); } @@ -13427,6 +13544,8 @@ rs6000_init_builtins (void) TYPE_USER_ALIGN (vector_pair_type_node) = 0; lang_hooks.types.register_builtin_type (vector_pair_type_node, "__vector_pair"); + t = build_qualified_type (vector_pair_type_node, TYPE_QUAL_CONST); + ptr_vector_pair_type_node = build_pointer_type (t); vector_quad_type_node = make_node (OPAQUE_TYPE); SET_TYPE_MODE (vector_quad_type_node, XOmode); @@ -13437,6 +13556,8 @@ rs6000_init_builtins (void) TYPE_USER_ALIGN (vector_quad_type_node) = 0; lang_hooks.types.register_builtin_type (vector_quad_type_node, "__vector_quad"); + t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST); + ptr_vector_quad_type_node = build_pointer_type (t); } /* Initialize the modes for builtin_function_type, mapping a machine mode to @@ -13487,18 +13608,41 @@ rs6000_init_builtins (void) bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char", bool_char_type_node, 16); + ptr_bool_V16QI_type_node + = build_pointer_type (build_qualified_type (bool_V16QI_type_node, + TYPE_QUAL_CONST)); + bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short", bool_short_type_node, 8); + ptr_bool_V8HI_type_node + = build_pointer_type (build_qualified_type (bool_V8HI_type_node, + TYPE_QUAL_CONST)); + bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int", bool_int_type_node, 4); + ptr_bool_V4SI_type_node + = build_pointer_type (build_qualified_type (bool_V4SI_type_node, + TYPE_QUAL_CONST)); + bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector __bool long" : "__vector __bool long long", bool_long_long_type_node, 2); + ptr_bool_V2DI_type_node + = build_pointer_type (build_qualified_type (bool_V2DI_type_node, + TYPE_QUAL_CONST)); + bool_V1TI_type_node = rs6000_vector_type ("__vector __bool __int128", intTI_type_node, 1); + ptr_bool_V1TI_type_node + = build_pointer_type (build_qualified_type (bool_V1TI_type_node, + TYPE_QUAL_CONST)); + pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel", pixel_type_node, 8); + ptr_pixel_V8HI_type_node + = build_pointer_type (build_qualified_type (pixel_V8HI_type_node, + TYPE_QUAL_CONST)); pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST)); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index c5d20d2..3eba1c0 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2461,6 +2461,47 @@ enum rs6000_builtin_type_index RS6000_BTI_vector_pair, /* unsigned 256-bit types (vector pair). */ RS6000_BTI_vector_quad, /* unsigned 512-bit types (vector quad). */ RS6000_BTI_const_ptr_void, /* const pointer to void */ + RS6000_BTI_ptr_V16QI, + RS6000_BTI_ptr_V1TI, + RS6000_BTI_ptr_V2DI, + RS6000_BTI_ptr_V2DF, + RS6000_BTI_ptr_V4SI, + RS6000_BTI_ptr_V4SF, + RS6000_BTI_ptr_V8HI, + RS6000_BTI_ptr_unsigned_V16QI, + RS6000_BTI_ptr_unsigned_V1TI, + RS6000_BTI_ptr_unsigned_V8HI, + RS6000_BTI_ptr_unsigned_V4SI, + RS6000_BTI_ptr_unsigned_V2DI, + RS6000_BTI_ptr_bool_V16QI, + RS6000_BTI_ptr_bool_V8HI, + RS6000_BTI_ptr_bool_V4SI, + RS6000_BTI_ptr_bool_V2DI, + RS6000_BTI_ptr_bool_V1TI, + RS6000_BTI_ptr_pixel_V8HI, + RS6000_BTI_ptr_INTQI, + RS6000_BTI_ptr_UINTQI, + RS6000_BTI_ptr_INTHI, + RS6000_BTI_ptr_UINTHI, + RS6000_BTI_ptr_INTSI, + RS6000_BTI_ptr_UINTSI, + RS6000_BTI_ptr_INTDI, + RS6000_BTI_ptr_UINTDI, + RS6000_BTI_ptr_INTTI, + RS6000_BTI_ptr_UINTTI, + RS6000_BTI_ptr_long_integer, + RS6000_BTI_ptr_long_unsigned, + RS6000_BTI_ptr_float, + RS6000_BTI_ptr_double, + RS6000_BTI_ptr_long_double, + RS6000_BTI_ptr_dfloat64, + RS6000_BTI_ptr_dfloat128, + RS6000_BTI_ptr_ieee128_float, + RS6000_BTI_ptr_ibm128_float, + RS6000_BTI_ptr_vector_pair, + RS6000_BTI_ptr_vector_quad, + RS6000_BTI_ptr_long_long, + RS6000_BTI_ptr_long_long_unsigned, RS6000_BTI_MAX }; @@ -2517,6 +2558,47 @@ enum rs6000_builtin_type_index #define vector_pair_type_node (rs6000_builtin_types[RS6000_BTI_vector_pair]) #define vector_quad_type_node (rs6000_builtin_types[RS6000_BTI_vector_quad]) #define pcvoid_type_node (rs6000_builtin_types[RS6000_BTI_const_ptr_void]) +#define ptr_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V16QI]) +#define ptr_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V1TI]) +#define ptr_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V2DI]) +#define ptr_V2DF_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V2DF]) +#define ptr_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V4SI]) +#define ptr_V4SF_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V4SF]) +#define ptr_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V8HI]) +#define ptr_unsigned_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V16QI]) +#define ptr_unsigned_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V1TI]) +#define ptr_unsigned_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V8HI]) +#define ptr_unsigned_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V4SI]) +#define ptr_unsigned_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V2DI]) +#define ptr_bool_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V16QI]) +#define ptr_bool_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V8HI]) +#define ptr_bool_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V4SI]) +#define ptr_bool_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V2DI]) +#define ptr_bool_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V1TI]) +#define ptr_pixel_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_pixel_V8HI]) +#define ptr_intQI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTQI]) +#define ptr_uintQI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTQI]) +#define ptr_intHI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTHI]) +#define ptr_uintHI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTHI]) +#define ptr_intSI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTSI]) +#define ptr_uintSI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTSI]) +#define ptr_intDI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTDI]) +#define ptr_uintDI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTDI]) +#define ptr_intTI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTTI]) +#define ptr_uintTI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTTI]) +#define ptr_long_integer_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_integer]) +#define ptr_long_unsigned_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_unsigned]) +#define ptr_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_float]) +#define ptr_double_type_node (rs6000_builtin_types[RS6000_BTI_ptr_double]) +#define ptr_long_double_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_double]) +#define ptr_dfloat64_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat64]) +#define ptr_dfloat128_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat128]) +#define ptr_ieee128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ieee128_float]) +#define ptr_ibm128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ibm128_float]) +#define ptr_vector_pair_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair]) +#define ptr_vector_quad_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad]) +#define ptr_long_long_integer_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long]) +#define ptr_long_long_unsigned_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long_unsigned]) extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX]; extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; -- cgit v1.1 From 50cb8300d3bf0b487063784fbbe394301b6c79b2 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Wed, 28 Jul 2021 13:22:57 -0400 Subject: rs6000: Add Power10 builtins 2021-07-28 Bill Schmidt gcc/ * config/rs6000/rs6000-builtin-new.def: Add power10 and power10-64 stanzas. --- gcc/config/rs6000/rs6000-builtin-new.def | 523 +++++++++++++++++++++++++++++++ 1 file changed, 523 insertions(+) (limited to 'gcc') diff --git a/gcc/config/rs6000/rs6000-builtin-new.def b/gcc/config/rs6000/rs6000-builtin-new.def index 0462797..b6fc994 100644 --- a/gcc/config/rs6000/rs6000-builtin-new.def +++ b/gcc/config/rs6000/rs6000-builtin-new.def @@ -2806,3 +2806,526 @@ pure vsc __builtin_vsx_xl_len_r (void *, signed long); XL_LEN_R xl_len_r {} + + +[power10] + const vbq __builtin_altivec_cmpge_1ti (vsq, vsq); + CMPGE_1TI vector_nltv1ti {} + + const vbq __builtin_altivec_cmpge_u1ti (vuq, vuq); + CMPGE_U1TI vector_nltuv1ti {} + + const vbq __builtin_altivec_cmple_1ti (vsq, vsq); + CMPLE_1TI vector_ngtv1ti {} + + const vbq __builtin_altivec_cmple_u1ti (vuq, vuq); + CMPLE_U1TI vector_ngtuv1ti {} + + const unsigned long long __builtin_altivec_cntmbb (vuc, const int<1>); + VCNTMBB vec_cntmb_v16qi {} + + const unsigned long long __builtin_altivec_cntmbd (vull, const int<1>); + VCNTMBD vec_cntmb_v2di {} + + const unsigned long long __builtin_altivec_cntmbh (vus, const int<1>); + VCNTMBH vec_cntmb_v8hi {} + + const unsigned long long __builtin_altivec_cntmbw (vui, const int<1>); + VCNTMBW vec_cntmb_v4si {} + + const vsq __builtin_altivec_div_v1ti (vsq, vsq); + DIV_V1TI vsx_div_v1ti {} + + const vsq __builtin_altivec_dives (vsq, vsq); + DIVES_V1TI vsx_dives_v1ti {} + + const vuq __builtin_altivec_diveu (vuq, vuq); + DIVEU_V1TI vsx_diveu_v1ti {} + + const vsq __builtin_altivec_mods (vsq, vsq); + MODS_V1TI vsx_mods_v1ti {} + + const vuq __builtin_altivec_modu (vuq, vuq); + MODU_V1TI vsx_modu_v1ti {} + + const vuc __builtin_altivec_mtvsrbm (unsigned long long); + MTVSRBM vec_mtvsr_v16qi {} + + const vull __builtin_altivec_mtvsrdm (unsigned long long); + MTVSRDM vec_mtvsr_v2di {} + + const vus __builtin_altivec_mtvsrhm (unsigned long long); + MTVSRHM vec_mtvsr_v8hi {} + + const vuq __builtin_altivec_mtvsrqm (unsigned long long); + MTVSRQM vec_mtvsr_v1ti {} + + const vui __builtin_altivec_mtvsrwm (unsigned long long); + MTVSRWM vec_mtvsr_v4si {} + + pure signed __int128 __builtin_altivec_se_lxvrbx (signed long, const signed char *); + SE_LXVRBX vsx_lxvrbx {lxvrse} + + pure signed __int128 __builtin_altivec_se_lxvrhx (signed long, const signed short *); + SE_LXVRHX vsx_lxvrhx {lxvrse} + + pure signed __int128 __builtin_altivec_se_lxvrwx (signed long, const signed int *); + SE_LXVRWX vsx_lxvrwx {lxvrse} + + pure signed __int128 __builtin_altivec_se_lxvrdx (signed long, const signed long long *); + SE_LXVRDX vsx_lxvrdx {lxvrse} + + void __builtin_altivec_tr_stxvrbx (vsq, signed long, signed char *); + TR_STXVRBX vsx_stxvrbx {stvec} + + void __builtin_altivec_tr_stxvrhx (vsq, signed long, signed int *); + TR_STXVRHX vsx_stxvrhx {stvec} + + void __builtin_altivec_tr_stxvrwx (vsq, signed long, signed short *); + TR_STXVRWX vsx_stxvrwx {stvec} + + void __builtin_altivec_tr_stxvrdx (vsq, signed long, signed long long *); + TR_STXVRDX vsx_stxvrdx {stvec} + + const vuq __builtin_altivec_udiv_v1ti (vuq, vuq); + UDIV_V1TI vsx_udiv_v1ti {} + + const vull __builtin_altivec_vcfuged (vull, vull); + VCFUGED vcfuged {} + + const vsc __builtin_altivec_vclrlb (vsc, signed int); + VCLRLB vclrlb {} + + const vsc __builtin_altivec_vclrrb (vsc, signed int); + VCLRRB vclrrb {} + + const signed int __builtin_altivec_vcmpaet_p (vsq, vsq); + VCMPAET_P vector_ae_v1ti_p {} + + const vbq __builtin_altivec_vcmpequt (vsq, vsq); + VCMPEQUT vector_eqv1ti {} + + const signed int __builtin_altivec_vcmpequt_p (signed int, vsq, vsq); + VCMPEQUT_P vector_eq_v1ti_p {pred} + + const vbq __builtin_altivec_vcmpgtst (vsq, vsq); + VCMPGTST vector_gtv1ti {} + + const signed int __builtin_altivec_vcmpgtst_p (signed int, vsq, vsq); + VCMPGTST_P vector_gt_v1ti_p {pred} + + const vbq __builtin_altivec_vcmpgtut (vuq, vuq); + VCMPGTUT vector_gtuv1ti {} + + const signed int __builtin_altivec_vcmpgtut_p (signed int, vuq, vuq); + VCMPGTUT_P vector_gtu_v1ti_p {pred} + + const vbq __builtin_altivec_vcmpnet (vsq, vsq); + VCMPNET vcmpnet {} + + const signed int __builtin_altivec_vcmpnet_p (vsq, vsq); + VCMPNET_P vector_ne_v1ti_p {} + + const vull __builtin_altivec_vclzdm (vull, vull); + VCLZDM vclzdm {} + + const vull __builtin_altivec_vctzdm (vull, vull); + VCTZDM vctzdm {} + + const vsll __builtin_altivec_vdivesd (vsll, vsll); + VDIVESD dives_v2di {} + + const vsi __builtin_altivec_vdivesw (vsi, vsi); + VDIVESW dives_v4si {} + + const vull __builtin_altivec_vdiveud (vull, vull); + VDIVEUD diveu_v2di {} + + const vui __builtin_altivec_vdiveuw (vui, vui); + VDIVEUW diveu_v4si {} + + const vsll __builtin_altivec_vdivsd (vsll, vsll); + VDIVSD divv2di3 {} + + const vsi __builtin_altivec_vdivsw (vsi, vsi); + VDIVSW divv4si3 {} + + const vull __builtin_altivec_vdivud (vull, vull); + VDIVUD udivv2di3 {} + + const vui __builtin_altivec_vdivuw (vui, vui); + VDIVUW udivv4si3 {} + + const vuc __builtin_altivec_vexpandmb (vuc); + VEXPANDMB vec_expand_v16qi {} + + const vull __builtin_altivec_vexpandmd (vull); + VEXPANDMD vec_expand_v2di {} + + const vus __builtin_altivec_vexpandmh (vus); + VEXPANDMH vec_expand_v8hi {} + + const vuq __builtin_altivec_vexpandmq (vuq); + VEXPANDMQ vec_expand_v1ti {} + + const vui __builtin_altivec_vexpandmw (vui); + VEXPANDMW vec_expand_v4si {} + + const vull __builtin_altivec_vextddvhx (vull, vull, unsigned int); + VEXTRACTDR vextractrv2di {} + + const vull __builtin_altivec_vextddvlx (vull, vull, unsigned int); + VEXTRACTDL vextractlv2di {} + + const vull __builtin_altivec_vextdubvhx (vuc, vuc, unsigned int); + VEXTRACTBR vextractrv16qi {} + + const vull __builtin_altivec_vextdubvlx (vuc, vuc, unsigned int); + VEXTRACTBL vextractlv16qi {} + + const vull __builtin_altivec_vextduhvhx (vus, vus, unsigned int); + VEXTRACTHR vextractrv8hi {} + + const vull __builtin_altivec_vextduhvlx (vus, vus, unsigned int); + VEXTRACTHL vextractlv8hi {} + + const vull __builtin_altivec_vextduwvhx (vui, vui, unsigned int); + VEXTRACTWR vextractrv4si {} + + const vull __builtin_altivec_vextduwvlx (vui, vui, unsigned int); + VEXTRACTWL vextractlv4si {} + + const signed int __builtin_altivec_vextractmb (vsc); + VEXTRACTMB vec_extract_v16qi {} + + const signed int __builtin_altivec_vextractmd (vsll); + VEXTRACTMD vec_extract_v2di {} + + const signed int __builtin_altivec_vextractmh (vss); + VEXTRACTMH vec_extract_v8hi {} + + const signed int __builtin_altivec_vextractmq (vsq); + VEXTRACTMQ vec_extract_v1ti {} + + const signed int __builtin_altivec_vextractmw (vsi); + VEXTRACTMW vec_extract_v4si {} + + const unsigned long long __builtin_altivec_vgnb (vull, const int <2,7>); + VGNB vgnb {} + + const vuc __builtin_altivec_vinsgubvlx (unsigned int, vuc, unsigned int); + VINSERTGPRBL vinsertgl_v16qi {} + + const vsc __builtin_altivec_vinsgubvrx (signed int, vsc, signed int); + VINSERTGPRBR vinsertgr_v16qi {} + + const vull __builtin_altivec_vinsgudvlx (unsigned int, vull, unsigned int); + VINSERTGPRDL vinsertgl_v2di {} + + const vsll __builtin_altivec_vinsgudvrx (signed int, vsll, signed int); + VINSERTGPRDR vinsertgr_v2di {} + + const vus __builtin_altivec_vinsguhvlx (unsigned int, vus, unsigned int); + VINSERTGPRHL vinsertgl_v8hi {} + + const vss __builtin_altivec_vinsguhvrx (signed int, vss, signed int); + VINSERTGPRHR vinsertgr_v8hi {} + + const vui __builtin_altivec_vinsguwvlx (unsigned int, vui, unsigned int); + VINSERTGPRWL vinsertgl_v4si {} + + const vsi __builtin_altivec_vinsguwvrx (signed int, vsi, signed int); + VINSERTGPRWR vinsertgr_v4si {} + + const vuc __builtin_altivec_vinsvubvlx (vuc, vuc, unsigned int); + VINSERTVPRBL vinsertvl_v16qi {} + + const vsc __builtin_altivec_vinsvubvrx (vsc, vsc, signed int); + VINSERTVPRBR vinsertvr_v16qi {} + + const vus __builtin_altivec_vinsvuhvlx (vus, vus, unsigned int); + VINSERTVPRHL vinsertvl_v8hi {} + + const vss __builtin_altivec_vinsvuhvrx (vss, vss, signed int); + VINSERTVPRHR vinsertvr_v8hi {} + + const vui __builtin_altivec_vinsvuwvlx (vui, vui, unsigned int); + VINSERTVPRWL vinsertvl_v4si {} + + const vsi __builtin_altivec_vinsvuwvrx (vsi, vsi, signed int); + VINSERTVPRWR vinsertvr_v4si {} + + const vsll __builtin_altivec_vmodsd (vsll, vsll); + VMODSD modv2di3 {} + + const vsi __builtin_altivec_vmodsw (vsi, vsi); + VMODSW modv4si3 {} + + const vull __builtin_altivec_vmodud (vull, vull); + VMODUD umodv2di3 {} + + const vui __builtin_altivec_vmoduw (vui, vui); + VMODUW umodv4si3 {} + + const vsq __builtin_altivec_vmulesd (vsll, vsll); + VMULESD vec_widen_smult_even_v2di {} + + const vuq __builtin_altivec_vmuleud (vull, vull); + VMULEUD vec_widen_umult_even_v2di {} + + const vsll __builtin_altivec_vmulhsd (vsll, vsll); + VMULHSD smulv2di3_highpart {} + + const vsi __builtin_altivec_vmulhsw (vsi, vsi); + VMULHSW smulv4si3_highpart {} + + const vull __builtin_altivec_vmulhud (vull, vull); + VMULHUD umulv2di3_highpart {} + + const vui __builtin_altivec_vmulhuw (vui, vui); + VMULHUW umulv4si3_highpart {} + + const vsll __builtin_altivec_vmulld (vsll, vsll); + VMULLD mulv2di3 {} + + const vsq __builtin_altivec_vmulosd (vsll, vsll); + VMULOSD vec_widen_smult_odd_v2di {} + + const vuq __builtin_altivec_vmuloud (vull, vull); + VMULOUD vec_widen_umult_odd_v2di {} + + const vsq __builtin_altivec_vnor_v1ti (vsq, vsq); + VNOR_V1TI norv1ti3 {} + + const vuq __builtin_altivec_vnor_v1ti_uns (vuq, vuq); + VNOR_V1TI_UNS norv1ti3 {} + + const vull __builtin_altivec_vpdepd (vull, vull); + VPDEPD vpdepd {} + + const vull __builtin_altivec_vpextd (vull, vull); + VPEXTD vpextd {} + + const vull __builtin_altivec_vreplace_un_uv2di (vull, unsigned long long, const int<4>); + VREPLACE_UN_UV2DI vreplace_un_v2di {} + + const vui __builtin_altivec_vreplace_un_uv4si (vui, unsigned int, const int<4>); + VREPLACE_UN_UV4SI vreplace_un_v4si {} + + const vd __builtin_altivec_vreplace_un_v2df (vd, double, const int<4>); + VREPLACE_UN_V2DF vreplace_un_v2df {} + + const vsll __builtin_altivec_vreplace_un_v2di (vsll, signed long long, const int<4>); + VREPLACE_UN_V2DI vreplace_un_v2di {} + + const vf __builtin_altivec_vreplace_un_v4sf (vf, float, const int<4>); + VREPLACE_UN_V4SF vreplace_un_v4sf {} + + const vsi __builtin_altivec_vreplace_un_v4si (vsi, signed int, const int<4>); + VREPLACE_UN_V4SI vreplace_un_v4si {} + + const vull __builtin_altivec_vreplace_uv2di (vull, unsigned long long, const int<1>); + VREPLACE_ELT_UV2DI vreplace_elt_v2di {} + + const vui __builtin_altivec_vreplace_uv4si (vui, unsigned int, const int<2>); + VREPLACE_ELT_UV4SI vreplace_elt_v4si {} + + const vd __builtin_altivec_vreplace_v2df (vd, double, const int<1>); + VREPLACE_ELT_V2DF vreplace_elt_v2df {} + + const vsll __builtin_altivec_vreplace_v2di (vsll, signed long long, const int<1>); + VREPLACE_ELT_V2DI vreplace_elt_v2di {} + + const vf __builtin_altivec_vreplace_v4sf (vf, float, const int<2>); + VREPLACE_ELT_V4SF vreplace_elt_v4sf {} + + const vsi __builtin_altivec_vreplace_v4si (vsi, signed int, const int<2>); + VREPLACE_ELT_V4SI vreplace_elt_v4si {} + + const vsq __builtin_altivec_vrlq (vsq, vuq); + VRLQ vrotlv1ti3 {} + + const vsq __builtin_altivec_vrlqmi (vsq, vsq, vuq); + VRLQMI altivec_vrlqmi {} + + const vsq __builtin_altivec_vrlqnm (vsq, vuq); + VRLQNM altivec_vrlqnm {} + + const vsq __builtin_altivec_vsignext (vsll); + VSIGNEXTSD2Q vsignextend_v2di_v1ti {} + + const vsc __builtin_altivec_vsldb_v16qi (vsc, vsc, const int<3>); + VSLDB_V16QI vsldb_v16qi {} + + const vsll __builtin_altivec_vsldb_v2di (vsll, vsll, const int<3>); + VSLDB_V2DI vsldb_v2di {} + + const vsi __builtin_altivec_vsldb_v4si (vsi, vsi, const int<3>); + VSLDB_V4SI vsldb_v4si {} + + const vss __builtin_altivec_vsldb_v8hi (vss, vss, const int<3>); + VSLDB_V8HI vsldb_v8hi {} + + const vsq __builtin_altivec_vslq (vsq, vuq); + VSLQ vashlv1ti3 {} + + const vsq __builtin_altivec_vsraq (vsq, vuq); + VSRAQ vashrv1ti3 {} + + const vsc __builtin_altivec_vsrdb_v16qi (vsc, vsc, const int<3>); + VSRDB_V16QI vsrdb_v16qi {} + + const vsll __builtin_altivec_vsrdb_v2di (vsll, vsll, const int<3>); + VSRDB_V2DI vsrdb_v2di {} + + const vsi __builtin_altivec_vsrdb_v4si (vsi, vsi, const int<3>); + VSRDB_V4SI vsrdb_v4si {} + + const vss __builtin_altivec_vsrdb_v8hi (vss, vss, const int<3>); + VSRDB_V8HI vsrdb_v8hi {} + + const vsq __builtin_altivec_vsrq (vsq, vuq); + VSRQ vlshrv1ti3 {} + + const vsc __builtin_altivec_vstribl (vsc); + VSTRIBL vstril_v16qi {} + + const signed int __builtin_altivec_vstribl_p (vsc); + VSTRIBL_P vstril_p_v16qi {} + + const vsc __builtin_altivec_vstribr (vsc); + VSTRIBR vstrir_v16qi {} + + const signed int __builtin_altivec_vstribr_p (vsc); + VSTRIBR_P vstrir_p_v16qi {} + + const vss __builtin_altivec_vstrihl (vss); + VSTRIHL vstril_v8hi {} + + const signed int __builtin_altivec_vstrihl_p (vss); + VSTRIHL_P vstril_p_v8hi {} + + const vss __builtin_altivec_vstrihr (vss); + VSTRIHR vstrir_v8hi {} + + const signed int __builtin_altivec_vstrihr_p (vss); + VSTRIHR_P vstrir_p_v8hi {} + + const signed int __builtin_vsx_xvtlsbb_all_ones (vsc); + XVTLSBB_ONES xvtlsbbo {} + + const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc); + XVTLSBB_ZEROS xvtlsbbz {} + + const vf __builtin_vsx_vxxsplti32dx_v4sf (vf, const int<1>, float); + VXXSPLTI32DX_V4SF xxsplti32dx_v4sf {} + + const vsi __builtin_vsx_vxxsplti32dx_v4si (vsi, const int<1>, signed int); + VXXSPLTI32DX_V4SI xxsplti32dx_v4si {} + + const vd __builtin_vsx_vxxspltidp (float); + VXXSPLTIDP xxspltidp_v2df {} + + const vf __builtin_vsx_vxxspltiw_v4sf (float); + VXXSPLTIW_V4SF xxspltiw_v4sf {} + + const vsi __builtin_vsx_vxxspltiw_v4si (signed int); + VXXSPLTIW_V4SI xxspltiw_v4si {} + + const vuc __builtin_vsx_xvcvbf16spn (vuc); + XVCVBF16SPN vsx_xvcvbf16spn {} + + const vuc __builtin_vsx_xvcvspbf16 (vuc); + XVCVSPBF16 vsx_xvcvspbf16 {} + + const vuc __builtin_vsx_xxblend_v16qi (vuc, vuc, vuc); + VXXBLEND_V16QI xxblend_v16qi {} + + const vd __builtin_vsx_xxblend_v2df (vd, vd, vd); + VXXBLEND_V2DF xxblend_v2df {} + + const vull __builtin_vsx_xxblend_v2di (vull, vull, vull); + VXXBLEND_V2DI xxblend_v2di {} + + const vf __builtin_vsx_xxblend_v4sf (vf, vf, vf); + VXXBLEND_V4SF xxblend_v4sf {} + + const vui __builtin_vsx_xxblend_v4si (vui, vui, vui); + VXXBLEND_V4SI xxblend_v4si {} + + const vus __builtin_vsx_xxblend_v8hi (vus, vus, vus); + VXXBLEND_V8HI xxblend_v8hi {} + + const vull __builtin_vsx_xxeval (vull, vull, vull, const int <8>); + XXEVAL xxeval {} + + const vuc __builtin_vsx_xxgenpcvm_v16qi (vuc, const int <2>); + XXGENPCVM_V16QI xxgenpcvm_v16qi {} + + const vull __builtin_vsx_xxgenpcvm_v2di (vull, const int <2>); + XXGENPCVM_V2DI xxgenpcvm_v2di {} + + const vui __builtin_vsx_xxgenpcvm_v4si (vui, const int <2>); + XXGENPCVM_V4SI xxgenpcvm_v4si {} + + const vus __builtin_vsx_xxgenpcvm_v8hi (vus, const int <2>); + XXGENPCVM_V8HI xxgenpcvm_v8hi {} + + const vuc __builtin_vsx_xxpermx_uv16qi (vuc, vuc, vuc, const int<3>); + XXPERMX_UV16QI xxpermx {} + + const vull __builtin_vsx_xxpermx_uv2di (vull, vull, vuc, const int<3>); + XXPERMX_UV2DI xxpermx {} + + const vui __builtin_vsx_xxpermx_uv4si (vui, vui, vuc, const int<3>); + XXPERMX_UV4SI xxpermx {} + + const vus __builtin_vsx_xxpermx_uv8hi (vus, vus, vuc, const int<3>); + XXPERMX_UV8HI xxpermx {} + + const vsc __builtin_vsx_xxpermx_v16qi (vsc, vsc, vuc, const int<3>); + XXPERMX_V16QI xxpermx {} + + const vd __builtin_vsx_xxpermx_v2df (vd, vd, vuc, const int<3>); + XXPERMX_V2DF xxpermx {} + + const vsll __builtin_vsx_xxpermx_v2di (vsll, vsll, vuc, const int<3>); + XXPERMX_V2DI xxpermx {} + + const vf __builtin_vsx_xxpermx_v4sf (vf, vf, vuc, const int<3>); + XXPERMX_V4SF xxpermx {} + + const vsi __builtin_vsx_xxpermx_v4si (vsi, vsi, vuc, const int<3>); + XXPERMX_V4SI xxpermx {} + + const vss __builtin_vsx_xxpermx_v8hi (vss, vss, vuc, const int<3>); + XXPERMX_V8HI xxpermx {} + + pure unsigned __int128 __builtin_altivec_ze_lxvrbx (signed long, const unsigned char *); + ZE_LXVRBX vsx_lxvrbx {lxvrze} + + pure unsigned __int128 __builtin_altivec_ze_lxvrhx (signed long, const unsigned short *); + ZE_LXVRHX vsx_lxvrhx {lxvrze} + + pure unsigned __int128 __builtin_altivec_ze_lxvrwx (signed long, const unsigned int *); + ZE_LXVRWX vsx_lxvrwx {lxvrze} + + pure unsigned __int128 __builtin_altivec_ze_lxvrdx (signed long, const unsigned long long *); + ZE_LXVRDX vsx_lxvrdx {lxvrze} + + +[power10-64] + const unsigned long long __builtin_cfuged (unsigned long long, unsigned long long); + CFUGED cfuged {} + + const unsigned long long __builtin_cntlzdm (unsigned long long, unsigned long long); + CNTLZDM cntlzdm {} + + const unsigned long long __builtin_cnttzdm (unsigned long long, unsigned long long); + CNTTZDM cnttzdm {} + + const unsigned long long __builtin_pdepd (unsigned long long, unsigned long long); + PDEPD pdepd {} + + const unsigned long long __builtin_pextd (unsigned long long, unsigned long long); + PEXTD pextd {} -- cgit v1.1 From f95946afd160e2a1f4beac4ee5e6d5633307f39a Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Tue, 24 Aug 2021 21:07:50 +0200 Subject: Fortran: fix pointless warning for static variables gcc/fortran/ChangeLog: PR fortran/98411 * trans-decl.c (gfc_finish_var_decl): Adjust check to handle implicit SAVE as well as variables in the main program. Improve warning message text. gcc/testsuite/ChangeLog: PR fortran/98411 * gfortran.dg/pr98411.f90: Adjust testcase options to restrict to F2008, and verify case of implicit SAVE. --- gcc/fortran/trans-decl.c | 20 +++++++++++++------- gcc/testsuite/gfortran.dg/pr98411.f90 | 4 +++- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 784f7b6..bed61e2 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -743,8 +743,10 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) /* Keep variables larger than max-stack-var-size off stack. */ if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive) + && !(sym->ns->proc_name && sym->ns->proc_name->attr.is_main_program) && !sym->attr.automatic && sym->attr.save != SAVE_EXPLICIT + && sym->attr.save != SAVE_IMPLICIT && INTEGER_CST_P (DECL_SIZE_UNIT (decl)) && !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)) /* Put variable length auto array pointers always into stack. */ @@ -757,13 +759,17 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) { if (flag_max_stack_var_size > 0) gfc_warning (OPT_Wsurprising, - "Array %qs at %L is larger than limit set by" - " %<-fmax-stack-var-size=%>, moved from stack to static" - " storage. This makes the procedure unsafe when called" - " recursively, or concurrently from multiple threads." - " Consider using %<-frecursive%>, or increase the" - " %<-fmax-stack-var-size=%> limit, or change the code to" - " use an ALLOCATABLE array.", + "Array %qs at %L is larger than limit set by " + "%<-fmax-stack-var-size=%>, moved from stack to static " + "storage. This makes the procedure unsafe when called " + "recursively, or concurrently from multiple threads. " + "Consider increasing the %<-fmax-stack-var-size=%> " + "limit (or use %<-frecursive%>, which implies " + "unlimited %<-fmax-stack-var-size%>) - or change the " + "code to use an ALLOCATABLE array. If the variable is " + "never accessed concurrently, this warning can be " + "ignored, and the variable could also be declared with " + "the SAVE attribute.", sym->name, &sym->declared_at); TREE_STATIC (decl) = 1; diff --git a/gcc/testsuite/gfortran.dg/pr98411.f90 b/gcc/testsuite/gfortran.dg/pr98411.f90 index 249afae..7c906a9 100644 --- a/gcc/testsuite/gfortran.dg/pr98411.f90 +++ b/gcc/testsuite/gfortran.dg/pr98411.f90 @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-Wall -fautomatic -fmax-stack-var-size=100" } +! { dg-options "-std=f2008 -Wall -fautomatic -fmax-stack-var-size=100" } ! PR fortran/98411 - Pointless warning for static variables module try @@ -9,8 +9,10 @@ contains subroutine initmodule real, save :: b(1000) logical :: c(1000) ! { dg-warning "moved from stack to static storage" } + integer :: e(1000) = 1 a(1) = 42 b(2) = 3.14 c(3) = .true. + e(5) = -1 end subroutine initmodule end module try -- cgit v1.1 From 81e1894456bc6214c0c42148ff2b1bed142a3545 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 24 Aug 2021 22:07:41 +0100 Subject: [Committed] PR middle-end/102031: Fix typo/mistake in simplify_truncation patch. My apologies again. My patch to simplify truncations of SUBREGs in simplify-rtx.c contained an error where I'd accidentally compared against a mode instead of the precision of that mode. Grr! It even survived regression testing on two platforms. Fixed below, and committed as obvious, after a full "make bootstrap" and "make -k check" on x86_64-pc-linux-gnu with no new regressions. 2021-08-24 Roger Sayle gcc/ChangeLog PR middle-end/102031 * simplify-rtx.c (simplify_truncation): When comparing precisions use "subreg_prec" variable, not "subreg_mode". --- gcc/simplify-rtx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 8eea9fb..c81e27e 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -841,7 +841,7 @@ simplify_context::simplify_truncation (machine_mode mode, rtx op, { unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode); unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode); - if (int_op_prec > subreg_mode) + if (int_op_prec > subreg_prec) { if (int_mode == subreg_mode) return SUBREG_REG (op); @@ -851,7 +851,7 @@ simplify_context::simplify_truncation (machine_mode mode, rtx op, } /* Simplification of (truncate:A (subreg:B X:C 0)) where A is narrower than B and B is narrower than C. */ - else if (int_op_prec < subreg_mode + else if (int_op_prec < subreg_prec && GET_MODE_PRECISION (int_mode) < int_op_prec) return simplify_gen_unary (TRUNCATE, int_mode, SUBREG_REG (op), subreg_mode); -- cgit v1.1 From 9cf3f026e281f5eb978a78055d8949a3295b7f10 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Tue, 24 Aug 2021 16:48:57 -0400 Subject: aix: SYSTEM_IMPLICIT_EXTERN_C AIX 7.3 system headers are C++ safe and GCC no longer needs to define SYSTEM_IMPLICIT_EXTERN_C for AIX 7.3. This patch moves the definition from aix.h to the individual OS-level configuration files and does not define the macro for AIX 7.3. The patch also corrects the definition of TARGET_AIX_VERSION to 73. gcc/ChangeLog: * config/rs6000/aix.h (SYSTEM_IMPLICIT_EXTERN_C): Delete. * config/rs6000/aix71.h (SYSTEM_IMPLICIT_EXTERN_C): Define. * config/rs6000/aix72.h (SYSTEM_IMPLICIT_EXTERN_C): Define. * config/rs6000/aix73.h (TARGET_AIX_VERSION): Increase to 73. --- gcc/config/rs6000/aix.h | 4 +--- gcc/config/rs6000/aix71.h | 4 ++++ gcc/config/rs6000/aix72.h | 3 +++ gcc/config/rs6000/aix73.h | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 662785c..0f4d8cb 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0-or-later /* Definitions of target machine for GNU compiler, for IBM RS/6000 POWER running AIX. Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -23,9 +24,6 @@ #undef TARGET_AIX #define TARGET_AIX 1 -/* System headers are not C++-aware. */ -#define SYSTEM_IMPLICIT_EXTERN_C 1 - /* Linux64.h wants to redefine TARGET_AIX based on -m64, but it can't be used in the #if conditional in options-default.h, so provide another macro. */ #undef TARGET_AIX_OS diff --git a/gcc/config/rs6000/aix71.h b/gcc/config/rs6000/aix71.h index 38cfa9e..1bc1560 100644 --- a/gcc/config/rs6000/aix71.h +++ b/gcc/config/rs6000/aix71.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0-or-later /* Definitions of target machine for GNU compiler, for IBM RS/6000 POWER running AIX V7.1. Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -268,6 +269,9 @@ extern long long int atoll(const char *); #define SET_CMODEL(opt) do {} while (0) #endif +/* System headers are not C++-aware. */ +#define SYSTEM_IMPLICIT_EXTERN_C 1 + /* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, but does not have crtbegin/end. */ diff --git a/gcc/config/rs6000/aix72.h b/gcc/config/rs6000/aix72.h index a497a7d..cca64f1 100644 --- a/gcc/config/rs6000/aix72.h +++ b/gcc/config/rs6000/aix72.h @@ -270,6 +270,9 @@ extern long long int atoll(const char *); #define SET_CMODEL(opt) do {} while (0) #endif +/* System headers are not C++-aware. */ +#define SYSTEM_IMPLICIT_EXTERN_C 1 + /* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, but does not have crtbegin/end. */ diff --git a/gcc/config/rs6000/aix73.h b/gcc/config/rs6000/aix73.h index c707c7e..f0ca1a5 100644 --- a/gcc/config/rs6000/aix73.h +++ b/gcc/config/rs6000/aix73.h @@ -274,7 +274,7 @@ extern long long int atoll(const char *); /* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, but does not have crtbegin/end. */ -#define TARGET_AIX_VERSION 72 +#define TARGET_AIX_VERSION 73 /* AIX 7.2 supports DWARF3+ debugging. */ #define DWARF2_DEBUGGING_INFO 1 -- cgit v1.1 From 05ace2946b4369b49026789d5a83635076b10422 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 25 Aug 2021 00:16:57 +0000 Subject: Daily bump. --- gcc/ChangeLog | 221 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/fortran/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 68 +++++++++++++++ 4 files changed, 297 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0183764..e4dd226 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,224 @@ +2021-08-24 David Edelsohn + + * config/rs6000/aix.h (SYSTEM_IMPLICIT_EXTERN_C): Delete. + * config/rs6000/aix71.h (SYSTEM_IMPLICIT_EXTERN_C): Define. + * config/rs6000/aix72.h (SYSTEM_IMPLICIT_EXTERN_C): Define. + * config/rs6000/aix73.h (TARGET_AIX_VERSION): Increase to 73. + +2021-08-24 Roger Sayle + + PR middle-end/102031 + * simplify-rtx.c (simplify_truncation): When comparing precisions + use "subreg_prec" variable, not "subreg_mode". + +2021-08-24 Bill Schmidt + + * config/rs6000/rs6000-builtin-new.def: Add power10 and power10-64 + stanzas. + +2021-08-24 Bill Schmidt + + * config/rs6000/rs6000-call.c (rs6000_init_builtins): Initialize + various pointer type nodes. + * config/rs6000/rs6000.h (rs6000_builtin_type_index): Add enum + values for various pointer types. + (ptr_V16QI_type_node): New macro. + (ptr_V1TI_type_node): New macro. + (ptr_V2DI_type_node): New macro. + (ptr_V2DF_type_node): New macro. + (ptr_V4SI_type_node): New macro. + (ptr_V4SF_type_node): New macro. + (ptr_V8HI_type_node): New macro. + (ptr_unsigned_V16QI_type_node): New macro. + (ptr_unsigned_V1TI_type_node): New macro. + (ptr_unsigned_V8HI_type_node): New macro. + (ptr_unsigned_V4SI_type_node): New macro. + (ptr_unsigned_V2DI_type_node): New macro. + (ptr_bool_V16QI_type_node): New macro. + (ptr_bool_V8HI_type_node): New macro. + (ptr_bool_V4SI_type_node): New macro. + (ptr_bool_V2DI_type_node): New macro. + (ptr_bool_V1TI_type_node): New macro. + (ptr_pixel_type_node): New macro. + (ptr_intQI_type_node): New macro. + (ptr_uintQI_type_node): New macro. + (ptr_intHI_type_node): New macro. + (ptr_uintHI_type_node): New macro. + (ptr_intSI_type_node): New macro. + (ptr_uintSI_type_node): New macro. + (ptr_intDI_type_node): New macro. + (ptr_uintDI_type_node): New macro. + (ptr_intTI_type_node): New macro. + (ptr_uintTI_type_node): New macro. + (ptr_long_integer_type_node): New macro. + (ptr_long_unsigned_type_node): New macro. + (ptr_float_type_node): New macro. + (ptr_double_type_node): New macro. + (ptr_long_double_type_node): New macro. + (ptr_dfloat64_type_node): New macro. + (ptr_dfloat128_type_node): New macro. + (ptr_ieee128_type_node): New macro. + (ptr_ibm128_type_node): New macro. + (ptr_vector_pair_type_node): New macro. + (ptr_vector_quad_type_node): New macro. + (ptr_long_long_integer_type_node): New macro. + (ptr_long_long_unsigned_type_node): New macro. + +2021-08-24 Bill Schmidt + + * config/rs6000/rs6000-builtin-new.def: Add power9-vector, power9, + and power9-64 stanzas. + +2021-08-24 Roger Sayle + Tom de Vries + + * config.gcc (nvptx-*-*): Define {c,c++}_target_objs. + * config/nvptx/nvptx-protos.h (nvptx_cpu_cpp_builtins): Prototype. + * config/nvptx/nvptx.h (TARGET_CPU_CPP_BUILTINS): Implement with + a call to the new nvptx_cpu_cpp_builtins function in nvptx-c.c. + * config/nvptx/t-nvptx (nvptx-c.o): New rule. + * config/nvptx/nvptx-c.c: New source file. + (nvptx_cpu_cpp_builtins): Move implementation here. + +2021-08-24 Martin Sebor + + PR middle-end/101600 + PR middle-end/101977 + * gimple-ssa-warn-access.cc (maybe_warn_for_bound): Tighten up + the phrasing of a warning. + (check_access): Use the remaining size after subtracting any offset + rather than the whole object size. + * pointer-query.cc (access_ref::get_ref): Clear BASE0 flag if it's + clear for any nonnull PHI argument. + (compute_objsize): Clear argument. + +2021-08-24 Bill Schmidt + + * config/rs6000/rs6000-builtin-new.def: Add power8-vector stanza. + +2021-08-24 Bill Schmidt + + * config/rs6000/rs6000-builtin-new.def: Add power7 and power7-64 + stanzas. + +2021-08-24 Andrew MacLeod + + * value-relation.cc (rr_transitive_table): New. + (relation_transitive): New. + (value_relation::swap): Remove. + (value_relation::apply_transitive): New. + (relation_oracle::relation_oracle): Allocate a new tmp bitmap. + (relation_oracle::register_relation): Call register_transitives. + (relation_oracle::register_transitives): New. + * value-relation.h (relation_oracle): Add new temporary bitmap and + methods. + +2021-08-24 H.J. Lu + + PR target/102021 + * config/i386/i386-expand.c (ix86_expand_vector_move): Broadcast + from integer to a pseudo vector register. + +2021-08-24 Richard Biener + + PR tree-optimization/100089 + * tree-vectorizer.h (vect_slp_bb): Rename to ... + (vect_slp_if_converted_bb): ... this and get the original + loop as new argument. + * tree-vectorizer.c (try_vectorize_loop_1): Revert previous fix, + pass original loop to vect_slp_if_converted_bb. + * tree-vect-slp.c (vect_bb_vectorization_profitable_p): + If orig_loop was passed scan the not vectorized stmts + for COND_EXPRs and force not profitable if found. + (vect_slp_region): Pass down all SLP instances to costing + if orig_loop was specified. + (vect_slp_bbs): Pass through orig_loop. + (vect_slp_bb): Rename to ... + (vect_slp_if_converted_bb): ... this and get the original + loop as new argument. + (vect_slp_function): Adjust. + +2021-08-24 Richard Earnshaw + + PR target/102035 + * config/arm/arm.md (attribute arch): Add fix_vlldm. + (arch_enabled): Use it. + * config/arm/vfp.md (lazy_store_multiple_insn): Add alternative to + use when erratum mitigation is needed. + +2021-08-24 Richard Earnshaw + + PR target/102035 + * config/arm/arm.opt (mfix-cmse-cve-2021-35465): New option. + * doc/invoke.texi (Arm Options): Document it. + * config/arm/arm-cpus.in (quirk_vlldm): New feature bit. + (ALL_QUIRKS): Add quirk_vlldm. + (cortex-m33): Add quirk_vlldm. + (cortex-m35p, cortex-m55): Likewise. + * config/arm/arm.c (arm_option_override): Enable fix_vlldm if + targetting an affected CPU and not explicitly controlled on + the command line. + +2021-08-24 Richard Earnshaw + + * config/arm/vfp.md (lazy_store_multiple_insn): Rewrite as valid RTL. + (lazy_load_multiple_insn): Likewise. + +2021-08-24 liuhongt + + PR target/101989 + * config/i386/sse.md (_vternlog): + Enable avx512 embedded broadcast. + (*_vternlog_all): Ditto. + (_vternlog_mask): Ditto. + +2021-08-24 liuhongt + + PR target/101989 + * config/i386/i386.c (ix86_rtx_costs): Define cost for + UNSPEC_VTERNLOG. + * config/i386/i386.h (STRIP_UNARY): New macro. + * config/i386/predicates.md (reg_or_notreg_operand): New + predicate. + * config/i386/sse.md (*_vternlog_all): New define_insn. + (*_vternlog_1): New pre_reload + define_insn_and_split. + (*_vternlog_2): Ditto. + (*_vternlog_3): Ditto. + (any_logic1,any_logic2): New code iterator. + (logic_op): New code attribute. + (ternlogsuffix): Extend to VNxDF and VNxSF. + +2021-08-24 Richard Biener + + * doc/invoke.texi (vect-inner-loop-cost-factor): Adjust. + * params.opt (--param vect-inner-loop-cost-factor): Adjust + maximum value. + * tree-vect-loop.c (vect_analyze_loop_form): Initialize + inner_loop_cost_factor to the minimum of the estimated number + of iterations of the inner loop and vect-inner-loop-cost-factor. + +2021-08-24 Roger Sayle + Richard Biener + + * config/i386/i386-features.c (compute_convert_gain): Provide + more accurate values for CONST_INT, when optimizing for size. + * config/i386/i386.c (COSTS_N_BYTES): Move definition from here... + * config/i386/i386.h (COSTS_N_BYTES): to here. + +2021-08-24 Roger Sayle + Jakub Jelinek + + PR middle-end/102029 + * match.pd (shift transformations): Add an additional check for + !POINTER_TYPE_P in the recently added left shift transformation. + +2021-08-24 liuhongt + + PR tree-optimization/100089 + * tree-vectorizer.c (try_vectorize_loop_1): Disable slp in + loop vectorizer when cost model is very-cheap. + 2021-08-23 Bill Schmidt * config/rs6000/rs6000-gen-builtins.c (parse_bif_entry): Don't call diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 83a5291..83bcbc1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210824 +20210825 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 307886d..2866f5d 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2021-08-24 Harald Anlauf + + PR fortran/98411 + * trans-decl.c (gfc_finish_var_decl): Adjust check to handle + implicit SAVE as well as variables in the main program. Improve + warning message text. + 2021-08-23 Tobias Burnus * openmp.c (gfc_match_dupl_check, gfc_match_dupl_memorder, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c49bd3..84e6afb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,71 @@ +2021-08-24 Harald Anlauf + + PR fortran/98411 + * gfortran.dg/pr98411.f90: Adjust testcase options to restrict to + F2008, and verify case of implicit SAVE. + +2021-08-24 Martin Sebor + + PR middle-end/101600 + PR middle-end/101977 + * g++.dg/pr100574.C: Prune out valid warning. + * gcc.dg/pr20126.c: Same. + * gcc.dg/Wstringop-overread.c: Adjust text of expected warnings. + Add new instances. + * gcc.dg/warn-strnlen-no-nul.c: Same. + * g++.dg/warn/Warray-bounds-26.C: New test. + * gcc.dg/Warray-bounds-88.c: New test. + +2021-08-24 Andrew MacLeod + + * gcc.dg/predict-1.c: Disable evrp. + * gcc.dg/tree-ssa/evrp-trans.c: New. + +2021-08-24 H.J. Lu + + PR target/102021 + * gcc.target/i386/pr100865-10b.c: Expect vzeroupper. + * gcc.target/i386/pr100865-4b.c: Likewise. + * gcc.target/i386/pr100865-6b.c: Expect vmovdqu and vzeroupper. + * gcc.target/i386/pr100865-7b.c: Likewise. + * gcc.target/i386/pr102021.c: New test. + +2021-08-24 Richard Earnshaw + + PR target/102035 + * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13a.c: New test. + * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7a.c: Likewise. + * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8a.c: Likewise. + * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7a.c: Likewise. + * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8a.c: Likewise. + * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13a.c: Likewise. + * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7a.c: Likewise. + * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8a.c: Likewise. + +2021-08-24 Richard Earnshaw + + * lib/target-supports.exp (check_effective_target_arm_cmse_hw): + Check the CMSE feature register, rather than relying on the + SG operation causing an execution fault. + +2021-08-24 liuhongt + + PR target/101989 + * gcc.target/i386/pr101989-broadcast-1.c: New test. + +2021-08-24 liuhongt + + PR target/101989 + * gcc.target/i386/pr101989-1.c: New test. + * gcc.target/i386/pr101989-2.c: New test. + * gcc.target/i386/avx512bw-shiftqihi-constant-1.c: Adjust testcase. + +2021-08-24 Roger Sayle + Jakub Jelinek + + PR middle-end/102029 + * gcc.dg/fold-convlshift-3.c: New test case. + 2021-08-23 David Malcolm * gcc.dg/analyzer/switch.c: Remove xfail. Add various tests. -- cgit v1.1 From 4f5391dde1a83086b451f7534c815ab1267bb6bc Mon Sep 17 00:00:00 2001 From: liuhongt Date: Wed, 25 Aug 2021 09:45:25 +0800 Subject: Adjust testcases to avoid new failures brought by r12-3108 when compiled w -march=cascadelake. gcc/testsuite/ChangeLog: PR target/101989 * gcc.target/i386/avx2-shiftqihi-constant-1.c: Add -mno-avx512f. * gcc.target/i386/sse2-shiftqihi-constant-1.c: Add -mno-avx --- gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c | 2 +- gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c b/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c index 7206503..801f570 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c +++ b/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c @@ -1,6 +1,6 @@ /* PR target/95524 */ /* { dg-do compile } */ -/* { dg-options "-O2 -mavx2" } */ +/* { dg-options "-O2 -mavx2 -mno-avx512f" } */ /* { dg-final { scan-assembler-times "vpand\[^\n\]*%ymm" 3 } } */ typedef char v32qi __attribute__ ((vector_size (32))); typedef unsigned char v32uqi __attribute__ ((vector_size (32))); diff --git a/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c b/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c index f1c68cb..015450f 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c +++ b/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c @@ -1,6 +1,6 @@ /* PR target/95524 */ /* { dg-do compile } */ -/* { dg-options "-O2 -msse2" } */ +/* { dg-options "-O2 -msse2 -mno-avx" } */ /* { dg-final { scan-assembler-times "pand\[^\n\]*%xmm" 3 { xfail *-*-* } } } */ typedef char v16qi __attribute__ ((vector_size (16))); typedef unsigned char v16uqi __attribute__ ((vector_size (16))); -- cgit v1.1 From a20be0cdc068d9ffab7bf0c9d2a8702162746bd8 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Tue, 24 Aug 2021 21:58:14 -0500 Subject: rs6000: Add vec_unpacku_{hi,lo}_v4si The existing vec_unpacku_{hi,lo} supports emulated unsigned unpacking for short and char but misses the support for int. This patch adds the support of vec_unpacku_{hi,lo}_v4si. Meanwhile, the current implementation uses vector permutation way, which requires one extra customized constant vector as the permutation control vector. It's better to use vector merge high/low with zero constant vector, to save the space in constant area as well as the cost to initialize pcv in prologue. This patch updates it with vector merging and simplify it with iterators. gcc/ChangeLog: * config/rs6000/altivec.md (vec_unpacku_hi_v16qi): Remove. (vec_unpacku_hi_v8hi): Likewise. (vec_unpacku_lo_v16qi): Likewise. (vec_unpacku_lo_v8hi): Likewise. (vec_unpacku_hi_): New define_expand. (vec_unpacku_lo_): Likewise. gcc/testsuite/ChangeLog: * gcc.target/powerpc/unpack-vectorize-1.c: New test. * gcc.target/powerpc/unpack-vectorize-1.h: New test. * gcc.target/powerpc/unpack-vectorize-2.c: New test. * gcc.target/powerpc/unpack-vectorize-2.h: New test. * gcc.target/powerpc/unpack-vectorize-3.c: New test. * gcc.target/powerpc/unpack-vectorize-3.h: New test. * gcc.target/powerpc/unpack-vectorize-run-1.c: New test. * gcc.target/powerpc/unpack-vectorize-run-2.c: New test. * gcc.target/powerpc/unpack-vectorize-run-3.c: New test. * gcc.target/powerpc/unpack-vectorize.h: New test. --- gcc/config/rs6000/altivec.md | 158 ++++----------------- .../gcc.target/powerpc/unpack-vectorize-1.c | 18 +++ .../gcc.target/powerpc/unpack-vectorize-1.h | 14 ++ .../gcc.target/powerpc/unpack-vectorize-2.c | 12 ++ .../gcc.target/powerpc/unpack-vectorize-2.h | 7 + .../gcc.target/powerpc/unpack-vectorize-3.c | 11 ++ .../gcc.target/powerpc/unpack-vectorize-3.h | 7 + .../gcc.target/powerpc/unpack-vectorize-run-1.c | 24 ++++ .../gcc.target/powerpc/unpack-vectorize-run-2.c | 16 +++ .../gcc.target/powerpc/unpack-vectorize-run-3.c | 16 +++ .../gcc.target/powerpc/unpack-vectorize.h | 42 ++++++ 11 files changed, 196 insertions(+), 129 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c create mode 100644 gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h (limited to 'gcc') diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 2c73dde..93d23715 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -134,10 +134,8 @@ UNSPEC_VMULWLUH UNSPEC_VMULWHSH UNSPEC_VMULWLSH - UNSPEC_VUPKHUB - UNSPEC_VUPKHUH - UNSPEC_VUPKLUB - UNSPEC_VUPKLUH + UNSPEC_VUPKHU + UNSPEC_VUPKLU UNSPEC_VPERMSI UNSPEC_VPERMHI UNSPEC_INTERHI @@ -3688,143 +3686,45 @@ [(set_attr "type" "vecperm") (set_attr "isa" "p9v,*")]) -(define_expand "vec_unpacku_hi_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VUPKHUB))] - "TARGET_ALTIVEC" -{ - rtx vzero = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - bool be = BYTES_BIG_ENDIAN; - - emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); - - emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); - DONE; -}) - -(define_expand "vec_unpacku_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VUPKHUH))] +(define_expand "vec_unpacku_hi_" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUPKHU))] "TARGET_ALTIVEC" { - rtx vzero = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - bool be = BYTES_BIG_ENDIAN; + rtx vzero = gen_reg_rtx (mode); + emit_insn (gen_altivec_vspltis (vzero, const0_rtx)); - emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); - - emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); - DONE; -}) + rtx res = gen_reg_rtx (mode); + rtx op1 = operands[1]; -(define_expand "vec_unpacku_lo_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VUPKLUB))] - "TARGET_ALTIVEC" -{ - rtx vzero = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - bool be = BYTES_BIG_ENDIAN; - - emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrgh (res, vzero, op1)); + else + emit_insn (gen_altivec_vmrgl (res, op1, vzero)); - emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); + emit_insn (gen_move_insn (operands[0], gen_lowpart (mode, res))); DONE; }) -(define_expand "vec_unpacku_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VUPKLUH))] +(define_expand "vec_unpacku_lo_" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUPKLU))] "TARGET_ALTIVEC" { - rtx vzero = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - bool be = BYTES_BIG_ENDIAN; + rtx vzero = gen_reg_rtx (mode); + emit_insn (gen_altivec_vspltis (vzero, const0_rtx)); - emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); + rtx res = gen_reg_rtx (mode); + rtx op1 = operands[1]; - emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrgl (res, vzero, op1)); + else + emit_insn (gen_altivec_vmrgh (res, op1, vzero)); + + emit_insn (gen_move_insn (operands[0], gen_lowpart (mode, res))); DONE; }) diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c new file mode 100644 index 0000000..dceb5b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */ + +/* Test if unpack vectorization succeeds for type signed/unsigned + short and char. */ + +#include "unpack-vectorize-1.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */ +/* { dg-final { scan-assembler-times {\mvupkhsb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvupklsb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvupkhsh\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvupklsh\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvmrghb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvmrglb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvmrghh\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvmrglh\M} 2 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h new file mode 100644 index 0000000..1cb89ab --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h @@ -0,0 +1,14 @@ +#include "unpack-vectorize.h" + +DEF_ARR (si) +DEF_ARR (ui) +DEF_ARR (sh) +DEF_ARR (uh) +DEF_ARR (sc) +DEF_ARR (uc) + +TEST1 (sh, si) +TEST1 (uh, ui) +TEST1 (sc, sh) +TEST1 (uc, uh) + diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c new file mode 100644 index 0000000..4f2e6eb --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-mdejagnu-cpu=power7 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */ + +/* Test if unsigned int unpack vectorization succeeds. V2DImode is + supported since Power7 so guard it under Power7 and up. */ + +#include "unpack-vectorize-2.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-assembler-times {\mxxmrghw\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxxmrglw\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h new file mode 100644 index 0000000..e199229 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h @@ -0,0 +1,7 @@ +#include "unpack-vectorize.h" + +DEF_ARR (ui) +DEF_ARR (ull) + +TEST1 (ui, ull) + diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c new file mode 100644 index 0000000..520a279 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-options "-mdejagnu-cpu=power8 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */ + +/* Test if signed int unpack vectorization succeeds. */ + +#include "unpack-vectorize-3.h" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-assembler-times {\mvupkhsw\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvupklsw\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h new file mode 100644 index 0000000..6a5191d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h @@ -0,0 +1,7 @@ +#include "unpack-vectorize.h" + +DEF_ARR (si) +DEF_ARR (sll) + +TEST1 (si, sll) + diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c new file mode 100644 index 0000000..51f0e67 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vmx_hw } */ +/* { dg-options "-maltivec -O2 -ftree-vectorize -fno-vect-cost-model" } */ + +#include "unpack-vectorize-1.h" + +/* Test if unpack vectorization cases on signed/unsigned short and char + run successfully. */ + +CHECK1 (sh, si) +CHECK1 (uh, ui) +CHECK1 (sc, sh) +CHECK1 (uc, uh) + +int +main () +{ + check1_sh_si (); + check1_uh_ui (); + check1_sc_sh (); + check1_uc_uh (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c new file mode 100644 index 0000000..6d24360 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-mdejagnu-cpu=power7 -O2 -ftree-vectorize -fno-vect-cost-model" } */ + +#include "unpack-vectorize-2.h" + +/* Test if unpack vectorization cases on unsigned int run successfully. */ + +CHECK1 (ui, ull) + +int +main () +{ + check1_ui_ull (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c new file mode 100644 index 0000000..fec33c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-require-effective-target p8vector_hw } */ +/* { dg-options "-mdejagnu-cpu=power8 -O2 -ftree-vectorize -fno-vect-cost-model" } */ + +#include "unpack-vectorize-3.h" + +/* Test if unpack vectorization cases on signed int run successfully. */ + +CHECK1 (si, sll) + +int +main () +{ + check1_si_sll (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h new file mode 100644 index 0000000..11fa7d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h @@ -0,0 +1,42 @@ +typedef signed long long sll; +typedef unsigned long long ull; +typedef signed int si; +typedef unsigned int ui; +typedef signed short sh; +typedef unsigned short uh; +typedef signed char sc; +typedef unsigned char uc; + +#ifndef ALIGN +#define ALIGN 32 +#endif + +#define ALIGN_ATTR __attribute__((__aligned__(ALIGN))) + +#define N 128 + +#define DEF_ARR(TYPE) \ + TYPE TYPE##_a[N] ALIGN_ATTR; \ + TYPE TYPE##_b[N] ALIGN_ATTR; \ + TYPE TYPE##_c[N] ALIGN_ATTR; + +#define TEST1(NTYPE, WTYPE) \ + __attribute__((noipa)) void test1_##NTYPE##_##WTYPE() { \ + for (int i = 0; i < N; i++) \ + WTYPE##_c[i] = NTYPE##_a[i] + NTYPE##_b[i]; \ + } + +#define CHECK1(NTYPE, WTYPE) \ + __attribute__((noipa, optimize(0))) void check1_##NTYPE##_##WTYPE() { \ + for (int i = 0; i < N; i++) { \ + NTYPE##_a[i] = 2 * i * sizeof(NTYPE) + 10; \ + NTYPE##_b[i] = 7 * i * sizeof(NTYPE) / 5 - 10; \ + } \ + test1_##NTYPE##_##WTYPE(); \ + for (int i = 0; i < N; i++) { \ + WTYPE exp = NTYPE##_a[i] + NTYPE##_b[i]; \ + if (WTYPE##_c[i] != exp) \ + __builtin_abort(); \ + } \ + } + -- cgit v1.1 From db3d4129b6f4cff685713da514b64ff7bbc401fc Mon Sep 17 00:00:00 2001 From: konglin1 Date: Mon, 9 Aug 2021 10:58:24 +0800 Subject: i386: Fix _mm512_fpclass_ps_mask in O0 [PR 101471] gcc/ChangeLog: PR target/101471 * config/i386/avx512dqintrin.h (_mm512_fpclass_ps_mask): Fix macro define in O0. (_mm512_mask_fpclass_ps_mask): Ditto. gcc/testsuite/ChangeLog: PR target/101471 * gcc.target/i386/avx512f-pr101471.c: New test. --- gcc/config/i386/avx512dqintrin.h | 4 ++-- gcc/testsuite/gcc.target/i386/avx512f-pr101471.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-pr101471.c (limited to 'gcc') diff --git a/gcc/config/i386/avx512dqintrin.h b/gcc/config/i386/avx512dqintrin.h index 51c0b12..9794f5d 100644 --- a/gcc/config/i386/avx512dqintrin.h +++ b/gcc/config/i386/avx512dqintrin.h @@ -2814,7 +2814,7 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm) #define _mm512_mask_fpclass_ps_mask(u, x, c) \ ((__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) (__m512) (x),\ - (int) (c),(__mmask8)(u))) + (int) (c),(__mmask16)(u))) #define _mm512_fpclass_pd_mask(X, C) \ ((__mmask8) __builtin_ia32_fpclasspd512_mask ((__v8df) (__m512d) (X), \ @@ -2822,7 +2822,7 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm) #define _mm512_fpclass_ps_mask(x, c) \ ((__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) (__m512) (x),\ - (int) (c),(__mmask8)-1)) + (int) (c),(__mmask16)-1)) #define _mm_reduce_sd(A, B, C) \ ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), \ diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr101471.c b/gcc/testsuite/gcc.target/i386/avx512f-pr101471.c new file mode 100644 index 0000000..4a0057b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-pr101471.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-mavx512dq -O0" } */ +/* { dg-require-effective-target avx512dq } */ + +#include "avx512f-check.h" + +static void +avx512f_test (void) +{ + __m512 x = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 0, 0, 0, + 0, 0, 0, 0, }; + int ret = _mm512_fpclass_ps_mask(x, 0x26); + if (ret != 65280) + __builtin_abort(); +} -- cgit v1.1 From 3673dcf6d6baeb67bb70ff03d4cb3f92beed0075 Mon Sep 17 00:00:00 2001 From: Jiufu Guo Date: Wed, 7 Jul 2021 13:41:01 +0800 Subject: Analyze niter for until-wrap condition [PR101145] For code like: unsigned foo(unsigned val, unsigned start) { unsigned cnt = 0; for (unsigned i = start; i > val; ++i) cnt++; return cnt; } The number of iterations should be about UINT_MAX - start. There is function adjust_cond_for_loop_until_wrap which handles similar work for const bases. Like adjust_cond_for_loop_until_wrap, this patch enhance function number_of_iterations_cond/number_of_iterations_lt to analyze number of iterations for this kind of loop. gcc/ChangeLog: 2021-08-25 Jiufu Guo PR tree-optimization/101145 * tree-ssa-loop-niter.c (number_of_iterations_until_wrap): New function. (number_of_iterations_lt): Invoke above function. (adjust_cond_for_loop_until_wrap): Merge to number_of_iterations_until_wrap. (number_of_iterations_cond): Update invokes for adjust_cond_for_loop_until_wrap and number_of_iterations_lt. gcc/testsuite/ChangeLog: 2021-08-25 Jiufu Guo PR tree-optimization/101145 * gcc.dg/vect/pr101145.c: New test. * gcc.dg/vect/pr101145.inc: New test. * gcc.dg/vect/pr101145_1.c: New test. * gcc.dg/vect/pr101145_2.c: New test. * gcc.dg/vect/pr101145_3.c: New test. * gcc.dg/vect/pr101145inf.c: New test. * gcc.dg/vect/pr101145inf.inc: New test. * gcc.dg/vect/pr101145inf_1.c: New test. --- gcc/testsuite/gcc.dg/vect/pr101145.c | 187 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/pr101145.inc | 65 +++++++++++ gcc/testsuite/gcc.dg/vect/pr101145_1.c | 13 +++ gcc/testsuite/gcc.dg/vect/pr101145_2.c | 13 +++ gcc/testsuite/gcc.dg/vect/pr101145_3.c | 13 +++ gcc/testsuite/gcc.dg/vect/pr101145inf.c | 25 ++++ gcc/testsuite/gcc.dg/vect/pr101145inf.inc | 28 +++++ gcc/testsuite/gcc.dg/vect/pr101145inf_1.c | 23 ++++ gcc/tree-ssa-loop-niter.c | 157 ++++++++++++++----------- 9 files changed, 459 insertions(+), 65 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145.inc create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145_1.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145_2.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145_3.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145inf.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145inf.inc create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145inf_1.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.c b/gcc/testsuite/gcc.dg/vect/pr101145.c new file mode 100644 index 0000000..74031b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145.c @@ -0,0 +1,187 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-options "-O3 -fdump-tree-vect-details" } */ +#include + +unsigned __attribute__ ((noinline)) +foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ + while (n < ++l) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) +{ + while (UINT_MAX - 64 < ++l) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ + l = UINT_MAX - 32; + while (n < ++l) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ + while (n <= ++l) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ // infininate + while (0 <= ++l) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +foo_5 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ + //no loop + l = UINT_MAX; + while (n < ++l) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +bar (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ + while (--l < n) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +bar_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) +{ + while (--l < 64) + *a++ = *b++ + 1; + return l; +} + +unsigned __attribute__ ((noinline)) +bar_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) +{ + l = 32; + while (--l < n) + *a++ = *b++ + 1; + return l; +} + + +int a[3200], b[3200]; +int fail; + +int +main () +{ + unsigned l, n; + unsigned res; + /* l > n*/ + n = UINT_MAX - 64; + l = n + 32; + res = foo (a, b, l, n); + if (res != 0) + fail++; + + l = n; + res = foo (a, b, l, n); + if (res != 0) + fail++; + + l = n - 1; + res = foo (a, b, l, n); + if (res != l + 1) + fail++; + + l = n - 32; + res = foo (a, b, l, n); + if (res != l + 1) + fail++; + + l = UINT_MAX; + res = foo (a, b, l, n); + if (res != 0) + fail++; + + l = n + 32; + res = foo_1 (a, b, l, n); + if (res != 0) + fail++; + + l = n + 32; + res = foo_2 (a, b, l, n); + if (res != 0) + fail++; + + l = n; + res = foo_3 (a, b, l, n); + if (res != 0) + fail++; + + l = n - 1; + res = foo_3 (a, b, l, n); + if (res != 0) + fail++; + + l = n - 2; + res = foo_3 (a, b, l, n); + if (res != l + 1) + fail++; + + res = foo_5 (a, b, l, n); + if (res != 0) + fail++; + + n = 64; + l = n - 32; + res = bar (a, b, l, n); + res++; + if (res != 0) + fail++; + + l = n; + res = bar (a, b, l, n); + res++; + if (res != 0) + fail++; + + l = n + 1; + res = bar (a, b, l, n); + res++; + if (res != l) + fail++; + + l = 0; + res = bar (a, b, l, n); + res++; + if (res != l) + fail++; + + l = 32; + res = bar_1 (a, b, l, n); + res++; + if (res != 0) + fail++; + + res = bar_1 (a, b, l, n); + res++; + if (res != 0) + fail++; + + if (fail) + __builtin_abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 7 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.inc b/gcc/testsuite/gcc.dg/vect/pr101145.inc new file mode 100644 index 0000000..615d2e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145.inc @@ -0,0 +1,65 @@ +TYPE __attribute__ ((noinline)) +foo_sign (int *__restrict__ a, int *__restrict__ b, TYPE l, TYPE n) +{ + TYPE i; + for (i = l; n < i; i += C) + *a++ = *b++ + 1; + return i; +} + +TYPE __attribute__ ((noinline)) +bar_sign (int *__restrict__ a, int *__restrict__ b, TYPE l, TYPE n) +{ + TYPE i; + for (i = l; i < n; i -= C) + *a++ = *b++ + 1; + return i; +} + +int __attribute__ ((noinline)) neq (int a, int b) { return a != b; } + +int a[1000], b[1000]; +int fail; + +int +main () +{ + TYPE res; + TYPE l; + TYPE n; + n = N_BASE; + l = n - C; + res = foo_sign (a, b, l, n); + if (res != l) + fail++; + + l = n; + res = foo_sign (a, b, l, n); + if (res != l) + fail++; + + l = n + C; + res = foo_sign (a, b, l, n); + if (neq ((res - MIN) / C, 0)) + fail++; + + n = N_BASE_DOWN; + l = n - C; + res = bar_sign (a, b, l, n); + if (neq ((MAX - res) / C, 0)) + fail++; + + l = n; + res = bar_sign (a, b, l, n); + if (res != l) + fail++; + + l = n + C; + res = bar_sign (a, b, l, n); + if (res != l) + fail++; + + if (fail) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_1.c b/gcc/testsuite/gcc.dg/vect/pr101145_1.c new file mode 100644 index 0000000..8bc26e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145_1.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-options "-O3 -fdump-tree-vect-details" } */ +#define TYPE signed char +#define MIN -128 +#define MAX 127 +#define N_BASE (MAX - 32) +#define N_BASE_DOWN (MIN + 32) + +#define C 3 + +#include "pr101145.inc" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_2.c b/gcc/testsuite/gcc.dg/vect/pr101145_2.c new file mode 100644 index 0000000..b14c4b4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145_2.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-options "-O3 -fdump-tree-vect-details" } */ +#define TYPE unsigned char +#define MIN 0 +#define MAX 255 +#define N_BASE (MAX - 32 + 1) +#define N_BASE_DOWN (MIN + 32) + +#define C 2 + +#include "pr101145.inc" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_3.c b/gcc/testsuite/gcc.dg/vect/pr101145_3.c new file mode 100644 index 0000000..99289af --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145_3.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-options "-O3 -fdump-tree-vect-details" } */ +#define TYPE int * +#define MIN ((TYPE)0) +#define MAX ((TYPE)((long long)-1)) +#define N_BASE (MIN - 32) +#define N_BASE_DOWN (MIN + 32) + +#define C 1 + +#include "pr101145.inc" + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr101145inf.c b/gcc/testsuite/gcc.dg/vect/pr101145inf.c new file mode 100644 index 0000000..ed49f56 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145inf.c @@ -0,0 +1,25 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ +/* { dg-options "-O3" } */ +#include +#include "pr101145inf.inc" + +__attribute__ ((noinline)) +unsigned foo(unsigned val, unsigned start) +{ + unsigned cnt = 0; + for (unsigned i = start; val <= i; i+=16) + cnt++; + return cnt; +} + +void test_finite () +{ + unsigned n = foo (16, UINT_MAX - 32); + if (n != 3) + __builtin_abort (); +} + +void test_infinite () +{ + foo (15, UINT_MAX - 32); +} diff --git a/gcc/testsuite/gcc.dg/vect/pr101145inf.inc b/gcc/testsuite/gcc.dg/vect/pr101145inf.inc new file mode 100644 index 0000000..4aa3d04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145inf.inc @@ -0,0 +1,28 @@ +#include +#include +#include + +void test_finite (); +void test_infinite (); + +void do_exit (int i) +{ + exit (0); +} + +int main(void) +{ + test_finite (); + struct sigaction s; + sigemptyset (&s.sa_mask); + s.sa_handler = do_exit; + s.sa_flags = 0; + sigaction (SIGALRM, &s, NULL); + alarm (1); + + test_infinite (); + + __builtin_abort (); + return 1; +} + diff --git a/gcc/testsuite/gcc.dg/vect/pr101145inf_1.c b/gcc/testsuite/gcc.dg/vect/pr101145inf_1.c new file mode 100644 index 0000000..4ee3e31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101145inf_1.c @@ -0,0 +1,23 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ +/* { dg-options "-O3" } */ +#include +#include "pr101145inf.inc" + +__attribute__ ((noinline)) +unsigned foo(unsigned val, unsigned start) +{ + unsigned cnt = 0; + for (unsigned i = start; i < val; i-=16) + cnt++; + return cnt; +} + +void test_finite () +{ + foo (UINT_MAX - 15, 32); +} + +void test_infinite () +{ + foo (UINT_MAX - 14, 32); +} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 466158a..7af92d1 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -1474,6 +1474,93 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1, } /* Determines number of iterations of loop whose ending condition + is IV0 < IV1 which likes: {base, -C} < n, or n < {base, C}. + The number of iterations is stored to NITER. */ + +static bool +number_of_iterations_until_wrap (class loop *, tree type, affine_iv *iv0, + affine_iv *iv1, class tree_niter_desc *niter) +{ + tree niter_type = unsigned_type_for (type); + tree step, num, assumptions, may_be_zero; + wide_int high, low, max, min; + + may_be_zero = fold_build2 (LE_EXPR, boolean_type_node, iv1->base, iv0->base); + if (integer_onep (may_be_zero)) + return false; + + int prec = TYPE_PRECISION (type); + signop sgn = TYPE_SIGN (type); + min = wi::min_value (prec, sgn); + max = wi::max_value (prec, sgn); + + /* n < {base, C}. */ + if (integer_zerop (iv0->step) && !tree_int_cst_sign_bit (iv1->step)) + { + step = iv1->step; + /* MIN + C - 1 <= n. */ + tree last = wide_int_to_tree (type, min + wi::to_wide (step) - 1); + assumptions = fold_build2 (LE_EXPR, boolean_type_node, last, iv0->base); + if (integer_zerop (assumptions)) + return false; + + num = fold_build2 (MINUS_EXPR, niter_type, wide_int_to_tree (type, max), + iv1->base); + high = max; + if (TREE_CODE (iv1->base) == INTEGER_CST) + low = wi::to_wide (iv1->base) - 1; + else if (TREE_CODE (iv0->base) == INTEGER_CST) + low = wi::to_wide (iv0->base); + else + low = min; + } + /* {base, -C} < n. */ + else if (tree_int_cst_sign_bit (iv0->step) && integer_zerop (iv1->step)) + { + step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv0->step), iv0->step); + /* MAX - C + 1 >= n. */ + tree last = wide_int_to_tree (type, max - wi::to_wide (step) + 1); + assumptions = fold_build2 (GE_EXPR, boolean_type_node, last, iv1->base); + if (integer_zerop (assumptions)) + return false; + + num = fold_build2 (MINUS_EXPR, niter_type, iv0->base, + wide_int_to_tree (type, min)); + low = min; + if (TREE_CODE (iv0->base) == INTEGER_CST) + high = wi::to_wide (iv0->base) + 1; + else if (TREE_CODE (iv1->base) == INTEGER_CST) + high = wi::to_wide (iv1->base); + else + high = max; + } + else + return false; + + /* (delta + step - 1) / step */ + step = fold_convert (niter_type, step); + num = fold_convert (niter_type, num); + num = fold_build2 (PLUS_EXPR, niter_type, num, step); + niter->niter = fold_build2 (FLOOR_DIV_EXPR, niter_type, num, step); + + widest_int delta, s; + delta = widest_int::from (high, sgn) - widest_int::from (low, sgn); + s = wi::to_widest (step); + delta = delta + s - 1; + niter->max = wi::udiv_floor (delta, s); + + niter->may_be_zero = may_be_zero; + + if (!integer_nonzerop (assumptions)) + niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, + niter->assumptions, assumptions); + + niter->control.no_overflow = false; + + return true; +} + +/* Determines number of iterations of loop whose ending condition is IV0 < IV1. TYPE is the type of the iv. The number of iterations is stored to NITER. BNDS bounds the difference IV1->base - IV0->base. EXIT_MUST_BE_TAKEN is true if we know @@ -1501,6 +1588,11 @@ number_of_iterations_lt (class loop *loop, tree type, affine_iv *iv0, niter->bound = iv0->base; } + /* {base, -C} < n, or n < {base, C} */ + if (tree_int_cst_sign_bit (iv0->step) + || (!integer_zerop (iv1->step) && !tree_int_cst_sign_bit (iv1->step))) + return number_of_iterations_until_wrap (loop, type, iv0, iv1, niter); + delta = fold_build2 (MINUS_EXPR, niter_type, fold_convert (niter_type, iv1->base), fold_convert (niter_type, iv0->base)); @@ -1665,62 +1757,6 @@ dump_affine_iv (FILE *file, affine_iv *iv) } } -/* Given exit condition IV0 CODE IV1 in TYPE, this function adjusts - the condition for loop-until-wrap cases. For example: - (unsigned){8, -1}_loop < 10 => {0, 1} != 9 - 10 < (unsigned){0, max - 7}_loop => {0, 1} != 8 - Return true if condition is successfully adjusted. */ - -static bool -adjust_cond_for_loop_until_wrap (tree type, affine_iv *iv0, tree_code *code, - affine_iv *iv1) -{ - /* Only support simple cases for the moment. */ - if (TREE_CODE (iv0->base) != INTEGER_CST - || TREE_CODE (iv1->base) != INTEGER_CST) - return false; - - tree niter_type = unsigned_type_for (type), high, low; - /* Case: i-- < 10. */ - if (integer_zerop (iv1->step)) - { - /* TODO: Should handle case in which abs(step) != 1. */ - if (!integer_minus_onep (iv0->step)) - return false; - /* Give up on infinite loop. */ - if (*code == LE_EXPR - && tree_int_cst_equal (iv1->base, TYPE_MAX_VALUE (type))) - return false; - high = fold_build2 (PLUS_EXPR, niter_type, - fold_convert (niter_type, iv0->base), - build_int_cst (niter_type, 1)); - low = fold_convert (niter_type, TYPE_MIN_VALUE (type)); - } - else if (integer_zerop (iv0->step)) - { - /* TODO: Should handle case in which abs(step) != 1. */ - if (!integer_onep (iv1->step)) - return false; - /* Give up on infinite loop. */ - if (*code == LE_EXPR - && tree_int_cst_equal (iv0->base, TYPE_MIN_VALUE (type))) - return false; - high = fold_convert (niter_type, TYPE_MAX_VALUE (type)); - low = fold_build2 (MINUS_EXPR, niter_type, - fold_convert (niter_type, iv1->base), - build_int_cst (niter_type, 1)); - } - else - gcc_unreachable (); - - iv0->base = low; - iv0->step = fold_convert (niter_type, integer_one_node); - iv1->base = high; - iv1->step = build_int_cst (niter_type, 0); - *code = NE_EXPR; - return true; -} - /* Determine the number of iterations according to condition (for staying inside loop) which compares two induction variables using comparison operator CODE. The induction variable on left side of the comparison @@ -1855,15 +1891,6 @@ number_of_iterations_cond (class loop *loop, return true; } - /* Handle special case loops: while (i-- < 10) and while (10 < i++) by - adjusting iv0, iv1 and code. */ - if (code != NE_EXPR - && (tree_int_cst_sign_bit (iv0->step) - || (!integer_zerop (iv1->step) - && !tree_int_cst_sign_bit (iv1->step))) - && !adjust_cond_for_loop_until_wrap (type, iv0, &code, iv1)) - return false; - /* OK, now we know we have a senseful loop. Handle several cases, depending on what comparison operator is used. */ bound_difference (loop, iv1->base, iv0->base, &bnds); -- cgit v1.1 From 87afc7b81cd44d04997add383856b2504af3afe6 Mon Sep 17 00:00:00 2001 From: Hongyu Wang Date: Tue, 17 Aug 2021 16:53:46 +0800 Subject: i386: Optimize lea with zero-extend. [PR 101716] For ASHIFT + ZERO_EXTEND pattern, combine pass failed to match it to lea since it will generate non-canonical zero-extend. Adjust predicate and cost_model to allow combine for lea. gcc/ChangeLog: PR target/101716 * config/i386/i386.c (ix86_live_on_entry): Adjust comment. (ix86_decompose_address): Remove retval check for ASHIFT, allow non-canonical zero extend if AND mask covers ASHIFT count. (ix86_legitimate_address_p): Adjust condition for decompose. (ix86_rtx_costs): Adjust cost for lea with non-canonical zero-extend. Co-Authored by: Uros Bizjak gcc/testsuite/ChangeLog: PR target/101716 * gcc.target/i386/pr101716.c: New test. --- gcc/config/i386/i386.c | 36 ++++++++++++++++++++++++++------ gcc/testsuite/gcc.target/i386/pr101716.c | 11 ++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr101716.c (limited to 'gcc') diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ebec866..ddbbbce 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10018,8 +10018,7 @@ ix86_live_on_entry (bitmap regs) /* Extract the parts of an RTL expression that is a valid memory address for an instruction. Return 0 if the structure of the address is - grossly off. Return -1 if the address contains ASHIFT, so it is not - strictly valid, but still used for computing length of lea instruction. */ + grossly off. */ int ix86_decompose_address (rtx addr, struct ix86_address *out) @@ -10029,7 +10028,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) HOST_WIDE_INT scale = 1; rtx scale_rtx = NULL_RTX; rtx tmp; - int retval = 1; addr_space_t seg = ADDR_SPACE_GENERIC; /* Allow zero-extended SImode addresses, @@ -10053,6 +10051,27 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) if (CONST_INT_P (addr)) return 0; } + else if (GET_CODE (addr) == AND) + { + /* For ASHIFT inside AND, combine will not generate + canonical zero-extend. Merge mask for AND and shift_count + to check if it is canonical zero-extend. */ + tmp = XEXP (addr, 0); + rtx mask = XEXP (addr, 1); + if (tmp && GET_CODE(tmp) == ASHIFT) + { + rtx shift_val = XEXP (tmp, 1); + if (CONST_INT_P (mask) && CONST_INT_P (shift_val) + && (((unsigned HOST_WIDE_INT) INTVAL(mask) + | ((HOST_WIDE_INT_1U << INTVAL(shift_val)) - 1)) + == 0xffffffff)) + { + addr = lowpart_subreg (SImode, XEXP (addr, 0), + DImode); + } + } + + } } /* Allow SImode subregs of DImode addresses, @@ -10179,7 +10198,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) if ((unsigned HOST_WIDE_INT) scale > 3) return 0; scale = 1 << scale; - retval = -1; } else disp = addr; /* displacement */ @@ -10252,7 +10270,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) out->scale = scale; out->seg = seg; - return retval; + return 1; } /* Return cost of the memory address x. @@ -10765,7 +10783,7 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict) HOST_WIDE_INT scale; addr_space_t seg; - if (ix86_decompose_address (addr, &parts) <= 0) + if (ix86_decompose_address (addr, &parts) == 0) /* Decomposition failed. */ return false; @@ -20419,6 +20437,12 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, << (GET_MODE (XEXP (x, 1)) != DImode))); return true; } + else if (code == AND + && address_no_seg_operand (x, mode)) + { + *total = cost->lea; + return true; + } /* FALLTHRU */ case NEG: diff --git a/gcc/testsuite/gcc.target/i386/pr101716.c b/gcc/testsuite/gcc.target/i386/pr101716.c new file mode 100644 index 0000000..5e3ea64 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101716.c @@ -0,0 +1,11 @@ +/* PR target/101716 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler "leal\[\\t \]\[^\\n\]*eax" } } */ +/* { dg-final { scan-assembler-not "movl\[\\t \]\[^\\n\]*eax" } } */ + +unsigned long long sample1(unsigned long long m) { + unsigned int t = -1; + return (m << 1) & t; +} -- cgit v1.1 From 29c77454e5ab33ce06a741eacdfbd5348fbccc95 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 25 Aug 2021 10:06:01 +0200 Subject: tree-optimization/102046 - fix SLP build from scalars with patterns When we swap operands for SLP builds we lose track where exactly pattern defs are - but we fail to update the any_pattern member of the operands info. Do so conservatively. 2021-08-25 Richard Biener PR tree-optimization/102046 * tree-vect-slp.c (vect_build_slp_tree_2): Conservatively update ->any_pattern when swapping operands. * gcc.dg/vect/pr102046.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr102046.c | 19 +++++++++++++++++++ gcc/tree-vect-slp.c | 4 ++++ 2 files changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr102046.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/vect/pr102046.c b/gcc/testsuite/gcc.dg/vect/pr102046.c new file mode 100644 index 0000000..ae48b49 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr102046.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 -fvect-cost-model=dynamic" } */ +/* { dg-additional-options "-march=btver2" { target x86_64-*-* i?86-*-* } } */ + +struct S +{ + unsigned a, b; +}; + +struct S g; + +void +foo (struct S *o) +{ + struct S s = g; + s.b *= 3; + s.a -= s.a / 2; + *o = s; +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index edc11c6..4d688c7 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2311,6 +2311,10 @@ out: } if (dump_enabled_p ()) dump_printf (MSG_NOTE, "\n"); + /* After swapping some operands we lost track whether an + operand has any pattern defs so be conservative here. */ + if (oprnds_info[0]->any_pattern || oprnds_info[1]->any_pattern) + oprnds_info[0]->any_pattern = oprnds_info[1]->any_pattern = true; /* And try again with scratch 'matches' ... */ bool *tem = XALLOCAVEC (bool, group_size); if ((child = vect_build_slp_tree (vinfo, oprnd_info->def_stmts, -- cgit v1.1 From 43a5d46feabd93ba78983919234f05f5fc9a0982 Mon Sep 17 00:00:00 2001 From: Ankur Saini Date: Wed, 25 Aug 2021 12:33:06 +0530 Subject: analyzer: Impose recursion limit on indirect calls. 2021-08-25 Ankur Saini gcc/analyzer/ChangeLog: PR analyzer/101980 * engine.cc (exploded_graph::maybe_create_dynamic_call): Don't create calls if max recursion limit is reached. --- gcc/analyzer/engine.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'gcc') diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 4ee9279..9c604d1 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -3059,6 +3059,20 @@ exploded_graph::maybe_create_dynamic_call (const gcall *call, new_point.push_to_call_stack (sn_exit, next_point.get_supernode()); + + /* Impose a maximum recursion depth and don't analyze paths + that exceed it further. + This is something of a blunt workaround, but it only + applies to recursion (and mutual recursion), not to + general call stacks. */ + if (new_point.get_call_string ().calc_recursion_depth () + > param_analyzer_max_recursion_depth) + { + if (logger) + logger->log ("rejecting call edge: recursion limit exceeded"); + return false; + } + next_state.push_call (*this, node, call, uncertainty); if (next_state.m_valid) -- cgit v1.1 From 3ac6b5cff1eca4e1748c671960ef7b4ca5e47fd2 Mon Sep 17 00:00:00 2001 From: Lewis Hyatt Date: Tue, 24 Aug 2021 19:30:44 -0400 Subject: diagnostics: Support for -finput-charset [PR93067] Adds the logic to handle -finput-charset in layout_get_source_line(), so that source lines are converted from their input encodings prior to being output by diagnostics machinery. Also adds the ability to strip a UTF-8 BOM similarly. gcc/c-family/ChangeLog: PR other/93067 * c-opts.c (c_common_input_charset_cb): New function. (c_common_post_options): Call new function diagnostic_initialize_input_context(). gcc/d/ChangeLog: PR other/93067 * d-lang.cc (d_input_charset_callback): New function. (d_init): Call new function diagnostic_initialize_input_context(). gcc/fortran/ChangeLog: PR other/93067 * cpp.c (gfc_cpp_post_options): Call new function diagnostic_initialize_input_context(). gcc/ChangeLog: PR other/93067 * coretypes.h (typedef diagnostic_input_charset_callback): Declare. * diagnostic.c (diagnostic_initialize_input_context): New function. * diagnostic.h (diagnostic_initialize_input_context): Declare. * input.c (default_charset_callback): New function. (file_cache::initialize_input_context): New function. (file_cache_slot::create): Added ability to convert the input according to the input context. (file_cache::file_cache): Initialize the new input context. (class file_cache_slot): Added new m_alloc_offset member. (file_cache_slot::file_cache_slot): Initialize the new member. (file_cache_slot::~file_cache_slot): Handle potentially offset buffer. (file_cache_slot::maybe_grow): Likewise. (file_cache_slot::needs_read_p): Handle NULL fp, which is now possible. (file_cache_slot::get_next_line): Likewise. * input.h (class file_cache): Added input context member. libcpp/ChangeLog: PR other/93067 * charset.c (init_iconv_desc): Adapt to permit PFILE argument to be NULL. (_cpp_convert_input): Likewise. Also move UTF-8 BOM logic to... (cpp_check_utf8_bom): ...here. New function. (cpp_input_conversion_is_trivial): New function. * files.c (read_file_guts): Allow PFILE argument to be NULL. Add INPUT_CHARSET argument as an alternate source of this information. (read_file): Pass the new argument to read_file_guts. (cpp_get_converted_source): New function. * include/cpplib.h (struct cpp_converted_source): Declare. (cpp_get_converted_source): Declare. (cpp_input_conversion_is_trivial): Declare. (cpp_check_utf8_bom): Declare. gcc/testsuite/ChangeLog: PR other/93067 * gcc.dg/diagnostic-input-charset-1.c: New test. * gcc.dg/diagnostic-input-utf8-bom.c: New test. --- gcc/c-family/c-opts.c | 13 +++ gcc/coretypes.h | 1 + gcc/d/d-lang.cc | 19 ++++ gcc/diagnostic.c | 11 +++ gcc/diagnostic.h | 19 ++++ gcc/fortran/cpp.c | 6 ++ gcc/input.c | 100 +++++++++++++++++++--- gcc/input.h | 10 +++ gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c | 17 ++++ gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c | 14 +++ 10 files changed, 198 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c create mode 100644 gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c (limited to 'gcc') diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 373af0c..fdde082 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -188,6 +188,14 @@ c_common_diagnostics_set_defaults (diagnostic_context *context) context->opt_permissive = OPT_fpermissive; } +/* Input charset configuration for diagnostics. */ +static const char * +c_common_input_charset_cb (const char * /*filename*/) +{ + const char *cs = cpp_opts->input_charset; + return cpp_input_conversion_is_trivial (cs) ? nullptr : cs; +} + /* Whether options from all C-family languages should be accepted quietly. */ static bool accept_all_c_family_options = false; @@ -1136,6 +1144,11 @@ c_common_post_options (const char **pfilename) cpp_post_options (parse_in); init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in)); + /* Let diagnostics infrastructure know how to convert input files the same + way libcpp will do it, namely using the configured input charset and + skipping a UTF-8 BOM if present. */ + diagnostic_initialize_input_context (global_dc, + c_common_input_charset_cb, true); input_location = UNKNOWN_LOCATION; *pfilename = this_input_filename diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 406572e..726fcad 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -154,6 +154,7 @@ struct cl_option_handlers; struct diagnostic_context; class pretty_printer; class diagnostic_event_id_t; +typedef const char * (*diagnostic_input_charset_callback)(const char *); template struct array_traits; diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 4386a48..fa29a46a 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "print-tree.h" #include "debug.h" +#include "input.h" #include "d-tree.h" #include "id.h" @@ -362,6 +363,19 @@ d_option_lang_mask (void) return CL_D; } +/* Implements input charset and BOM skipping configuration for + diagnostics. */ +static const char *d_input_charset_callback (const char * /*filename*/) +{ + /* TODO: The input charset is automatically determined by code in + dmd/dmodule.c based on the contents of the file. If this detection + logic were factored out and could be reused here, then we would be able + to return UTF-16 or UTF-32 as needed here. For now, we return always + NULL, which means no conversion is necessary, i.e. the input is assumed + to be UTF-8 when diagnostics read this file. */ + return nullptr; +} + /* Implements the lang_hooks.init routine for language D. */ static bool @@ -373,6 +387,11 @@ d_init (void) Expression::_init (); Objc::_init (); + /* Diagnostics input init, to enable BOM skipping and + input charset conversion. */ + diagnostic_initialize_input_context (global_dc, + d_input_charset_callback, true); + /* Back-end init. */ global_binding_level = ggc_cleared_alloc (); current_binding_level = global_binding_level; diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 8361f68..b3afbea 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -293,6 +293,17 @@ diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */) = determine_url_format ((diagnostic_url_rule_t) value); } +/* Create the file_cache, if not already created, and tell it how to + translate files on input. */ +void diagnostic_initialize_input_context (diagnostic_context *context, + diagnostic_input_charset_callback ccb, + bool should_skip_bom) +{ + if (!context->m_file_cache) + context->m_file_cache = new file_cache; + context->m_file_cache->initialize_input_context (ccb, should_skip_bom); +} + /* Do any cleaning up required after the last diagnostic is emitted. */ void diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 7227dae..f90d20a 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -446,6 +446,25 @@ extern void diagnostic_show_locus (diagnostic_context *, diagnostic_t diagnostic_kind); extern void diagnostic_show_any_path (diagnostic_context *, diagnostic_info *); +/* Because we read source files a second time after the frontend did it the + first time, we need to know how the frontend handled things like character + set conversion and UTF-8 BOM stripping, in order to make everything + consistent. This function needs to be called by each frontend that requires + non-default behavior, to inform the diagnostics infrastructure how input is + to be processed. The default behavior is to do no conversion and not to + strip a UTF-8 BOM. + + The callback should return the input charset to be used to convert the given + file's contents to UTF-8, or it should return NULL if no conversion is needed + for this file. SHOULD_SKIP_BOM only applies in case no conversion was + performed, and if true, it will cause a UTF-8 BOM to be skipped at the + beginning of the file. (In case a conversion was performed, the BOM is + rather skipped as part of the conversion process.) */ + +void diagnostic_initialize_input_context (diagnostic_context *context, + diagnostic_input_charset_callback ccb, + bool should_skip_bom); + /* Force diagnostics controlled by OPTIDX to be kind KIND. */ extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *, int /* optidx */, diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c index 419cd6a..83c4517 100644 --- a/gcc/fortran/cpp.c +++ b/gcc/fortran/cpp.c @@ -493,6 +493,12 @@ gfc_cpp_post_options (void) cpp_post_options (cpp_in); + + /* Let diagnostics infrastructure know how to convert input files the same + way libcpp will do it, namely, with no charset conversion but with + skipping of a UTF-8 BOM if present. */ + diagnostic_initialize_input_context (global_dc, nullptr, true); + gfc_cpp_register_include_paths (); } diff --git a/gcc/input.c b/gcc/input.c index de20d98..4b80986 100644 --- a/gcc/input.c +++ b/gcc/input.c @@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "intl.h" #include "diagnostic.h" -#include "diagnostic-core.h" #include "selftest.h" #include "cpplib.h" @@ -30,6 +29,20 @@ along with GCC; see the file COPYING3. If not see #define HAVE_ICONV 0 #endif +/* Input charset configuration. */ +static const char *default_charset_callback (const char *) +{ + return nullptr; +} + +void +file_cache::initialize_input_context (diagnostic_input_charset_callback ccb, + bool should_skip_bom) +{ + in_context.ccb = (ccb ? ccb : default_charset_callback); + in_context.should_skip_bom = should_skip_bom; +} + /* This is a cache used by get_next_line to store the content of a file to be searched for file lines. */ class file_cache_slot @@ -51,7 +64,8 @@ public: void inc_use_count () { m_use_count++; } - void create (const char *file_path, FILE *fp, unsigned highest_use_count); + bool create (const file_cache::input_context &in_context, + const char *file_path, FILE *fp, unsigned highest_use_count); void evict (); private: @@ -110,6 +124,10 @@ public: far. */ char *m_data; + /* The allocated buffer to be freed may start a little earlier than DATA, + e.g. if a UTF8 BOM was skipped at the beginning. */ + int m_alloc_offset; + /* The size of the DATA array above.*/ size_t m_size; @@ -147,6 +165,17 @@ public: doesn't explode. We thus scale total_lines down to line_record_size. */ vec m_line_record; + + void offset_buffer (int offset) + { + gcc_assert (offset < 0 ? m_alloc_offset + offset >= 0 + : (size_t) offset <= m_size); + gcc_assert (m_data); + m_alloc_offset += offset; + m_data += offset; + m_size -= offset; + } + }; /* Current position in real source file. */ @@ -419,21 +448,25 @@ file_cache::add_file (const char *file_path) unsigned highest_use_count = 0; file_cache_slot *r = evicted_cache_tab_entry (&highest_use_count); - r->create (file_path, fp, highest_use_count); + if (!r->create (in_context, file_path, fp, highest_use_count)) + return NULL; return r; } /* Populate this slot for use on FILE_PATH and FP, dropping any existing cached content within it. */ -void -file_cache_slot::create (const char *file_path, FILE *fp, +bool +file_cache_slot::create (const file_cache::input_context &in_context, + const char *file_path, FILE *fp, unsigned highest_use_count) { m_file_path = file_path; if (m_fp) fclose (m_fp); m_fp = fp; + if (m_alloc_offset) + offset_buffer (-m_alloc_offset); m_nb_read = 0; m_line_start_idx = 0; m_line_num = 0; @@ -443,6 +476,36 @@ file_cache_slot::create (const char *file_path, FILE *fp, m_use_count = ++highest_use_count; m_total_lines = total_lines_num (file_path); m_missing_trailing_newline = true; + + + /* Check the input configuration to determine if we need to do any + transformations, such as charset conversion or BOM skipping. */ + if (const char *input_charset = in_context.ccb (file_path)) + { + /* Need a full-blown conversion of the input charset. */ + fclose (m_fp); + m_fp = NULL; + const cpp_converted_source cs + = cpp_get_converted_source (file_path, input_charset); + if (!cs.data) + return false; + if (m_data) + XDELETEVEC (m_data); + m_data = cs.data; + m_nb_read = m_size = cs.len; + m_alloc_offset = cs.data - cs.to_free; + } + else if (in_context.should_skip_bom) + { + if (read_data ()) + { + const int offset = cpp_check_utf8_bom (m_data, m_nb_read); + offset_buffer (offset); + m_nb_read -= offset; + } + } + + return true; } /* file_cache's ctor. */ @@ -450,6 +513,7 @@ file_cache_slot::create (const char *file_path, FILE *fp, file_cache::file_cache () : m_file_slots (new file_cache_slot[num_file_slots]) { + initialize_input_context (nullptr, false); } /* file_cache's dtor. */ @@ -478,8 +542,8 @@ file_cache::lookup_or_add_file (const char *file_path) file_cache_slot::file_cache_slot () : m_use_count (0), m_file_path (NULL), m_fp (NULL), m_data (0), - m_size (0), m_nb_read (0), m_line_start_idx (0), m_line_num (0), - m_total_lines (0), m_missing_trailing_newline (true) + m_alloc_offset (0), m_size (0), m_nb_read (0), m_line_start_idx (0), + m_line_num (0), m_total_lines (0), m_missing_trailing_newline (true) { m_line_record.create (0); } @@ -495,6 +559,7 @@ file_cache_slot::~file_cache_slot () } if (m_data) { + offset_buffer (-m_alloc_offset); XDELETEVEC (m_data); m_data = 0; } @@ -509,7 +574,7 @@ file_cache_slot::~file_cache_slot () bool file_cache_slot::needs_read_p () const { - return (m_nb_read == 0 + return m_fp && (m_nb_read == 0 || m_nb_read == m_size || (m_line_start_idx >= m_nb_read - 1)); } @@ -531,9 +596,20 @@ file_cache_slot::maybe_grow () if (!needs_grow_p ()) return; - size_t size = m_size == 0 ? buffer_size : m_size * 2; - m_data = XRESIZEVEC (char, m_data, size); - m_size = size; + if (!m_data) + { + gcc_assert (m_size == 0 && m_alloc_offset == 0); + m_size = buffer_size; + m_data = XNEWVEC (char, m_size); + } + else + { + const int offset = m_alloc_offset; + offset_buffer (-offset); + m_size *= 2; + m_data = XRESIZEVEC (char, m_data, m_size); + offset_buffer (offset); + } } /* Read more data into the cache. Extends the cache if need be. @@ -632,7 +708,7 @@ file_cache_slot::get_next_line (char **line, ssize_t *line_len) m_missing_trailing_newline = false; } - if (ferror (m_fp)) + if (m_fp && ferror (m_fp)) return false; /* At this point, we've found the end of the of line. It either diff --git a/gcc/input.h b/gcc/input.h index bbcec84..e688107 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -111,6 +111,15 @@ class file_cache file_cache_slot *lookup_or_add_file (const char *file_path); void forcibly_evict_file (const char *file_path); + /* See comments in diagnostic.h about the input conversion context. */ + struct input_context + { + diagnostic_input_charset_callback ccb; + bool should_skip_bom; + }; + void initialize_input_context (diagnostic_input_charset_callback ccb, + bool should_skip_bom); + private: file_cache_slot *evicted_cache_tab_entry (unsigned *highest_use_count); file_cache_slot *add_file (const char *file_path); @@ -119,6 +128,7 @@ class file_cache private: static const size_t num_file_slots = 16; file_cache_slot *m_file_slots; + input_context in_context; }; extern expanded_location diff --git a/gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c b/gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c new file mode 100644 index 0000000..4e56833 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-iconv "CP850" } */ +/* { dg-options "-finput-charset=CP850 -fdiagnostics-show-caret" } */ + +/* Test that diagnostics are converted to UTF-8; this file is encoded in + CP850. Why CP850? -finput-charset only supports encodings that are a + superset of ASCII. But encodings that look like latin-1 are automatically + converted by expect to UTF-8, and hence by the time dg sees them, it can't + verify they were actually output in UTF-8. So codepage 850 was chosen as one + that is hopefully available and meets the requirements of matching ASCII and + not matching latin-1. */ +const char *section = "õ" +/* { dg-error "expected .* at end of input" "" { target *-*-*} .-1 } */ +/* { dg-begin-multiline-output "" } + const char *section = "§" + ^~~~~ + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c b/gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c new file mode 100644 index 0000000..1a3f352 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c @@ -0,0 +1,14 @@ +int 1; +/* { dg-do compile } */ +/* { dg-options "-fdiagnostics-show-caret" } */ + +/* This file begins with a UTF-8 byte order mark. Verify that diagnostics + still point to the right place, since the stripping of the BOM happens twice, + once when libcpp reads the file, and once when diagnostics infrastucture + reads it. */ + +/* { dg-error "expected .* before numeric constant" "" { target *-*-*} 1 } */ +/* { dg-begin-multiline-output "" } + int 1; + ^ + { dg-end-multiline-output "" } */ -- cgit v1.1 From bb24717e5042b6e8a3847e780a8d215edb9c62f6 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 25 Aug 2021 15:11:47 -0400 Subject: Make xxsplti*, xpermx, xxeval be vecperm type. I noticed that the built-functions for xxspltiw, xxspltidp, xxsplti32dx, xxpermx, and xxeval all used the 'vecsimple' type. These instructions are permute instructions (3 cycle latency) and should use 'vecperm' instead. While I was at it, I changed the UNSPEC name for xxspltidp to be UNSPEC_XXSPLTIDP instead of UNSPEC_XXSPLTID. 2021-08-25 Michael Meissner gcc/ * config/rs6000/vsx.md (UNSPEC_XXSPLTIDP): Rename from UNSPEC_XXSPLTID. (xxspltiw_v4si): Use vecperm type attribute. (xxspltiw_v4si_inst): Use vecperm type attribute. (xxspltiw_v4sf_inst): Likewise. (xxspltidp_v2df): Use vecperm type attribute. Use UNSPEC_XXSPLTIDP instead of UNSPEC_XXSPLTID. (xxspltidp_v2df_inst): Likewise. (xxsplti32dx_v4si): Use vecperm type attribute. (xxsplti32dx_v4si_inst): Likewise. (xxsplti32dx_v4sf_inst): Likewise. (xxblend_): Likewise. (xxpermx): Likewise. (xxpermx_inst): Likewise. (xxeval): Likewise. --- gcc/config/rs6000/vsx.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'gcc') diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index e4ca6e9..bf033e3 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -374,7 +374,7 @@ UNSPEC_VDIVEU UNSPEC_XXEVAL UNSPEC_XXSPLTIW - UNSPEC_XXSPLTID + UNSPEC_XXSPLTIDP UNSPEC_XXSPLTI32DX UNSPEC_XXBLEND UNSPEC_XXPERMX @@ -6414,7 +6414,7 @@ UNSPEC_XXSPLTIW))] "TARGET_POWER10" "xxspltiw %x0,%1" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) (define_expand "xxspltiw_v4sf" @@ -6434,14 +6434,14 @@ UNSPEC_XXSPLTIW))] "TARGET_POWER10" "xxspltiw %x0,%1" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) ;; XXSPLTIDP built-in function support (define_expand "xxspltidp_v2df" [(set (match_operand:V2DF 0 "register_operand" ) (unspec:V2DF [(match_operand:SF 1 "const_double_operand")] - UNSPEC_XXSPLTID))] + UNSPEC_XXSPLTIDP))] "TARGET_POWER10" { long value = rs6000_const_f32_to_i32 (operands[1]); @@ -6452,10 +6452,10 @@ (define_insn "xxspltidp_v2df_inst" [(set (match_operand:V2DF 0 "register_operand" "=wa") (unspec:V2DF [(match_operand:SI 1 "c32bit_cint_operand" "n")] - UNSPEC_XXSPLTID))] + UNSPEC_XXSPLTIDP))] "TARGET_POWER10" "xxspltidp %x0,%1" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) ;; XXSPLTI32DX built-in function support @@ -6476,7 +6476,7 @@ GEN_INT (index), operands[3])); DONE; } - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecperm")]) (define_insn "xxsplti32dx_v4si_inst" [(set (match_operand:V4SI 0 "register_operand" "=wa") @@ -6486,7 +6486,7 @@ UNSPEC_XXSPLTI32DX))] "TARGET_POWER10" "xxsplti32dx %x0,%2,%3" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) (define_expand "xxsplti32dx_v4sf" @@ -6515,7 +6515,7 @@ UNSPEC_XXSPLTI32DX))] "TARGET_POWER10" "xxsplti32dx %x0,%2,%3" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) ;; XXBLEND built-in function support @@ -6527,7 +6527,7 @@ UNSPEC_XXBLEND))] "TARGET_POWER10" "xxblendv %x0,%x1,%x2,%x3" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) ;; XXPERMX built-in function support @@ -6562,7 +6562,7 @@ DONE; } - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecperm")]) (define_insn "xxpermx_inst" [(set (match_operand:V2DI 0 "register_operand" "+v") @@ -6573,7 +6573,7 @@ UNSPEC_XXPERMX))] "TARGET_POWER10" "xxpermx %x0,%x1,%x2,%x3,%4" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) ;; XXEVAL built-in function support @@ -6586,6 +6586,6 @@ UNSPEC_XXEVAL))] "TARGET_POWER10" "xxeval %0,%1,%2,%3,%4" - [(set_attr "type" "vecsimple") + [(set_attr "type" "vecperm") (set_attr "prefixed" "yes")]) -- cgit v1.1 From 5c85f29537662f1f4195a102cbf0182ffa32d8ac Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 25 Aug 2021 21:43:07 +0200 Subject: Merge load/stores in ipa-modref summaries this patch adds logic needed to merge neighbouring accesses in ipa-modref summaries. This helps analyzing array initializers and similar code. It is bit of work, since it breaks the fact that modref tree makes a good lattice for dataflow: the access ranges can be extended indefinitely. For this reason I added counter tracking number of adjustments and a cap to limit them during the dataflow. gcc/ChangeLog: * doc/invoke.texi: Document --param modref-max-adjustments. * ipa-modref-tree.c (test_insert_search_collapse): Update. (test_merge): Update. * ipa-modref-tree.h (struct modref_access_node): Add adjustments; (modref_access_node::operator==): Fix handling of access ranges. (modref_access_node::contains): Constify parameter; handle also mismatched parm offsets. (modref_access_node::update): New function. (modref_access_node::merge): New function. (unspecified_modref_access_node): Update constructor. (modref_ref_node::insert_access): Add record_adjustments parameter; handle merging. (modref_ref_node::try_merge_with): New private function. (modref_tree::insert): New record_adjustments parameter. (modref_tree::merge): New record_adjustments parameter. (modref_tree::copy_from): Update. * ipa-modref.c (dump_access): Dump adjustments field. (get_access): Update constructor. (record_access): Update call of insert. (record_access_lto): Update call of insert. (merge_call_side_effects): Add record_adjustments parameter. (get_access_for_fnspec): Update. (process_fnspec): Update. (analyze_call): Update. (analyze_function): Update. (read_modref_records): Update. (ipa_merge_modref_summary_after_inlining): Update. (propagate_unknown_call): Update. (modref_propagate_in_scc): Update. * params.opt (param-max-modref-adjustments=): New. gcc/testsuite/ChangeLog: * gcc.dg/ipa/modref-1.c: Update testcase. * gcc.dg/tree-ssa/modref-4.c: Update testcase. * gcc.dg/tree-ssa/modref-8.c: New test. --- gcc/doc/invoke.texi | 4 + gcc/ipa-modref-tree.c | 44 +++--- gcc/ipa-modref-tree.h | 247 ++++++++++++++++++++++++++++--- gcc/ipa-modref.c | 80 ++++++---- gcc/params.opt | 4 + gcc/testsuite/gcc.dg/ipa/modref-1.c | 8 +- gcc/testsuite/gcc.dg/tree-ssa/modref-4.c | 8 +- gcc/testsuite/gcc.dg/tree-ssa/modref-8.c | 25 ++++ 8 files changed, 342 insertions(+), 78 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/modref-8.c (limited to 'gcc') diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index b8f5d9e..b83bd90 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -13423,6 +13423,10 @@ Setting to 0 disables the analysis completely. @item modref-max-escape-points Specifies the maximum number of escape points tracked by modref per SSA-name. +@item modref-max-adjustments +Specifies the maximum number the access range is enlarged during modref dataflow +analysis. + @item profile-func-internal-id A parameter to control whether to use function internal id in profile database lookup. If the value is 0, the compiler uses an id that diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c index 64e57f5..69395b0 100644 --- a/gcc/ipa-modref-tree.c +++ b/gcc/ipa-modref-tree.c @@ -41,7 +41,7 @@ test_insert_search_collapse () ASSERT_FALSE (t->every_base); /* Insert into an empty tree. */ - t->insert (1, 2, a); + t->insert (1, 2, a, false); ASSERT_NE (t->bases, NULL); ASSERT_EQ (t->bases->length (), 1); ASSERT_FALSE (t->every_base); @@ -59,7 +59,7 @@ test_insert_search_collapse () ASSERT_EQ (ref_node->ref, 2); /* Insert when base exists but ref does not. */ - t->insert (1, 3, a); + t->insert (1, 3, a, false); ASSERT_NE (t->bases, NULL); ASSERT_EQ (t->bases->length (), 1); ASSERT_EQ (t->search (1), base_node); @@ -72,7 +72,7 @@ test_insert_search_collapse () /* Insert when base and ref exist, but access is not dominated by nor dominates other accesses. */ - t->insert (1, 2, a); + t->insert (1, 2, a, false); ASSERT_EQ (t->bases->length (), 1); ASSERT_EQ (t->search (1), base_node); @@ -80,12 +80,12 @@ test_insert_search_collapse () ASSERT_NE (ref_node, NULL); /* Insert when base and ref exist and access is dominated. */ - t->insert (1, 2, a); + t->insert (1, 2, a, false); ASSERT_EQ (t->search (1), base_node); ASSERT_EQ (base_node->search (2), ref_node); /* Insert ref to trigger ref list collapse for base 1. */ - t->insert (1, 4, a); + t->insert (1, 4, a, false); ASSERT_EQ (t->search (1), base_node); ASSERT_EQ (base_node->refs, NULL); ASSERT_EQ (base_node->search (2), NULL); @@ -93,7 +93,7 @@ test_insert_search_collapse () ASSERT_TRUE (base_node->every_ref); /* Further inserts to collapsed ref list are ignored. */ - t->insert (1, 5, a); + t->insert (1, 5, a, false); ASSERT_EQ (t->search (1), base_node); ASSERT_EQ (base_node->refs, NULL); ASSERT_EQ (base_node->search (2), NULL); @@ -101,13 +101,13 @@ test_insert_search_collapse () ASSERT_TRUE (base_node->every_ref); /* Insert base to trigger base list collapse. */ - t->insert (5, 6, a); + t->insert (5, 6, a, false); ASSERT_TRUE (t->every_base); ASSERT_EQ (t->bases, NULL); ASSERT_EQ (t->search (1), NULL); /* Further inserts to collapsed base list are ignored. */ - t->insert (7, 8, a); + t->insert (7, 8, a, false); ASSERT_TRUE (t->every_base); ASSERT_EQ (t->bases, NULL); ASSERT_EQ (t->search (1), NULL); @@ -123,22 +123,22 @@ test_merge () modref_access_node a = unspecified_modref_access_node; t1 = new modref_tree(3, 4, 1); - t1->insert (1, 1, a); - t1->insert (1, 2, a); - t1->insert (1, 3, a); - t1->insert (2, 1, a); - t1->insert (3, 1, a); + t1->insert (1, 1, a, false); + t1->insert (1, 2, a, false); + t1->insert (1, 3, a, false); + t1->insert (2, 1, a, false); + t1->insert (3, 1, a, false); t2 = new modref_tree(10, 10, 10); - t2->insert (1, 2, a); - t2->insert (1, 3, a); - t2->insert (1, 4, a); - t2->insert (3, 2, a); - t2->insert (3, 3, a); - t2->insert (3, 4, a); - t2->insert (3, 5, a); - - t1->merge (t2, NULL); + t2->insert (1, 2, a, false); + t2->insert (1, 3, a, false); + t2->insert (1, 4, a, false); + t2->insert (3, 2, a, false); + t2->insert (3, 3, a, false); + t2->insert (3, 4, a, false); + t2->insert (3, 5, a, false); + + t1->merge (t2, NULL, false); ASSERT_FALSE (t1->every_base); ASSERT_NE (t1->bases, NULL); diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h index 2e26b75..6f6932f 100644 --- a/gcc/ipa-modref-tree.h +++ b/gcc/ipa-modref-tree.h @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see Again ref is an template to allow LTO streaming. 3) Access: this level represent info about individual accesses. Presently we record whether access is through a dereference of a function parameter + and if so we record the access range. */ #ifndef GCC_MODREF_TREE_H @@ -57,6 +58,9 @@ struct GTY(()) modref_access_node a function parameter. */ int parm_index; bool parm_offset_known; + /* Number of times interval was extended during dataflow. + This has to be limited in order to keep dataflow finite. */ + unsigned char adjustments; /* Return true if access node holds no useful info. */ bool useful_p () const @@ -84,6 +88,8 @@ struct GTY(()) modref_access_node && !known_eq (parm_offset, a.parm_offset)) return false; } + if (range_info_useful_p () != a.range_info_useful_p ()) + return false; if (range_info_useful_p () && (!known_eq (a.offset, offset) || !known_eq (a.size, size) @@ -92,16 +98,24 @@ struct GTY(()) modref_access_node return true; } /* Return true A is a subaccess. */ - bool contains (modref_access_node &a) const + bool contains (const modref_access_node &a) const { - if (parm_index != a.parm_index) - return false; + poly_int64 aoffset_adj = 0; if (parm_index >= 0) { - if (parm_offset_known - && (!a.parm_offset_known - || !known_eq (parm_offset, a.parm_offset))) + if (parm_index != a.parm_index) return false; + if (parm_offset_known) + { + if (!a.parm_offset_known) + return false; + /* Accesses are never below parm_offset, so look + for smaller offset. */ + if (!known_le (parm_offset, a.parm_offset)) + return false; + aoffset_adj = (a.parm_offset - parm_offset) + << LOG2_BITS_PER_UNIT; + } } if (range_info_useful_p ()) { @@ -111,20 +125,181 @@ struct GTY(()) modref_access_node to fit the store, so smaller or unknown sotre is more general than large store. */ if (known_size_p (size) - && !known_le (size, a.size)) + && (!known_size_p (a.size) + || !known_le (size, a.size))) return false; if (known_size_p (max_size)) - return known_subrange_p (a.offset, a.max_size, offset, max_size); + return known_subrange_p (a.offset + aoffset_adj, + a.max_size, offset, max_size); else - return known_le (offset, a.offset); + return known_le (offset, a.offset + aoffset_adj); } return true; } + /* Update access range to new parameters. + If RECORD_ADJUSTMENTS is true, record number of changes in the access + and if threshold is exceeded start dropping precision + so only constantly many updates are possible. This makes dataflow + to converge. */ + void update (poly_int64 parm_offset1, + poly_int64 offset1, poly_int64 size1, poly_int64 max_size1, + bool record_adjustments) + { + if (known_eq (offset, offset1) + && known_eq (size, size1) + && known_eq (max_size, max_size1)) + return; + if (!record_adjustments + || (++adjustments) < param_modref_max_adjustments) + { + parm_offset = parm_offset1; + offset = offset1; + size = size1; + max_size = max_size1; + } + else + { + if (dump_file) + fprintf (dump_file, + "--param param=modref-max-adjustments limit reached:"); + if (!known_eq (parm_offset, parm_offset1)) + { + if (dump_file) + fprintf (dump_file, " parm_offset cleared"); + parm_offset_known = false; + } + if (!known_eq (size, size1)) + { + size = -1; + if (dump_file) + fprintf (dump_file, " size cleared"); + } + if (!known_eq (max_size, max_size1)) + { + max_size = -1; + if (dump_file) + fprintf (dump_file, " max_size cleared"); + } + if (!known_eq (offset, offset1)) + { + offset = 0; + if (dump_file) + fprintf (dump_file, " offset cleared"); + } + if (dump_file) + fprintf (dump_file, "\n"); + } + } + /* Merge in access A if it is possible to do without losing + precision. Return true if successful. + If RECORD_ADJUSTMENTs is true, remember how many interval + was prolonged and punt when there are too many. */ + bool merge (const modref_access_node &a, bool record_adjustments) + { + poly_int64 aoffset_adj = 0, offset_adj = 0; + poly_int64 new_parm_offset = parm_offset; + + /* We assume that containment was tested earlier. */ + gcc_checking_assert (!contains (a) && !a.contains (*this)); + if (parm_index >= 0) + { + if (parm_index != a.parm_index) + return false; + if (parm_offset_known) + { + if (!a.parm_offset_known) + return false; + if (known_le (a.parm_offset, parm_offset)) + { + offset_adj = (parm_offset - a.parm_offset) + << LOG2_BITS_PER_UNIT; + aoffset_adj = 0; + new_parm_offset = a.parm_offset; + } + else if (known_le (parm_offset, a.parm_offset)) + { + aoffset_adj = (a.parm_offset - parm_offset) + << LOG2_BITS_PER_UNIT; + offset_adj = 0; + } + else + return false; + } + } + /* See if we can merge ranges. */ + if (range_info_useful_p ()) + { + poly_int64 offset1 = offset + offset_adj; + poly_int64 aoffset1 = a.offset + aoffset_adj; + + /* In this case we have containment that should be + handled earlier. */ + gcc_checking_assert (a.range_info_useful_p ()); + + /* If a.size is less specified than size, merge only + if intervals are otherwise equivalent. */ + if (known_size_p (size) + && (!known_size_p (a.size) || known_lt (a.size, size))) + { + if (((known_size_p (max_size) || known_size_p (a.max_size)) + && !known_eq (max_size, a.max_size)) + || !known_eq (offset1, aoffset1)) + return false; + update (new_parm_offset, offset1, a.size, max_size, + record_adjustments); + return true; + } + /* If sizes are same, we can extend the interval. */ + if ((known_size_p (size) || known_size_p (a.size)) + && !known_eq (size, a.size)) + return false; + if (known_le (offset1, aoffset1)) + { + if (!known_size_p (max_size)) + { + update (new_parm_offset, offset1, size, max_size, + record_adjustments); + return true; + } + else if (known_ge (offset1 + max_size, aoffset1)) + { + poly_int64 new_max_size = max_size; + if (known_le (max_size, a.max_size + aoffset1 - offset1)) + new_max_size = a.max_size + aoffset1 - offset1; + update (new_parm_offset, offset1, size, new_max_size, + record_adjustments); + return true; + } + } + else if (known_le (aoffset1, offset1)) + { + if (!known_size_p (a.max_size)) + { + update (new_parm_offset, aoffset1, size, a.max_size, + record_adjustments); + return true; + } + else if (known_ge (aoffset1 + a.max_size, offset1)) + { + poly_int64 new_max_size = a.max_size; + if (known_le (a.max_size, max_size + offset1 - aoffset1)) + new_max_size = max_size + offset1 - aoffset1; + update (new_parm_offset, aoffset1, size, new_max_size, + record_adjustments); + return true; + } + } + return false; + } + update (new_parm_offset, offset + offset_adj, + size, max_size, record_adjustments); + return true; + } }; /* Access node specifying no useful info. */ const modref_access_node unspecified_modref_access_node - = {0, -1, -1, 0, -1, false}; + = {0, -1, -1, 0, -1, false, 0}; template struct GTY((user)) modref_ref_node @@ -149,8 +324,10 @@ struct GTY((user)) modref_ref_node /* Insert access with OFFSET and SIZE. Collapse tree if it has more than MAX_ACCESSES entries. + If RECORD_ADJUSTMENTs is true avoid too many interval extensions. Return true if record was changed. */ - bool insert_access (modref_access_node a, size_t max_accesses) + bool insert_access (modref_access_node a, size_t max_accesses, + bool record_adjustments) { /* If this base->ref pair has no access information, bail out. */ if (every_access) @@ -176,7 +353,17 @@ struct GTY((user)) modref_ref_node return false; if (a.contains (*a2)) { - *a2 = a; + a.adjustments = 0; + a2->parm_index = a.parm_index; + a2->parm_offset_known = a.parm_offset_known; + a2->update (a.parm_offset, a.offset, a.size, a.max_size, + record_adjustments); + try_merge_with (i); + return true; + } + if (a2->merge (a, record_adjustments)) + { + try_merge_with (i); return true; } gcc_checking_assert (!(a == *a2)); @@ -192,9 +379,28 @@ struct GTY((user)) modref_ref_node collapse (); return true; } + a.adjustments = 0; vec_safe_push (accesses, a); return true; } +private: + /* Try to optimize the access list after entry INDEX was modified. */ + void + try_merge_with (size_t index) + { + modref_access_node *a2; + size_t i; + + FOR_EACH_VEC_SAFE_ELT (accesses, i, a2) + if (i != index) + if ((*accesses)[index].contains (*a2) + || (*accesses)[index].merge (*a2, false)) + { + if (index == accesses->length () - 1) + index = i; + accesses->unordered_remove (i); + } + } }; /* Base of an access. */ @@ -342,7 +548,8 @@ struct GTY((user)) modref_tree /* Insert memory access to the tree. Return true if something changed. */ - bool insert (T base, T ref, modref_access_node a) + bool insert (T base, T ref, modref_access_node a, + bool record_adjustments) { if (every_base) return false; @@ -387,7 +594,8 @@ struct GTY((user)) modref_tree { if (ref_node->every_access) return changed; - changed |= ref_node->insert_access (a, max_accesses); + changed |= ref_node->insert_access (a, max_accesses, + record_adjustments); /* See if we failed to add useful access. */ if (ref_node->every_access) { @@ -456,7 +664,8 @@ struct GTY((user)) modref_tree PARM_MAP, if non-NULL, maps parm indexes of callee to caller. -2 is used to signalize that parameter is local and does not need to be tracked. Return true if something has changed. */ - bool merge (modref_tree *other, vec *parm_map) + bool merge (modref_tree *other, vec *parm_map, + bool record_accesses) { if (!other || every_base) return false; @@ -501,7 +710,8 @@ struct GTY((user)) modref_tree { changed |= insert (base_node->base, ref_node->ref, - unspecified_modref_access_node); + unspecified_modref_access_node, + record_accesses); } else FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node) @@ -525,7 +735,8 @@ struct GTY((user)) modref_tree = (*parm_map) [a.parm_index].parm_index; } } - changed |= insert (base_node->base, ref_node->ref, a); + changed |= insert (base_node->base, ref_node->ref, a, + record_accesses); } } } @@ -537,7 +748,7 @@ struct GTY((user)) modref_tree /* Copy OTHER to THIS. */ void copy_from (modref_tree *other) { - merge (other, NULL); + merge (other, NULL, false); } /* Search BASE in tree; return NULL if failed. */ diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index 6ab687a..0d5ab9c 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -426,6 +426,8 @@ dump_access (modref_access_node *a, FILE *out) print_dec ((poly_int64_pod)a->size, out, SIGNED); fprintf (out, " max_size:"); print_dec ((poly_int64_pod)a->max_size, out, SIGNED); + if (a->adjustments) + fprintf (out, " adjusted %i times", a->adjustments); } fprintf (out, "\n"); } @@ -656,7 +658,7 @@ get_access (ao_ref *ref) base = ao_ref_base (ref); modref_access_node a = {ref->offset, ref->size, ref->max_size, - 0, -1, false}; + 0, -1, false, 0}; if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF) { tree memref = base; @@ -708,7 +710,7 @@ record_access (modref_records *tt, ao_ref *ref) fprintf (dump_file, " - Recording base_set=%i ref_set=%i parm=%i\n", base_set, ref_set, a.parm_index); } - tt->insert (base_set, ref_set, a); + tt->insert (base_set, ref_set, a, false); } /* IPA version of record_access_tree. */ @@ -774,7 +776,7 @@ record_access_lto (modref_records_lto *tt, ao_ref *ref) a.parm_index); } - tt->insert (base_type, ref_type, a); + tt->insert (base_type, ref_type, a, false); } /* Returns true if and only if we should store the access to EXPR. @@ -858,12 +860,15 @@ parm_map_for_arg (gimple *stmt, int i) /* Merge side effects of call STMT to function with CALLEE_SUMMARY int CUR_SUMMARY. Return true if something changed. - If IGNORE_STORES is true, do not merge stores. */ + If IGNORE_STORES is true, do not merge stores. + If RECORD_ADJUSTMENTS is true cap number of adjustments to + a given access to make dataflow finite. */ bool merge_call_side_effects (modref_summary *cur_summary, gimple *stmt, modref_summary *callee_summary, - bool ignore_stores, cgraph_node *callee_node) + bool ignore_stores, cgraph_node *callee_node, + bool record_adjustments) { auto_vec parm_map; bool changed = false; @@ -902,11 +907,13 @@ merge_call_side_effects (modref_summary *cur_summary, fprintf (dump_file, "\n"); /* Merge with callee's summary. */ - changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map); + changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map, + record_adjustments); if (!ignore_stores) { changed |= cur_summary->stores->merge (callee_summary->stores, - &parm_map); + &parm_map, + record_adjustments); if (!cur_summary->writes_errno && callee_summary->writes_errno) { @@ -941,7 +948,7 @@ get_access_for_fnspec (gcall *call, attr_fnspec &fnspec, } modref_access_node a = {0, -1, -1, map.parm_offset, map.parm_index, - map.parm_offset_known}; + map.parm_offset_known, 0}; poly_int64 size_hwi; if (size && poly_int_tree_p (size, &size_hwi) @@ -1044,12 +1051,14 @@ process_fnspec (modref_summary *cur_summary, cur_summary->loads->insert (0, 0, get_access_for_fnspec (call, fnspec, i, - map)); + map), + false); if (cur_summary_lto) cur_summary_lto->loads->insert (0, 0, get_access_for_fnspec (call, fnspec, i, - map)); + map), + false); } } if (ignore_stores) @@ -1077,12 +1086,14 @@ process_fnspec (modref_summary *cur_summary, cur_summary->stores->insert (0, 0, get_access_for_fnspec (call, fnspec, i, - map)); + map), + false); if (cur_summary_lto) cur_summary_lto->stores->insert (0, 0, get_access_for_fnspec (call, fnspec, i, - map)); + map), + false); } if (fnspec.errno_maybe_written_p () && flag_errno_math) { @@ -1168,7 +1179,7 @@ analyze_call (modref_summary *cur_summary, modref_summary_lto *cur_summary_lto, } merge_call_side_effects (cur_summary, stmt, callee_summary, ignore_stores, - callee_node); + callee_node, false); return true; } @@ -2134,6 +2145,7 @@ analyze_function (function *f, bool ipa) if (!ipa) { bool changed = true; + bool first = true; while (changed) { changed = false; @@ -2144,13 +2156,14 @@ analyze_function (function *f, bool ipa) ignore_stores_p (current_function_decl, gimple_call_flags (recursive_calls[i])), - fnode); + fnode, !first); if (!summary->useful_p (ecf_flags, false)) { remove_summary (lto, nolto, ipa); return; } } + first = false; } } if (summary && !summary->useful_p (ecf_flags)) @@ -2501,11 +2514,11 @@ read_modref_records (lto_input_block *ib, struct data_in *data_in, } } modref_access_node a = {offset, size, max_size, parm_offset, - parm_index, parm_offset_known}; + parm_index, parm_offset_known, false}; if (nolto_ref_node) - nolto_ref_node->insert_access (a, max_accesses); + nolto_ref_node->insert_access (a, max_accesses, false); if (lto_ref_node) - lto_ref_node->insert_access (a, max_accesses); + lto_ref_node->insert_access (a, max_accesses, false); } } } @@ -3187,16 +3200,18 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge) if (!ignore_stores) { if (to_info && callee_info) - to_info->stores->merge (callee_info->stores, &parm_map); + to_info->stores->merge (callee_info->stores, &parm_map, false); if (to_info_lto && callee_info_lto) - to_info_lto->stores->merge (callee_info_lto->stores, &parm_map); + to_info_lto->stores->merge (callee_info_lto->stores, &parm_map, + false); } if (!(flags & (ECF_CONST | ECF_NOVOPS))) { if (to_info && callee_info) - to_info->loads->merge (callee_info->loads, &parm_map); + to_info->loads->merge (callee_info->loads, &parm_map, false); if (to_info_lto && callee_info_lto) - to_info_lto->loads->merge (callee_info_lto->loads, &parm_map); + to_info_lto->loads->merge (callee_info_lto->loads, &parm_map, + false); } } @@ -3346,7 +3361,7 @@ get_access_for_fnspec (cgraph_edge *e, attr_fnspec &fnspec, size = TYPE_SIZE_UNIT (get_parm_type (e->callee->decl, i)); modref_access_node a = {0, -1, -1, map.parm_offset, map.parm_index, - map.parm_offset_known}; + map.parm_offset_known, 0}; poly_int64 size_hwi; if (size && poly_int_tree_p (size, &size_hwi) @@ -3399,10 +3414,10 @@ propagate_unknown_call (cgraph_node *node, } if (cur_summary) changed |= cur_summary->loads->insert - (0, 0, get_access_for_fnspec (e, fnspec, i, map)); + (0, 0, get_access_for_fnspec (e, fnspec, i, map), false); if (cur_summary_lto) changed |= cur_summary_lto->loads->insert - (0, 0, get_access_for_fnspec (e, fnspec, i, map)); + (0, 0, get_access_for_fnspec (e, fnspec, i, map), false); } } if (ignore_stores_p (node->decl, ecf_flags)) @@ -3429,10 +3444,10 @@ propagate_unknown_call (cgraph_node *node, } if (cur_summary) changed |= cur_summary->stores->insert - (0, 0, get_access_for_fnspec (e, fnspec, i, map)); + (0, 0, get_access_for_fnspec (e, fnspec, i, map), false); if (cur_summary_lto) changed |= cur_summary_lto->stores->insert - (0, 0, get_access_for_fnspec (e, fnspec, i, map)); + (0, 0, get_access_for_fnspec (e, fnspec, i, map), false); } } if (fnspec.errno_maybe_written_p () && flag_errno_math) @@ -3491,6 +3506,7 @@ static void modref_propagate_in_scc (cgraph_node *component_node) { bool changed = true; + bool first = true; int iteration = 0; while (changed) @@ -3628,11 +3644,12 @@ modref_propagate_in_scc (cgraph_node *component_node) if (callee_summary) { changed |= cur_summary->loads->merge - (callee_summary->loads, &parm_map); + (callee_summary->loads, &parm_map, !first); if (!ignore_stores) { changed |= cur_summary->stores->merge - (callee_summary->stores, &parm_map); + (callee_summary->stores, &parm_map, + !first); if (!cur_summary->writes_errno && callee_summary->writes_errno) { @@ -3644,11 +3661,13 @@ modref_propagate_in_scc (cgraph_node *component_node) if (callee_summary_lto) { changed |= cur_summary_lto->loads->merge - (callee_summary_lto->loads, &parm_map); + (callee_summary_lto->loads, &parm_map, + !first); if (!ignore_stores) { changed |= cur_summary_lto->stores->merge - (callee_summary_lto->stores, &parm_map); + (callee_summary_lto->stores, &parm_map, + !first); if (!cur_summary_lto->writes_errno && callee_summary_lto->writes_errno) { @@ -3674,6 +3693,7 @@ modref_propagate_in_scc (cgraph_node *component_node) } } iteration++; + first = false; } if (dump_file) fprintf (dump_file, diff --git a/gcc/params.opt b/gcc/params.opt index f414dc1..cec43d2 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -1013,6 +1013,10 @@ Maximum depth of DFS walk used by modref escape analysis. Common Joined UInteger Var(param_modref_max_escape_points) Init(256) Param Optimization Maximum number of escape points tracked by modref per SSA-name. +-param=modref-max-adjustments= +Common Joined UInteger Var(param_modref_max_adjustments) Init(8) IntegerRange (0, 254) Param Optimization +Maximum number of times a given range is adjusted during the dataflow + -param=tm-max-aggregate-size= Common Joined UInteger Var(param_tm_max_aggregate_size) Init(9) Param Optimization Size in bytes after which thread-local aggregates should be instrumented with the logging functions instead of save/restore pairs. diff --git a/gcc/testsuite/gcc.dg/ipa/modref-1.c b/gcc/testsuite/gcc.dg/ipa/modref-1.c index 858567d..5314e7d 100644 --- a/gcc/testsuite/gcc.dg/ipa/modref-1.c +++ b/gcc/testsuite/gcc.dg/ipa/modref-1.c @@ -10,15 +10,15 @@ void a(char *ptr, char *ptr2) __attribute__((noinline)) void b(char *ptr) { - a(ptr+1,&ptr[2]); + a(ptr+1,&ptr[3]); } int main() { - char c[3]={0,1,0}; + char c[4]={0,1,0,0}; b(c); - return c[0]+c[2]; + return c[0]+c[3]; } /* Check that both param offsets are determined correctly. */ /* { dg-final { scan-ipa-dump "param offset:1" "modref" } } */ -/* { dg-final { scan-ipa-dump "param offset:2" "modref" } } */ +/* { dg-final { scan-ipa-dump "param offset:3" "modref" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c index 3ac217b..a277c70 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c @@ -10,17 +10,17 @@ void a(char *ptr, char *ptr2) __attribute__((noinline)) void b(char *ptr) { - a(ptr+1,&ptr[2]); + a(ptr+1,&ptr[3]); } int main() { - char c[4]={0,1,2,0}; + char c[5]={0,1,2,0,0}; b(c); - return c[0]+c[3]; + return c[0]+c[4]; } /* Check that both param offsets are determined correctly and the computation is optimized out. */ /* { dg-final { scan-tree-dump "param offset:1" "modref1" } } */ -/* { dg-final { scan-tree-dump "param offset:2" "modref1" } } */ +/* { dg-final { scan-tree-dump "param offset:3" "modref1" } } */ /* { dg-final { scan-tree-dump "return 0" "modref1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c new file mode 100644 index 0000000..15ae4ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c @@ -0,0 +1,25 @@ +/* { dg-options "-O2 --param modref-max-adjustments=8 -fdump-tree-modref1" } */ +/* { dg-do compile } */ +void +set (char *p) +{ + p[1]=1; + p[0]=0; + p[2]=2; + p[4]=4; + p[3]=3; +} + +void +recurse (char *p, int n) +{ + *p = 0; + if (n) + recurse (p+1,n-1); +} +/* { dg-final { scan-tree-dump-not "param=modref-max-accesses" "modref1" } } */ +/* { dg-final { scan-tree-dump "param=modref-max-adjustments" "modref1" } } */ +/* In set all accesses should merge together. */ +/* { dg-final { scan-tree-dump "access: Parm 0 param offset:0 offset:0 size:8 max_size:40" "modref1" } } */ +/* In recurse we should cap the recrusion after 8 attempts and set max_size to -1. */ +/* { dg-final { scan-tree-dump "access: Parm 0 param offset:0 offset:0 size:8 max_size:-1 adjusted 8 times" "modref1" } } */ -- cgit v1.1 From 1ab84eda5548119908c4e24c6ad953dd7c00a5b7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 25 Aug 2021 22:35:21 +0200 Subject: c++: Fix up value initialization of structs with zero width bitfields [PR102019] The removal of remove_zero_width_bit_fields, in addition to triggering some ABI issues that need solving anyway (ABI incompatibility between C and C++) also resulted in UB inside of gcc, we now call build_zero_init which calls build_int_cst on an integral type with TYPE_PRECISION of 0. Fixed by ignoring the zero width bitfields. I understand build_value_init_noctor wants to initialize to 0 even unnamed bitfields (of non-zero width), at least until we have some CONSTRUCTOR flag that says that even all the padding bits should be cleared. 2021-08-25 Jakub Jelinek PR c++/102019 * init.c (build_value_init_noctor): Ignore unnamed zero-width bitfields. --- gcc/cp/init.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc') diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 229c84e..1426f9a 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -427,6 +427,11 @@ build_value_init_noctor (tree type, tsubst_flags_t complain) == NULL_TREE)) continue; + /* Ignore unnamed zero-width bitfields. */ + if (DECL_UNNAMED_BIT_FIELD (field) + && integer_zerop (DECL_SIZE (field))) + continue; + /* We could skip vfields and fields of types with user-defined constructors, but I think that won't improve performance at all; it should be simpler in general just -- cgit v1.1 From ed3de423f1694d30f9cccc0c024fb6e19e2c6323 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 25 Aug 2021 14:36:13 -0600 Subject: Avoid printing range table header alone. gcc/ChangeLog: * gimple-range-cache.cc (ssa_global_cache::dump): Avoid printing range table header alone. * gimple-range.cc (gimple_ranger::export_global_ranges): Same. --- gcc/gimple-range-cache.cc | 40 ++++++++++++++++++++++++++-------------- gcc/gimple-range.cc | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 50 insertions(+), 35 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 4138d05..facf981 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -628,20 +628,32 @@ ssa_global_cache::clear () void ssa_global_cache::dump (FILE *f) { - unsigned x; - int_range_max r; - fprintf (f, "Non-varying global ranges:\n"); - fprintf (f, "=========================:\n"); - for ( x = 1; x < num_ssa_names; x++) - if (gimple_range_ssa_p (ssa_name (x)) && - get_global_range (r, ssa_name (x)) && !r.varying_p ()) - { - print_generic_expr (f, ssa_name (x), TDF_NONE); - fprintf (f, " : "); - r.dump (f); - fprintf (f, "\n"); - } - fputc ('\n', f); + /* Cleared after the table header has been printed. */ + bool print_header = true; + for (unsigned x = 1; x < num_ssa_names; x++) + { + int_range_max r; + if (gimple_range_ssa_p (ssa_name (x)) && + get_global_range (r, ssa_name (x)) && !r.varying_p ()) + { + if (print_header) + { + /* Print the header only when there's something else + to print below. */ + fprintf (f, "Non-varying global ranges:\n"); + fprintf (f, "=========================:\n"); + print_header = false; + } + + print_generic_expr (f, ssa_name (x), TDF_NONE); + fprintf (f, " : "); + r.dump (f); + fprintf (f, "\n"); + } + } + + if (!print_header) + fputc ('\n', f); } // -------------------------------------------------------------------------- diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index ef3afea..d74cea3 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -259,16 +259,11 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name) void gimple_ranger::export_global_ranges () { - unsigned x; - int_range_max r; - if (dump_file) - { - fprintf (dump_file, "Exported global range table\n"); - fprintf (dump_file, "===========================\n"); - } - - for ( x = 1; x < num_ssa_names; x++) + /* Cleared after the table header has been printed. */ + bool print_header = true; + for (unsigned x = 1; x < num_ssa_names; x++) { + int_range_max r; tree name = ssa_name (x); if (name && !SSA_NAME_IN_FREE_LIST (name) && gimple_range_ssa_p (name) @@ -276,21 +271,29 @@ gimple_ranger::export_global_ranges () && !r.varying_p()) { bool updated = update_global_range (r, name); + if (!updated || !dump_file || !(dump_flags & TDF_DETAILS)) + continue; - if (updated && dump_file) + if (print_header) { - value_range vr = r; - print_generic_expr (dump_file, name , TDF_SLIM); - fprintf (dump_file, " --> "); - vr.dump (dump_file); + /* Print the header only when there's something else + to print below. */ + fprintf (dump_file, "Exported global range table:\n"); + fprintf (dump_file, "============================\n"); + print_header = false; + } + + value_range vr = r; + print_generic_expr (dump_file, name , TDF_SLIM); + fprintf (dump_file, " : "); + vr.dump (dump_file); + fprintf (dump_file, "\n"); + int_range_max same = vr; + if (same != r) + { + fprintf (dump_file, " irange : "); + r.dump (dump_file); fprintf (dump_file, "\n"); - int_range_max same = vr; - if (same != r) - { - fprintf (dump_file, " irange : "); - r.dump (dump_file); - fprintf (dump_file, "\n"); - } } } } -- cgit v1.1 From 971df602e0a798fe9c805c3105f4ac80d638a12b Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Mon, 9 Aug 2021 18:33:17 -0700 Subject: Fix PR c++/66590: incorrect warning "reaches end of non-void function" for switch So the problem here is there is code in the C++ front-end not to add a break statement (to the IR) if the previous block does not fall through. The problem is the code which does the check to see if the block may fallthrough does not check a CLEANUP_STMT; it assumes it is always fall through. Anyways this adds the code for the case of a CLEANUP_STMT that is only for !CLEANUP_EH_ONLY (the try/finally case). OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/cp/ChangeLog: PR c++/66590 * cp-objcp-common.c (cxx_block_may_fallthru): Handle CLEANUP_STMT for the case which will be try/finally. gcc/testsuite/ChangeLog: PR c++/66590 * g++.dg/warn/Wreturn-5.C: New test. --- gcc/cp/cp-objcp-common.c | 9 +++++++++ gcc/testsuite/g++.dg/warn/Wreturn-5.C | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/g++.dg/warn/Wreturn-5.C (limited to 'gcc') diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 98fd962..28f2d7b 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -317,6 +317,15 @@ cxx_block_may_fallthru (const_tree stmt) return true; return block_may_fallthru (ELSE_CLAUSE (stmt)); + case CLEANUP_STMT: + /* Just handle the try/finally cases. */ + if (!CLEANUP_EH_ONLY (stmt)) + { + return (block_may_fallthru (CLEANUP_BODY (stmt)) + && block_may_fallthru (CLEANUP_EXPR (stmt))); + } + return true; + default: return c_block_may_fallthru (stmt); } diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-5.C b/gcc/testsuite/g++.dg/warn/Wreturn-5.C new file mode 100644 index 0000000..543e33e --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wreturn-5.C @@ -0,0 +1,15 @@ +// PR C++/66590 +// { dg-do compile } +// { dg-options "-Wall" } + +struct A{ ~A();}; + +int f(int x) +{ + A a; + switch (x) + { + case 1: { A tmp; return 1; } break; + default: return 0; + } +} // { dg-bogus "control reaches end of non-void function" } -- cgit v1.1 From 4c5d76a655b9abdacaa992ab1167b33d35c3ffe9 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 25 Aug 2021 19:25:12 -0400 Subject: Fix tests that require IBM 128-bit long double This patch adds 3 more selections to target-supports.exp to see if we can specify to use a particular long double format (IEEE 128-bit, IBM extended double, 64-bit), and the library support will track the changes for the long double. This is needed because two of the tests in the test suite use long double, and they are actually testing IBM extended double. This patch also forces the two tests that explicitly require long double to use the IBM double-double encoding to explicitly run the test. This requires GLIBC 2.32 or greater in order to do the switch. I have run tests on a little endian power9 system with 3 compilers. There were no regressions with these patches, and the two tests in the following patches now work if the default long double is not IBM 128-bit: * One compiler used the default IBM 128-bit format; * One compiler used the IEEE 128-bit format; (and) * One compiler used 64-bit long doubles. I have also tested compilers on a big endian power8 system with a compiler defaulting to power8 code generation and another with the default cpu set. There were no regressions. 2021-08-25 Michael Meissner gcc/testsuite/ PR target/94630 * gcc.target/powerpc/pr70117.c: Specify that we need the long double type to be IBM 128-bit. Remove the code to use __ibm128. * c-c++-common/dfp/convert-bfp-11.c: Specify that we need the long double type to be IBM 128-bit. Run the test at -O2 optimization. * lib/target-supports.exp (add_options_for_long_double_ibm128): New function. (check_effective_target_long_double_ibm128): New function. (add_options_for_long_double_ieee128): New function. (check_effective_target_long_double_ieee128): New function. (add_options_for_long_double_64bit): New function. (check_effective_target_long_double_64bit): New function. --- gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c | 20 ++-- gcc/testsuite/gcc.target/powerpc/pr70117.c | 24 ++--- gcc/testsuite/lib/target-supports.exp | 128 ++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 24 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c b/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c index 95c433d..c09c834 100644 --- a/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c +++ b/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c @@ -1,9 +1,16 @@ -/* { dg-skip-if "" { ! "powerpc*-*-linux*" } } */ +/* { dg-require-effective-target dfp } */ -/* Test decimal float conversions to and from IBM 128-bit long double. - Checks are skipped at runtime if long double is not 128 bits. - Don't force 128-bit long doubles because runtime support depends - on glibc. */ +/* We need the long double type to be IBM 128-bit because the CONVERT_TO_PINF + tests will fail if we use IEEE 128-bit floating point. This is due to IEEE + 128-bit having a larger exponent range than IBM 128-bit extended double. So + tests that would generate an infinity with IBM 128-bit will generate a + normal number with IEEE 128-bit. */ + +/* { dg-require-effective-target long_double_ibm128 } */ +/* { dg-options "-O2" } */ +/* { dg-add-options long_double_ibm128 } */ + +/* Test decimal float conversions to and from IBM 128-bit long double. */ #include "convert.h" @@ -36,9 +43,6 @@ CONVERT_TO_PINF (312, tf, sd, 1.6e+308L, d32) int main () { - if (sizeof (long double) != 16) - return 0; - convert_101 (); convert_102 (); diff --git a/gcc/testsuite/gcc.target/powerpc/pr70117.c b/gcc/testsuite/gcc.target/powerpc/pr70117.c index 3bbd2c5..4a51f58 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr70117.c +++ b/gcc/testsuite/gcc.target/powerpc/pr70117.c @@ -1,26 +1,18 @@ -/* { dg-do run { target { powerpc*-*-linux* powerpc*-*-darwin* powerpc*-*-aix* rs6000-*-* } } } */ -/* { dg-options "-std=c99 -mlong-double-128 -O2" } */ +/* { dg-do run } */ +/* { dg-require-effective-target long_double_ibm128 } */ +/* { dg-options "-std=c99 -O2" } */ +/* { dg-add-options long_double_ibm128 } */ #include -#if defined(__LONG_DOUBLE_IEEE128__) -/* If long double is IEEE 128-bit, we need to use the __ibm128 type instead of - long double. We can't use __ibm128 on systems that don't support IEEE - 128-bit floating point, because the type is not enabled on those - systems. */ -#define LDOUBLE __ibm128 - -#elif defined(__LONG_DOUBLE_IBM128__) -#define LDOUBLE long double - -#else -#error "long double must be either IBM 128-bit or IEEE 128-bit" +#ifndef __LONG_DOUBLE_IBM128__ +#error "long double must be IBM 128-bit" #endif union gl_long_double_union { struct { double hi; double lo; } dd; - LDOUBLE ld; + long double ld; }; /* This is gnulib's LDBL_MAX which, being 107 bits in precision, is @@ -36,7 +28,7 @@ volatile double dnan = 0.0/0.0; int main (void) { - LDOUBLE ld; + long double ld; ld = gl_LDBL_MAX.ld; if (__builtin_isinf (ld)) diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 06f5b1e..350dbdb 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -2360,6 +2360,134 @@ proc check_effective_target_ppc_ieee128_ok { } { }] } +# Check if GCC and GLIBC supports explicitly specifying that the long double +# format uses the IBM 128-bit extended double format. Under little endian +# PowerPC Linux, you need GLIBC 2.32 or later to be able to use a different +# long double format for running a program than the system default. + +proc check_effective_target_long_double_ibm128 { } { + return [check_runtime_nocache long_double_ibm128 { + #include + #include + /* use volatile to prevent optimization. */ + volatile __ibm128 a = (__ibm128) 3.0; + volatile long double one = 1.0L; + volatile long double two = 2.0L; + volatile long double b; + char buffer[20]; + int main() + { + __ibm128 a2; + long double b2; + if (sizeof (long double) != 16) + return 1; + b = one + two; + /* eliminate removing volatile cast warning. */ + a2 = a; + b2 = b; + if (memcmp (&a2, &b2, 16) != 0) + return 1; + sprintf (buffer, "%lg", b); + return strcmp (buffer, "3") != 0; + } + } [add_options_for_long_double_ibm128 ""]] +} + +# Return the appropriate options to specify that long double uses the IBM +# 128-bit format on PowerPC. + +proc add_options_for_long_double_ibm128 { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mlong-double-128 -Wno-psabi -mabi=ibmlongdouble" + } + return "$flags" +} + +# Check if GCC and GLIBC supports explicitly specifying that the long double +# format uses the IEEE 128-bit format. Under little endian PowerPC Linux, you +# need GLIBC 2.32 or later to be able to use a different long double format for +# running a program than the system default. + +proc check_effective_target_long_double_ieee128 { } { + return [check_runtime_nocache long_double_ieee128 { + #include + #include + /* use volatile to prevent optimization. */ + volatile _Float128 a = 3.0f128; + volatile long double one = 1.0L; + volatile long double two = 2.0L; + volatile long double b; + char buffer[20]; + int main() + { + _Float128 a2; + long double b2; + if (sizeof (long double) != 16) + return 1; + b = one + two; + /* eliminate removing volatile cast warning. */ + a2 = a; + b2 = b; + if (memcmp (&a2, &b2, 16) != 0) + return 1; + sprintf (buffer, "%lg", b); + return strcmp (buffer, "3") != 0; + } + } [add_options_for_long_double_ieee128 ""]] +} + +# Return the appropriate options to specify that long double uses the IBM +# 128-bit format on PowerPC. +proc add_options_for_long_double_ieee128 { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mlong-double-128 -Wno-psabi -mabi=ieeelongdouble" + } + return "$flags" +} + +# Check if GCC and GLIBC supports explicitly specifying that the long double +# format uses the IEEE 64-bit. Under little endian PowerPC Linux, you need +# GLIBC 2.32 or later to be able to use a different long double format for +# running a program than the system default. + +proc check_effective_target_long_double_64bit { } { + return [check_runtime_nocache long_double_64bit { + #include + #include + /* use volatile to prevent optimization. */ + volatile double a = 3.0; + volatile long double one = 1.0L; + volatile long double two = 2.0L; + volatile long double b; + char buffer[20]; + int main() + { + double a2; + long double b2; + if (sizeof (long double) != 8) + return 1; + b = one + two; + /* eliminate removing volatile cast warning. */ + a2 = a; + b2 = b; + if (memcmp (&a2, &b2, 16) != 0) + return 1; + sprintf (buffer, "%lg", b); + return strcmp (buffer, "3") != 0; + } + } [add_options_for_ppc_long_double_override_64bit ""]] +} + +# Return the appropriate options to specify that long double uses the IEEE +# 64-bit format on PowerPC. + +proc add_options_for_long_double_64bit { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mlong-double-64" + } + return "$flags" +} + # Return 1 if the target supports executing VSX instructions, 0 # otherwise. Cache the result. -- cgit v1.1 From 4de346d8a2048b2a97547443893695a82ed16a58 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 25 Aug 2021 17:25:08 -0600 Subject: Add -details to dump option needed after r12-3144. gcc/testsuite: * gcc.dg/tree-ssa/evrp1.c: Add -details to dump option. * gcc.dg/tree-ssa/evrp2.c: Same. * gcc.dg/tree-ssa/evrp3.c: Same. * gcc.dg/tree-ssa/evrp4.c: Same. * gcc.dg/tree-ssa/evrp6.c: Same. * gcc.dg/tree-ssa/pr64130.c: Same. --- gcc/testsuite/gcc.dg/tree-ssa/evrp1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/evrp2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/evrp3.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/evrp4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/evrp6.c | 3 +-- gcc/testsuite/gcc.dg/tree-ssa/pr64130.c | 3 +-- 6 files changed, 6 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c index 8c6e4e6..f5f38c4 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details" } */ int foo (int i); int bar (int j) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c index e6d4235..fc92cdf 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details" } */ int foo (int i); int bar2 (int j) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c index 1a3bbd5..805652b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details" } */ int foo (int i); void bar (int j) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c index 6710e6b..e3f4531 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details" } */ int foo (int *p); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c index 35d4d74..aaeec68 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c @@ -1,6 +1,5 @@ - /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c index 28ffbb7..b694ec1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c @@ -1,6 +1,5 @@ - /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details" } */ __extension__ typedef __UINT32_TYPE__ uint32_t; -- cgit v1.1 From 85d77ac4745c6263520c8fe66c0dfced8404003f Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 26 Aug 2021 00:17:03 +0000 Subject: Daily bump. --- gcc/ChangeLog | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/analyzer/ChangeLog | 6 +++ gcc/c-family/ChangeLog | 7 +++ gcc/cp/ChangeLog | 12 +++++ gcc/d/ChangeLog | 7 +++ gcc/fortran/ChangeLog | 6 +++ gcc/testsuite/ChangeLog | 87 ++++++++++++++++++++++++++++++++++ 8 files changed, 247 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4dd226..fe8242b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,124 @@ +2021-08-25 Martin Sebor + + * gimple-range-cache.cc (ssa_global_cache::dump): Avoid printing + range table header alone. + * gimple-range.cc (gimple_ranger::export_global_ranges): Same. + +2021-08-25 Jan Hubicka + + * doc/invoke.texi: Document --param modref-max-adjustments. + * ipa-modref-tree.c (test_insert_search_collapse): Update. + (test_merge): Update. + * ipa-modref-tree.h (struct modref_access_node): Add adjustments; + (modref_access_node::operator==): Fix handling of access ranges. + (modref_access_node::contains): Constify parameter; handle also + mismatched parm offsets. + (modref_access_node::update): New function. + (modref_access_node::merge): New function. + (unspecified_modref_access_node): Update constructor. + (modref_ref_node::insert_access): Add record_adjustments parameter; + handle merging. + (modref_ref_node::try_merge_with): New private function. + (modref_tree::insert): New record_adjustments parameter. + (modref_tree::merge): New record_adjustments parameter. + (modref_tree::copy_from): Update. + * ipa-modref.c (dump_access): Dump adjustments field. + (get_access): Update constructor. + (record_access): Update call of insert. + (record_access_lto): Update call of insert. + (merge_call_side_effects): Add record_adjustments parameter. + (get_access_for_fnspec): Update. + (process_fnspec): Update. + (analyze_call): Update. + (analyze_function): Update. + (read_modref_records): Update. + (ipa_merge_modref_summary_after_inlining): Update. + (propagate_unknown_call): Update. + (modref_propagate_in_scc): Update. + * params.opt (param-max-modref-adjustments=): New. + +2021-08-25 Michael Meissner + + * config/rs6000/vsx.md (UNSPEC_XXSPLTIDP): Rename from + UNSPEC_XXSPLTID. + (xxspltiw_v4si): Use vecperm type attribute. + (xxspltiw_v4si_inst): Use vecperm type attribute. + (xxspltiw_v4sf_inst): Likewise. + (xxspltidp_v2df): Use vecperm type attribute. Use + UNSPEC_XXSPLTIDP instead of UNSPEC_XXSPLTID. + (xxspltidp_v2df_inst): Likewise. + (xxsplti32dx_v4si): Use vecperm type attribute. + (xxsplti32dx_v4si_inst): Likewise. + (xxsplti32dx_v4sf_inst): Likewise. + (xxblend_): Likewise. + (xxpermx): Likewise. + (xxpermx_inst): Likewise. + (xxeval): Likewise. + +2021-08-25 Lewis Hyatt + + PR other/93067 + * coretypes.h (typedef diagnostic_input_charset_callback): Declare. + * diagnostic.c (diagnostic_initialize_input_context): New function. + * diagnostic.h (diagnostic_initialize_input_context): Declare. + * input.c (default_charset_callback): New function. + (file_cache::initialize_input_context): New function. + (file_cache_slot::create): Added ability to convert the input + according to the input context. + (file_cache::file_cache): Initialize the new input context. + (class file_cache_slot): Added new m_alloc_offset member. + (file_cache_slot::file_cache_slot): Initialize the new member. + (file_cache_slot::~file_cache_slot): Handle potentially offset buffer. + (file_cache_slot::maybe_grow): Likewise. + (file_cache_slot::needs_read_p): Handle NULL fp, which is now possible. + (file_cache_slot::get_next_line): Likewise. + * input.h (class file_cache): Added input context member. + +2021-08-25 Richard Biener + + PR tree-optimization/102046 + * tree-vect-slp.c (vect_build_slp_tree_2): Conservatively + update ->any_pattern when swapping operands. + +2021-08-25 Hongyu Wang + + PR target/101716 + * config/i386/i386.c (ix86_live_on_entry): Adjust comment. + (ix86_decompose_address): Remove retval check for ASHIFT, + allow non-canonical zero extend if AND mask covers ASHIFT + count. + (ix86_legitimate_address_p): Adjust condition for decompose. + (ix86_rtx_costs): Adjust cost for lea with non-canonical + zero-extend. + Co-Authored by: Uros Bizjak + +2021-08-25 Jiufu Guo + + PR tree-optimization/101145 + * tree-ssa-loop-niter.c (number_of_iterations_until_wrap): + New function. + (number_of_iterations_lt): Invoke above function. + (adjust_cond_for_loop_until_wrap): + Merge to number_of_iterations_until_wrap. + (number_of_iterations_cond): Update invokes for + adjust_cond_for_loop_until_wrap and number_of_iterations_lt. + +2021-08-25 konglin1 + + PR target/101471 + * config/i386/avx512dqintrin.h (_mm512_fpclass_ps_mask): Fix + macro define in O0. + (_mm512_mask_fpclass_ps_mask): Ditto. + +2021-08-25 Kewen Lin + + * config/rs6000/altivec.md (vec_unpacku_hi_v16qi): Remove. + (vec_unpacku_hi_v8hi): Likewise. + (vec_unpacku_lo_v16qi): Likewise. + (vec_unpacku_lo_v8hi): Likewise. + (vec_unpacku_hi_): New define_expand. + (vec_unpacku_lo_): Likewise. + 2021-08-24 David Edelsohn * config/rs6000/aix.h (SYSTEM_IMPLICIT_EXTERN_C): Delete. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 83bcbc1..98be008 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210825 +20210826 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 211f34c..c7e8ba92 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,9 @@ +2021-08-25 Ankur Saini + + PR analyzer/101980 + * engine.cc (exploded_graph::maybe_create_dynamic_call): Don't create + calls if max recursion limit is reached. + 2021-08-23 David Malcolm * analyzer.h (struct rejected_constraint): Convert to... diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 873d7ab..5e3ac92 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2021-08-25 Lewis Hyatt + + PR other/93067 + * c-opts.c (c_common_input_charset_cb): New function. + (c_common_post_options): Call new function + diagnostic_initialize_input_context(). + 2021-08-20 Tobias Burnus * c-format.c (gcc_gfc_length_specs): Add 'll' and 'w'. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ddea2a2..0b92ee4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2021-08-25 Andrew Pinski + + PR c++/66590 + * cp-objcp-common.c (cxx_block_may_fallthru): Handle + CLEANUP_STMT for the case which will be try/finally. + +2021-08-25 Jakub Jelinek + + PR c++/102019 + * init.c (build_value_init_noctor): Ignore unnamed zero-width + bitfields. + 2021-08-23 Jakub Jelinek * parser.c (cp_parser_omp_clause_num_tasks, diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index 3bf2eec..db85ffc 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,10 @@ +2021-08-25 Lewis Hyatt + + PR other/93067 + * d-lang.cc (d_input_charset_callback): New function. + (d_init): Call new function + diagnostic_initialize_input_context(). + 2021-07-30 Iain Buclaw * expr.cc (binary_op): Remove dead code. diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 2866f5d..9679f35 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2021-08-25 Lewis Hyatt + + PR other/93067 + * cpp.c (gfc_cpp_post_options): Call new function + diagnostic_initialize_input_context(). + 2021-08-24 Harald Anlauf PR fortran/98411 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 84e6afb..251af30 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,90 @@ +2021-08-25 Martin Sebor + + * gcc.dg/tree-ssa/evrp1.c: Add -details to dump option. + * gcc.dg/tree-ssa/evrp2.c: Same. + * gcc.dg/tree-ssa/evrp3.c: Same. + * gcc.dg/tree-ssa/evrp4.c: Same. + * gcc.dg/tree-ssa/evrp6.c: Same. + * gcc.dg/tree-ssa/pr64130.c: Same. + +2021-08-25 Michael Meissner + + PR target/94630 + * gcc.target/powerpc/pr70117.c: Specify that we need the long double + type to be IBM 128-bit. Remove the code to use __ibm128. + * c-c++-common/dfp/convert-bfp-11.c: Specify that we need the long + double type to be IBM 128-bit. Run the test at -O2 optimization. + * lib/target-supports.exp (add_options_for_long_double_ibm128): New + function. + (check_effective_target_long_double_ibm128): New function. + (add_options_for_long_double_ieee128): New function. + (check_effective_target_long_double_ieee128): New function. + (add_options_for_long_double_64bit): New function. + (check_effective_target_long_double_64bit): New function. + +2021-08-25 Andrew Pinski + + PR c++/66590 + * g++.dg/warn/Wreturn-5.C: New test. + +2021-08-25 Jan Hubicka + + * gcc.dg/ipa/modref-1.c: Update testcase. + * gcc.dg/tree-ssa/modref-4.c: Update testcase. + * gcc.dg/tree-ssa/modref-8.c: New test. + +2021-08-25 Lewis Hyatt + + PR other/93067 + * gcc.dg/diagnostic-input-charset-1.c: New test. + * gcc.dg/diagnostic-input-utf8-bom.c: New test. + +2021-08-25 Richard Biener + + PR tree-optimization/102046 + * gcc.dg/vect/pr102046.c: New testcase. + +2021-08-25 Hongyu Wang + + PR target/101716 + * gcc.target/i386/pr101716.c: New test. + +2021-08-25 Jiufu Guo + + PR tree-optimization/101145 + * gcc.dg/vect/pr101145.c: New test. + * gcc.dg/vect/pr101145.inc: New test. + * gcc.dg/vect/pr101145_1.c: New test. + * gcc.dg/vect/pr101145_2.c: New test. + * gcc.dg/vect/pr101145_3.c: New test. + * gcc.dg/vect/pr101145inf.c: New test. + * gcc.dg/vect/pr101145inf.inc: New test. + * gcc.dg/vect/pr101145inf_1.c: New test. + +2021-08-25 konglin1 + + PR target/101471 + * gcc.target/i386/avx512f-pr101471.c: New test. + +2021-08-25 Kewen Lin + + * gcc.target/powerpc/unpack-vectorize-1.c: New test. + * gcc.target/powerpc/unpack-vectorize-1.h: New test. + * gcc.target/powerpc/unpack-vectorize-2.c: New test. + * gcc.target/powerpc/unpack-vectorize-2.h: New test. + * gcc.target/powerpc/unpack-vectorize-3.c: New test. + * gcc.target/powerpc/unpack-vectorize-3.h: New test. + * gcc.target/powerpc/unpack-vectorize-run-1.c: New test. + * gcc.target/powerpc/unpack-vectorize-run-2.c: New test. + * gcc.target/powerpc/unpack-vectorize-run-3.c: New test. + * gcc.target/powerpc/unpack-vectorize.h: New test. + +2021-08-25 liuhongt + + PR target/101989 + * gcc.target/i386/avx2-shiftqihi-constant-1.c: Add -mno-avx512f. + * gcc.target/i386/sse2-shiftqihi-constant-1.c: Add -mno-avx + 2021-08-24 Harald Anlauf PR fortran/98411 -- cgit v1.1 From d4b782985b4adb86ebcccff697366136321d45b2 Mon Sep 17 00:00:00 2001 From: Jonathan Yong <10walls@gmail.com> Date: Wed, 25 Aug 2021 16:36:14 +0000 Subject: extend.texi: add note about reserved ctor/dtor priorities gcc/Changelog: * doc/extend.texi: Add note about reserved priorities to the constructor attribute. Signed-off-by: Jonathan Yong <10walls@gmail.com> --- gcc/doc/extend.texi | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 49df8e6..251a103 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2787,16 +2787,16 @@ On some targets the attributes also accept an integer argument to specify a priority to control the order in which constructor and destructor functions are run. A constructor with a smaller priority number runs before a constructor with a larger -priority number; the opposite relationship holds for destructors. So, -if you have a constructor that allocates a resource and a destructor -that deallocates the same resource, both functions typically have the -same priority. The priorities for constructor and destructor -functions are the same as those specified for namespace-scope C++ -objects (@pxref{C++ Attributes}). However, at present, the order in which -constructors for C++ objects with static storage duration and functions -decorated with attribute @code{constructor} are invoked is unspecified. -In mixed declarations, attribute @code{init_priority} can be used to -impose a specific ordering. +priority number; the opposite relationship holds for destructors. Note +that priorities 0-100 are reserved. So, if you have a constructor that +allocates a resource and a destructor that deallocates the same +resource, both functions typically have the same priority. The +priorities for constructor and destructor functions are the same as +those specified for namespace-scope C++ objects (@pxref{C++ Attributes}). +However, at present, the order in which constructors for C++ objects +with static storage duration and functions decorated with attribute +@code{constructor} are invoked is unspecified. In mixed declarations, +attribute @code{init_priority} can be used to impose a specific ordering. Using the argument forms of the @code{constructor} and @code{destructor} attributes on targets where the feature is not supported is rejected with -- cgit v1.1 From bfc9250e0de5d5de8a93785ec20e04466ad720f6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 20 Aug 2021 16:35:18 +0200 Subject: Use non-numbered clones for target_clones. gcc/ChangeLog: * cgraph.h (create_version_clone_with_body): Add new parameter. * cgraphclones.c: Likewise. * multiple_target.c (create_dispatcher_calls): Do not use numbered suffixes. (create_target_clone): Likewise here. gcc/testsuite/ChangeLog: * gcc.target/i386/mvc5.c: Scan assembly names. * gcc.target/i386/mvc7.c: Likewise. * gcc.target/i386/pr95778-1.c: Update scanned patterns. * gcc.target/i386/pr95778-2.c: Likewise. Co-Authored-By: Stefan Kneifel --- gcc/cgraph.h | 5 ++++- gcc/cgraphclones.c | 11 ++++++++--- gcc/multiple_target.c | 16 +++++++--------- gcc/testsuite/gcc.target/i386/mvc5.c | 4 ++++ gcc/testsuite/gcc.target/i386/mvc7.c | 8 ++++++-- gcc/testsuite/gcc.target/i386/pr95778-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/pr95778-2.c | 4 ++-- 7 files changed, 33 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/cgraph.h b/gcc/cgraph.h index d54a258..4cdb373 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1006,13 +1006,16 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET of the declaration. + If VERSION_DECL is set true, use clone_function_name_numbered for the + function clone. Otherwise, use clone_function_name. + Return the new version's cgraph node. */ cgraph_node *create_version_clone_with_body (vec redirect_callers, vec *tree_map, ipa_param_adjustments *param_adjustments, bitmap bbs_to_copy, basic_block new_entry_block, const char *clone_name, - tree target_attributes = NULL_TREE); + tree target_attributes = NULL_TREE, bool version_decl = true); /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab corresponding to cgraph_node. */ diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index b16e681..ae91dcc 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -987,6 +987,9 @@ cgraph_node::create_version_clone (tree new_decl, that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET of the declaration. + If VERSION_DECL is set true, use clone_function_name_numbered for the + function clone. Otherwise, use clone_function_name. + Return the new version's cgraph node. */ cgraph_node * @@ -995,7 +998,7 @@ cgraph_node::create_version_clone_with_body vec *tree_map, ipa_param_adjustments *param_adjustments, bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix, - tree target_attributes) + tree target_attributes, bool version_decl) { tree old_decl = decl; cgraph_node *new_version_node = NULL; @@ -1016,8 +1019,10 @@ cgraph_node::create_version_clone_with_body new_decl = copy_node (old_decl); /* Generate a new name for the new version. */ - DECL_NAME (new_decl) = clone_function_name_numbered (old_decl, suffix); - SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); + tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix) + : clone_function_name (old_decl, suffix)); + DECL_NAME (new_decl) = fnname; + SET_DECL_ASSEMBLER_NAME (new_decl, fnname); SET_DECL_RTL (new_decl, NULL); DECL_VIRTUAL_P (new_decl) = 0; diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c index 6c05658..28d5f95 100644 --- a/gcc/multiple_target.c +++ b/gcc/multiple_target.c @@ -166,9 +166,8 @@ create_dispatcher_calls (struct cgraph_node *node) } } - symtab->change_decl_assembler_name (node->decl, - clone_function_name_numbered ( - node->decl, "default")); + tree fname = clone_function_name (node->decl, "default"); + symtab->change_decl_assembler_name (node->decl, fname); if (node->definition) { @@ -309,9 +308,9 @@ create_target_clone (cgraph_node *node, bool definition, char *name, if (definition) { - new_node = node->create_version_clone_with_body (vNULL, NULL, - NULL, NULL, - NULL, name, attributes); + new_node + = node->create_version_clone_with_body (vNULL, NULL, NULL, NULL, NULL, + name, attributes, false); if (new_node == NULL) return NULL; new_node->force_output = true; @@ -322,9 +321,8 @@ create_target_clone (cgraph_node *node, bool definition, char *name, new_node = cgraph_node::get_create (new_decl); DECL_ATTRIBUTES (new_decl) = attributes; /* Generate a new name for the new version. */ - symtab->change_decl_assembler_name (new_node->decl, - clone_function_name_numbered ( - node->decl, name)); + tree fname = clone_function_name (node->decl, name); + symtab->change_decl_assembler_name (new_node->decl, fname); } return new_node; } diff --git a/gcc/testsuite/gcc.target/i386/mvc5.c b/gcc/testsuite/gcc.target/i386/mvc5.c index 677f79f..0e02bf6 100644 --- a/gcc/testsuite/gcc.target/i386/mvc5.c +++ b/gcc/testsuite/gcc.target/i386/mvc5.c @@ -3,6 +3,10 @@ /* { dg-options "-fno-inline" } */ /* { dg-final { scan-assembler "foo,foo.resolver" } } */ +/* Verify that foo clones are not numbered. */ +/* { dg-final { scan-assembler "foo.default:" } } */ +/* { dg-final { scan-assembler "foo.avx:" } } */ + __attribute__((target_clones("default","avx","avx2"))) int foo () diff --git a/gcc/testsuite/gcc.target/i386/mvc7.c b/gcc/testsuite/gcc.target/i386/mvc7.c index a3697ba..7fb9dde 100644 --- a/gcc/testsuite/gcc.target/i386/mvc7.c +++ b/gcc/testsuite/gcc.target/i386/mvc7.c @@ -1,7 +1,11 @@ /* { dg-do compile } */ /* { dg-require-ifunc "" } */ -/* { dg-final { scan-assembler "foo.resolver" } } */ -/* { dg-final { scan-assembler "avx" } } */ + +/* Verify that foo clones are not numbered. */ +/* { dg-final { scan-assembler "foo.resolver," } } */ +/* { dg-final { scan-assembler "foo.default," } } */ +/* { dg-final { scan-assembler "foo.avx," } } */ + /* { dg-final { scan-assembler "slm" } } */ /* { dg-final { scan-assembler "foo,foo.resolver" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr95778-1.c b/gcc/testsuite/gcc.target/i386/pr95778-1.c index 3238303..18f8383 100644 --- a/gcc/testsuite/gcc.target/i386/pr95778-1.c +++ b/gcc/testsuite/gcc.target/i386/pr95778-1.c @@ -17,5 +17,5 @@ g2(int *p) return f2(p); } -/* { dg-final { scan-assembler "g2.default.1:\n\tjmp\tf2.default.1\n" } } */ -/* { dg-final { scan-assembler "g2.avx2.0:\n\tjmp\tf2.avx2.0\n" } } */ +/* { dg-final { scan-assembler "g2.default:\n\tjmp\tf2.default\n" } } */ +/* { dg-final { scan-assembler "g2.avx2:\n\tjmp\tf2.avx2\n" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr95778-2.c b/gcc/testsuite/gcc.target/i386/pr95778-2.c index e88702d..9ef513a 100644 --- a/gcc/testsuite/gcc.target/i386/pr95778-2.c +++ b/gcc/testsuite/gcc.target/i386/pr95778-2.c @@ -17,5 +17,5 @@ g2(int *p) return f2(p); } -/* { dg-final { scan-assembler "g2.default.1:\n\tjmp\tf2.default.1\n" } } */ -/* { dg-final { scan-assembler "g2.avx2.0:\n\tjmp\tf2.avx2.0\n" } } */ +/* { dg-final { scan-assembler "g2.default:\n\tjmp\tf2.default\n" } } */ +/* { dg-final { scan-assembler "g2.avx2:\n\tjmp\tf2.avx2\n" } } */ -- cgit v1.1