From 57e274408c237c08d2f78722e3767651ef931170 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 18 Mar 2021 09:53:24 +0100 Subject: testsuite: Fix up pr98099.c testcase for big endian [PR98099] The testcase fails on big-endian without int128 support, because due to -fsso-struct=big-endian no swapping is needed for big endian. This patch restricts the testcase to big or little endian (but not pdp) and uses -fsso-struct=little-endian for big endian, so that it is swapping everywhere. 2021-03-18 Jakub Jelinek PR middle-end/98099 * gcc.dg/pr98099.c: Don't compile the test on pdp endian. For big endian use -fsso-struct=little-endian dg-options. --- gcc/testsuite/gcc.dg/pr98099.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr98099.c b/gcc/testsuite/gcc.dg/pr98099.c index 12e52f2..c78d43e 100644 --- a/gcc/testsuite/gcc.dg/pr98099.c +++ b/gcc/testsuite/gcc.dg/pr98099.c @@ -1,8 +1,9 @@ /* PR middle-end/98099 */ /* Reported by G. Steinmetz */ -/* { dg-do compile { target dfp } } */ -/* { dg-options "-fsso-struct=big-endian" } */ +/* { dg-do compile { target { dfp && { be || le } } } } */ +/* { dg-options "-fsso-struct=big-endian" { target le } } */ +/* { dg-options "-fsso-struct=little-endian" { target be } } */ struct S { _Decimal128 a; }; -- cgit v1.1 From fff9faa79043aa53d361e7f6e31b2680007a97e2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 18 Mar 2021 16:11:46 +0100 Subject: testsuite: Fix up strlenopt-73.c on powerpc [PR99626] As mentioned in the testcase as well as in the PR, this testcase relies on MOVE_MAX being sufficiently large that the memcpy call is folded early into load + store. Some popular targets define MOVE_MAX to 8 or even 16 (e.g. x86_64 or some options on s390x), but many other targets define it to just 4 (e.g. powerpc 32-bit), or even 2. The testcase has already one test routine guarded on one particular target with MOVE_MAX 16 (but does it incorrectly, __i386__ is only defined on 32-bit x86 and __SIZEOF_INT128__ is only defined on 64-bit targets), this patch fixes that, and guards another test that relies on memcpy (, , 8) being folded that way (which therefore needs MOVE_MAX >= 8) on a couple of common targets that are known to have such MOVE_MAX. 2021-03-18 Jakub Jelinek PR testsuite/99626 * gcc.dg/strlenopt-73.c: Ifdef out test_copy_cond_unequal_length_i64 on targets other than x86, aarch64, s390 and 64-bit powerpc. Use test_copy_cond_unequal_length_i128 for __x86_64__ with int128 support rather than __i386__. --- gcc/testsuite/gcc.dg/strlenopt-73.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/strlenopt-73.c b/gcc/testsuite/gcc.dg/strlenopt-73.c index 6523949..170b66a 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-73.c +++ b/gcc/testsuite/gcc.dg/strlenopt-73.c @@ -69,6 +69,13 @@ void test_copy_cond_equal_length (void) T ( 0 ==, 33, 1, (i0 ? a32 : b32) + 32); } +#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) \ + || defined(__s390__) || defined(__powerpc64__) + +/* The following tests assume GCC transforms the memcpy calls into + long long assignments which it does only on targets that define + the MOVE_MAX macro to 8 or higher. Enable on a set of targets + known to do that. */ const char a4[16] = "0123"; const char b4[16] = "3210"; @@ -84,12 +91,14 @@ void test_copy_cond_unequal_length_i64 (void) T (0 <, 16, 8, i0 ? a4 + 2 : b4 + 3); } +#endif + -#if __i386__ && __SIZEOF_INT128__ == 16 +#if defined(__x86_64__) && __SIZEOF_INT128__ == 16 /* The following tests assume GCC transforms the memcpy calls into int128_t assignments which it does only on targets that define - the MOVE_MAX macro to 16. That's only s390 and i386 with + the MOVE_MAX macro to 16. That's only s390 and x86_64 with int128_t support. */ const char a8[32] = "01234567"; -- cgit v1.1 From 89d44a9f3b9ab97634b7ef894e2c83ebd83582a8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 18 Mar 2021 16:14:47 +0100 Subject: testsuite: Fix up strlenopt-80.c on powerpc [PR99636] Similar issue as in strlenopt-73.c, various spots in this test rely on MOVE_MAX >= 8, this time it uses a target selector to pick up a couple of targets, and all of them but powerpc 32-bit satisfy it, but powerpc 32-bit have MOVE_MAX just 4. 2021-03-18 Jakub Jelinek PR testsuite/99636 * gcc.dg/strlenopt-80.c: For powerpc*-*-*, only enable for lp64. --- gcc/testsuite/gcc.dg/strlenopt-80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/strlenopt-80.c b/gcc/testsuite/gcc.dg/strlenopt-80.c index 9124fe4..a853402 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-80.c +++ b/gcc/testsuite/gcc.dg/strlenopt-80.c @@ -3,7 +3,7 @@ The optimization is only implemented for MEM_REF stores and other targets than those below may not transform the memcpy call into such a store. - { dg-do compile { target aarch64*-*-* i?86-*-* powerpc*-*-* x86_64-*-* } } + { dg-do compile { target { { aarch64*-*-* i?86-*-* x86_64-*-* } || { { powerpc*-*-* } && lp64 } } } } { dg-options "-O2 -Wall -fdump-tree-optimized" } */ -- cgit v1.1 From 5e2eabe1eed1e53d39923517122d3c7de2013ad4 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 18 Mar 2021 11:47:46 -0700 Subject: x86: Issue error for return/argument only with function body If we never generate function body, we shouldn't issue errors for return nor argument. Add silent_p to i386 machine_function to avoid issuing errors for return and argument without function body. gcc/ PR target/99652 * config/i386/i386-options.c (ix86_init_machine_status): Set silent_p to true. * config/i386/i386.c (init_cumulative_args): Set silent_p to false. (construct_container): Return early for return and argument errors if silent_p is true. * config/i386/i386.h (machine_function): Add silent_p. gcc/testsuite/ PR target/99652 * gcc.dg/torture/pr99652-1.c: New test. * gcc.dg/torture/pr99652-2.c: Likewise. * gcc.target/i386/pr57655.c: Adjusted. * gcc.target/i386/pr59794-6.c: Likewise. * gcc.target/i386/pr70738-1.c: Likewise. * gcc.target/i386/pr96744-1.c: Likewise. --- gcc/testsuite/gcc.dg/torture/pr99652-1.c | 8 ++++++++ gcc/testsuite/gcc.dg/torture/pr99652-2.c | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr99652-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr99652-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr99652-1.c b/gcc/testsuite/gcc.dg/torture/pr99652-1.c new file mode 100644 index 0000000..c2395ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99652-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-mgeneral-regs-only" } */ + +inline double +foo (void) +{ + return 1.0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr99652-2.c b/gcc/testsuite/gcc.dg/torture/pr99652-2.c new file mode 100644 index 0000000..beefad8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99652-2.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-mno-80387" } */ + +inline double +foo (void) +{ + return 1.0; +} -- cgit v1.1 From 3279a9a5a9a2e4e17175678cb7b15613495e306e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 19 Mar 2021 22:54:31 +0100 Subject: c: Fix up -Wunused-but-set-* warnings for _Atomics [PR99588] As the following testcases show, compared to -D_Atomic= case we have many -Wunused-but-set-* warning false positives. When an _Atomic variable/parameter is read, we call mark_exp_read on it in convert_lvalue_to_rvalue, but build_atomic_assign does not. For consistency with the non-_Atomic case where we mark_exp_read the lhs for lhs op= ... but not for lhs = ..., this patch does that too. But furthermore we need to pattern match the trees emitted by _Atomic store, so that _Atomic store itself is not marked as being a variable read, but when the result of the store is used, we mark it. 2021-03-19 Jakub Jelinek PR c/99588 * c-typeck.c (mark_exp_read): Recognize what build_atomic_assign with modifycode NOP_EXPR produces and mark the _Atomic var as read if found. (build_atomic_assign): For modifycode of NOP_EXPR, use COMPOUND_EXPRs rather than STATEMENT_LIST. Otherwise call mark_exp_read on lhs. Set TREE_SIDE_EFFECTS on the TARGET_EXPR. * gcc.dg/Wunused-var-5.c: New test. * gcc.dg/Wunused-var-6.c: New test. --- gcc/testsuite/gcc.dg/Wunused-var-5.c | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/Wunused-var-6.c | 14 ++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wunused-var-5.c create mode 100644 gcc/testsuite/gcc.dg/Wunused-var-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wunused-var-5.c b/gcc/testsuite/gcc.dg/Wunused-var-5.c new file mode 100644 index 0000000..cc5bbf5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wunused-var-5.c @@ -0,0 +1,23 @@ +/* PR c/99588 */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -Wunused-but-set-variable" } */ + +void bar (int, ...); +void f1 (void) { static _Atomic int x = 0; bar (0, x); } +void f2 (void) { static _Atomic int x = 0; bar (0, x += 1); } +void f3 (void) { static _Atomic int x = 0; bar (x); } +void f4 (void) { static _Atomic int x = 0; bar (x += 1); } +void f5 (void) { static _Atomic int x = 0; bar (x = 1); } +void f6 (void) { static _Atomic int x = 0; x = 1; } /* { dg-warning "variable 'x' set but not used" } */ +void f7 (void) { static _Atomic int x = 0; x += 3; } +void f8 (void) { _Atomic int x = 0; bar (0, x); } +void f9 (void) { _Atomic int x = 0; bar (0, x += 1); } +void f10 (void) { _Atomic int x = 0; bar (x); } +void f11 (void) { _Atomic int x = 0; bar (x += 1); } +void f12 (void) { _Atomic int x = 0; bar (x = 1); } +void f13 (void) { _Atomic int x = 0; x = 1; } /* { dg-warning "variable 'x' set but not used" } */ +void f14 (void) { _Atomic int x = 0; x += 3; } +void f15 (void) { _Atomic int x = 0; int y = 3; x += y; } +void f16 (void) { _Atomic int x = 0; int y = 3; bar (x += y); } +void f17 (void) { _Atomic int x = 0; int y = 3; x = y; } /* { dg-warning "variable 'x' set but not used" } */ +void f18 (void) { _Atomic int x = 0; int y = 3; bar (x = y); } diff --git a/gcc/testsuite/gcc.dg/Wunused-var-6.c b/gcc/testsuite/gcc.dg/Wunused-var-6.c new file mode 100644 index 0000000..f48a455 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wunused-var-6.c @@ -0,0 +1,14 @@ +/* PR c/99588 */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -Wunused-but-set-variable" } */ + +void bar (int, ...); +struct S { int a, b, c; }; +typedef _Atomic struct S T; + +void +foo (void) +{ + static T x = (struct S) { 0, 0, 0 }; /* { dg-bogus "set but not used" } */ + bar (0, x = (struct S) { 1, 1, 1 }); +} -- cgit v1.1 From 9f59cb7cac009f3c6eba81eb09714699b9ac9f8d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 20 Mar 2021 17:02:06 +0100 Subject: c-family: Fix PR94272 -fcompare-debug issue even for C [PR99230] The following testcase results in -fcompare-debug failure. The problem is the similar like in PR94272 https://gcc.gnu.org/pipermail/gcc-patches/2020-March/542562.html When genericizing, with -g0 we have just a TREE_SIDE_EFFECTS DO_STMT in a branch of if, while with -g we have that wrapped into TREE_SIDE_EFFECTS STATEMENT_LIST containing DEBUG_BEGIN_STMT and that DO_STMT. The do loop is empty with 0 condition, so c_genericize_control_stmt turns it into an empty statement (without TREE_SIDE_EFFECTS). For -g0 that means that suddenly the if branch doesn't have side effects and is expanded differently. But with -g we still have TREE_SIDE_EFFECTS STATEMENT_LIST containing DEBUG_BEGIN_STMT and non-TREE_SIDE_EFFECTS stmt. The following patch fixes that by detecting this case and removing TREE_SIDE_EFFECTS. And, so that we don't duplicate the same code, changes the C++ FE to just call the c_genericize_control_stmt function that can now handle it. 2021-03-20 Jakub Jelinek PR debug/99230 * c-gimplify.c (c_genericize_control_stmt): Handle STATEMENT_LIST. * cp-gimplify.c (cp_genericize_r) : Remove special code, instead call c_genericize_control_stmt. * gcc.dg/pr99230.c: New test. --- gcc/testsuite/gcc.dg/pr99230.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr99230.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr99230.c b/gcc/testsuite/gcc.dg/pr99230.c new file mode 100644 index 0000000..eb3f982 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99230.c @@ -0,0 +1,40 @@ +/* PR debug/99230 */ +/* { dg-do compile } */ +/* { dg-options "-O2 --param logical-op-non-short-circuit=0 -fcompare-debug --param=jump-table-max-growth-ratio-for-speed=5000" } */ + +extern void fn2 (void); +extern void fn3 (int); +int a, b; +void +fn1 (void) +{ + int c; + short d; + switch (a) { + case 22000: + fn2 (); + case 22300: + b = 0; + case 22600: + case 22601: + case 22900: + fn3 (1); + case 20100: + fn3 (2); + case 20200: + fn3 (3); + case 20300: + fn3 (4); + case 20400: + fn3 (5); + case 20310: + fn3 (4); + case 20410: + fn3 (5); + } + if (d || c) { + do + ; + while (0); + } +} -- cgit v1.1 From b931e4792b8696f3da69f70988720c4d1ec6142a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 22 Mar 2021 11:09:46 +0100 Subject: tree-optimization/99694 - fix value-numbering PHIs This avoids endless cycling when a PHI node with unchanged backedge value (the PHI result appearing there) is subject to CSE since doing that effectively alters the hash entry. The way to avoid this is to ignore such edges when processing the PHI node. 2021-03-22 Richard Biener PR tree-optimization/99694 * tree-ssa-sccvn.c (visit_phi): Ignore edges with the PHI result. * gcc.dg/torture/pr99694.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr99694.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr99694.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr99694.c b/gcc/testsuite/gcc.dg/torture/pr99694.c new file mode 100644 index 0000000..df31696 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99694.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-w" } */ + +#include + +int a, b, c; +void d() { + uint16_t e; + int32_t *f; + int32_t *g; + if (a) { + int32_t *k; + for (;; *k += 1) { + int32_t **i = &f; + int32_t **l = &g; + for (e = 6; e; e++) { + g = k = f; + j: + **l = 0; + } + *i = c; + } + } + uint16_t i = &e; + b = i / 0; + goto j; +} -- cgit v1.1 From 88081d38bd82562b6e2d6a4a275e7f6f2aac3422 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 18 Mar 2021 16:05:27 +0100 Subject: Handle setting of 1-bit anti-ranges uniformly. PR tree-optimization/99296 * value-range.cc (irange::irange_set_1bit_anti_range): New. (irange::irange_set_anti_range): Call irange_set_1bit_anti_range * value-range.h (irange::irange_set_1bit_anti_range): New. --- gcc/testsuite/gcc.dg/pr99296.c | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr99296.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr99296.c b/gcc/testsuite/gcc.dg/pr99296.c new file mode 100644 index 0000000..4a0b3f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99296.c @@ -0,0 +1,7 @@ +// { dg-do compile } +// { dg-options "-O2 -fno-tree-bit-ccp" } + +struct { + signed a : 1; +} b, c; +void d() { b.a |= c.a |= 0 != 2; } -- cgit v1.1 From d7cea7ceff9a2be7436108030c598628c51fba0f Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 23 Mar 2021 14:02:03 +0000 Subject: aarch64: Make aarch64_add_offset work with -ftrapv [PR99540] aarch64_add_offset uses expand_mult to multiply the SVE VL by an out-of-range constant. expand_mult takes an argument to indicate whether the multiplication is signed or unsigned, but in this context the multiplication is effectively signless and so the choice seemed arbitrary. However, one of the things that the signedness input does is indicate whether signed overflow should be trapped for -ftrapv. We don't want that here, so we must treat the multiplication as unsigned. gcc/ 2021-03-23 Jakub Jelinek PR target/99540 * config/aarch64/aarch64.c (aarch64_add_offset): Tell expand_mult to perform an unsigned rather than a signed multiplication. gcc/testsuite/ 2021-03-23 Richard Sandiford PR target/99540 * gcc.dg/vect/pr99540.c: New test. --- gcc/testsuite/gcc.dg/vect/pr99540.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr99540.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr99540.c b/gcc/testsuite/gcc.dg/vect/pr99540.c new file mode 100644 index 0000000..9136b09 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr99540.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftrapv -ffloat-store -march=armv8.2-a+sve" { target aarch64*-*-* } } */ + +float *MSalign2m2m_rec_initverticalw, *MSalign2m2m_rec_currentw; + +void +match_ribosum (int MSalign2m2m_rec_i, int MSalign2m2m_rec_lgth1, + int MSalign2m2m_rec_lgth2) +{ + float **WMMTX; + + while (MSalign2m2m_rec_i < 1) + WMMTX[MSalign2m2m_rec_i++][0] = MSalign2m2m_rec_initverticalw[0]; + + while (MSalign2m2m_rec_i < MSalign2m2m_rec_lgth1) + MSalign2m2m_rec_initverticalw[MSalign2m2m_rec_i++] += 0.1; + + while (MSalign2m2m_rec_i < MSalign2m2m_rec_lgth2) + MSalign2m2m_rec_currentw[MSalign2m2m_rec_i++] += 0.1; +} -- cgit v1.1 From f225c6b0c50dc472e0b73b440b572a3bf1514020 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Wed, 24 Mar 2021 20:27:27 +0100 Subject: ipa: Check that scalar types that IPA-CP comes up with are sane (PR99122) This patch fixes the last bit of PR 99122 where various bits of IPA infrastructure are presented with a program with type mismatches that make it have undefined behavior, and when inlining or performing IPA-CP, and encountering such mismatch, we basically try to VIEW_CONVERT_EXPR whatever the caller has into whatever the callee has or simply use an empty constructor if that cannot be done. This however does not work when the callee has VLA parameters because we ICE in the process. Richi has already disabled inlining for such cases, this patch avoids the issue in IPA-CP. It adds checks that whatever constant the propagation arrived at is actually compatible or fold_convertible to the callees formal parameer type. Unlike in the past, we now have types of all parameters of functions that we have analyzed, even with LTO, and so can do it. This should prevent only bogus propagations. I have looked at the effect of the patch on WPA of Firefox and did not have any. I have bootstrapped and LTO bootstrapped and tested the patch on x86_64-linux. OK for trunk? And perhaps later for GCC 10 too? Thanks gcc/ChangeLog: 2021-02-26 Martin Jambor PR ipa/99122 * ipa-cp.c (initialize_node_lattices): Mark as bottom all parameters with unknown type. (ipacp_value_safe_for_type): New function. (propagate_vals_across_arith_jfunc): Verify that the constant type can be used for a type of the formal parameter. (propagate_vals_across_ancestor): Likewise. (propagate_scalar_across_jump_function): Likewise. Pass the type also to propagate_vals_across_ancestor. gcc/testsuite/ChangeLog: 2021-02-26 Martin Jambor PR ipa/99122 * gcc.dg/pr99122-3.c: Remove -fno-ipa-cp from options. --- gcc/testsuite/gcc.dg/pr99122-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr99122-3.c b/gcc/testsuite/gcc.dg/pr99122-3.c index 6aa5b29..6a908ad 100644 --- a/gcc/testsuite/gcc.dg/pr99122-3.c +++ b/gcc/testsuite/gcc.dg/pr99122-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -g -fno-ipa-cp -w" } */ +/* { dg-options "-O2 -g -w" } */ static int foo (); -- cgit v1.1 From 71fc4655ab86ab66b40165b2cb49c1395ca82a9a Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 24 Mar 2021 20:47:57 -0400 Subject: analyzer; reset sm-state for SSA names at def-stmts [PR93695,PR99044,PR99716] Various false positives from -fanalyzer involve SSA names in loops, where sm-state associated with an SSA name from one iteration is erroneously reused in a subsequent iteration. For example, PR analyzer/99716 describes a false "double 'fclose' of FILE 'fp'" on: for (i = 0; i < 2; ++i) { FILE *fp = fopen ("/tmp/test", "w"); fprintf (fp, "hello"); fclose (fp); } where the gimple of the loop body is: fp_7 = fopen ("/tmp/test", "w"); __builtin_fwrite ("hello", 1, 5, fp_7); fclose (fp_7); i_10 = i_1 + 1; where fp_7 transitions to "closed" at the fclose, but is not reset at the subsequent fopen, leading to the false positive when the fclose is re-reached. The fix is to reset sm-state for svalues that involve an SSA name at the SSA name's def-stmt, since the def-stmt effectively changes the meaning of those related svalues. gcc/analyzer/ChangeLog: PR analyzer/93695 PR analyzer/99044 PR analyzer/99716 * engine.cc (exploded_node::on_stmt): Clear sm-state involving an SSA name at the def-stmt of that SSA name. * program-state.cc (sm_state_map::purge_state_involving): New. * program-state.h (sm_state_map::purge_state_involving): New decl. * region-model.cc (selftest::test_involves_p): New. (selftest::analyzer_region_model_cc_tests): Call it. * svalue.cc (class involvement_visitor): New class (svalue::involves_p): New. * svalue.h (svalue::involves_p): New decl. gcc/testsuite/ChangeLog: PR analyzer/93695 PR analyzer/99044 PR analyzer/99716 * gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c: Remove xfail. * gcc.dg/analyzer/pr93695-1.c: New test. * gcc.dg/analyzer/pr99044-1.c: New test. * gcc.dg/analyzer/pr99044-2.c: New test. * gcc.dg/analyzer/pr99716-1.c: New test. * gcc.dg/analyzer/pr99716-2.c: New test. * gcc.dg/analyzer/pr99716-3.c: New test. --- .../analyzer/attr-malloc-CVE-2019-19078-usb-leak.c | 4 +- gcc/testsuite/gcc.dg/analyzer/pr93695-1.c | 53 +++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99044-1.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99044-2.c | 42 +++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99716-1.c | 40 +++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99716-2.c | 34 ++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99716-3.c | 16 ++++++ 7 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr93695-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99044-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99044-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99716-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99716-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99716-3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c index 905d50e..e086843 100644 --- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c +++ b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c @@ -192,9 +192,7 @@ static int ath10k_usb_hif_tx_sg(struct ath10k *ar, u8 pipe_id, goto err_free_urb_to_pipe; } - /* TODO: the loop confuses the double-free checker (another - instance of PR analyzer/93695). */ - usb_free_urb(urb); /* { dg-bogus "double-'usb_free_urb' of 'urb'" "" { xfail *-*-* } } */ + usb_free_urb(urb); /* { dg-bogus "double-'usb_free_urb' of 'urb'" } */ } return 0; diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c b/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c new file mode 100644 index 0000000..e0500c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c @@ -0,0 +1,53 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ +/* TODO: remove the need for this option (PR analyzer/93695). */ + +#define NELEMS 10 +#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0])) + +void +test_1 (void) +{ + int *p[NELEMS]; + int i; + + for (i = 0; i < ARRAY_SIZE (p); ++i) + p[i] = __builtin_malloc (sizeof (i)); + + for (i = 0; i < ARRAY_SIZE (p); ++i) + __builtin_free (p [i]); +} + +void +test_2 (int n) +{ + int **p; + int i; + + p = (int **)__builtin_malloc (sizeof (int *) * n); + if (!p) + return; + + for (i = 0; i < n; ++i) + p[i] = __builtin_malloc (sizeof (i)); + + for (i = 0; i < n; ++i) + __builtin_free (p [i]); + + __builtin_free (p); +} + +void +test_3 (int **p, int n) +{ + int i; + for (i = 0; i < n; ++i) + p[i] = __builtin_malloc (sizeof (i)); +} + +void +test_4 (void **p, int n) +{ + int i; + for (i = 0; i < n; ++i) + __builtin_free (p[i]); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99044-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99044-1.c new file mode 100644 index 0000000..6b5d901 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99044-1.c @@ -0,0 +1,60 @@ +#include + +struct hashmap_entry { + struct hashmap_entry *next; + unsigned int hash; +}; + +struct strbuf { + size_t alloc; + size_t len; + char *buf; +}; + +struct oid2strbuf { + struct hashmap_entry ent; /* must be the first member! */ + unsigned char key[21]; + struct strbuf *value; +}; + + +struct hashmap_iter { + struct hashmap *map; + struct hashmap_entry *next; + unsigned int tablepos; +}; + +struct hashmap { + struct hashmap_entry **table; + // hashmap_cmp_fn cmpfn; + unsigned int size, tablesize, grow_at, shrink_at; + unsigned disallow_rehash : 1; +}; +void strbuf_init(struct strbuf *, size_t); +void *hashmap_iter_next(struct hashmap_iter *iter); +void hashmap_free(struct hashmap *map, int free_entries); +void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter); + +void strbuf_release(struct strbuf *sb) +{ + if (sb->alloc) { /* { dg-bogus "use after 'free'" } */ + free(sb->buf); + strbuf_init(sb, 0); + } +} + +void oid2strbuf_free(struct hashmap *map) { + struct hashmap_iter iter; + struct hashmap_entry *e; + + hashmap_iter_init(map, &iter); + while ((e = hashmap_iter_next(&iter))) { + struct oid2strbuf *e_strbuf = (struct oid2strbuf *)e; + strbuf_release(e_strbuf->value); /* { dg-bogus "use after 'free'" } */ + free(e_strbuf->value); + free(e); + } + + hashmap_free(map, 0); +} + diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c b/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c new file mode 100644 index 0000000..fd71d35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c @@ -0,0 +1,42 @@ +struct node +{ + struct node *next; +}; + +void test_1 (struct node *n) +{ + while (n) + { + struct node *next = n->next; + __builtin_free (n); + n = next; + } +} + +extern void *get_ptr (void); + +void test_2 (void) +{ + void *p; + while (p = get_ptr ()) + __builtin_free (p); /* { dg-bogus "double-'free' of 'p'" } */ +} + +extern void **get_ptr_ptr (void); + +void test_3 (void) +{ + void **p; + while (p = get_ptr_ptr ()) + __builtin_free (*p); /* { dg-bogus "double-'free'" } */ +} + +void test_4 (void) +{ + void *p = (void *)0; + while (1) + { + __builtin_free (p); /* { dg-bogus "double-'free' of 'p'" } */ + p = get_ptr (); + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c new file mode 100644 index 0000000..6720c3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c @@ -0,0 +1,40 @@ +#include +#include + +void +test_1 (void) +{ + int i; + + for (i = 0; i < 2; ++i) { + FILE *fp = fopen ("/tmp/test", "w"); + fprintf (fp, "hello:%s ", "world"); + fclose (fp); /* { dg-bogus "double 'fclose'" } */ + } +} + +void +test_2 (void) +{ + int i; + + for (i = 0; i < 2; ++i) { + FILE *fp = fopen ("/tmp/test", "w"); + fprintf (fp, "hello"); + } +} /* { dg-warning "leak of FILE 'fp'" } */ + +FILE *fp3; + +void +test_3 (FILE **fpp) +{ + int i; + + for (i = 0; i < 2; ++i) { + *fpp = fopen ("/tmp/test", "w"); + fprintf (*fpp, "hello"); + fclose (*fpp); /* { dg-bogus "double 'fclose'" } */ + *fpp = NULL; + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99716-2.c b/gcc/testsuite/gcc.dg/analyzer/pr99716-2.c new file mode 100644 index 0000000..7c9881c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99716-2.c @@ -0,0 +1,34 @@ +/* Reduced from + https://github.com/libguestfs/libguestfs/blob/e0a11061035d47b118c95706240bcc17fd576edc/tests/mount-local/test-parallel-mount-local.c#L299-L335 + which is GPLv2 or later. */ + +#include +#include + +extern int foo (void); + +void +test_mountpoint (const char *mp) +{ + const int nr_passes = 5 + (random () & 31); + int pass; + int ret = 1; + FILE *fp; + + for (pass = 0; pass < nr_passes; ++pass) { + if (foo ()) { + goto error; + } + fp = fopen ("file", "w"); + if (fp == NULL) { + goto error; + } + fprintf (fp, "hello world\n"); + fclose (fp); /* { dg-bogus "double 'fclose'" } */ + } + + ret = 0; + + error: + exit (ret); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99716-3.c b/gcc/testsuite/gcc.dg/analyzer/pr99716-3.c new file mode 100644 index 0000000..77d450e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99716-3.c @@ -0,0 +1,16 @@ +#include + +extern void foo (void *); + +void +test_1 (int nr_passes) +{ + int pass; + void *p; + + for (pass = 0; pass < nr_passes; ++pass) { + p = malloc (1024); + foo (p); + free (p); + } +} -- cgit v1.1 From 1b229a305091f0a9c64e5be3c1af5ef62b75e3cb Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 25 Mar 2021 15:31:46 -0600 Subject: New test for PR tree-optimization/44547 - -Wuninitialized reports false warning in nested switch statements. gcc/testsuite/ChangeLog: * gcc.dg/uninit-pr44547.c: New. --- gcc/testsuite/gcc.dg/uninit-pr44547.c | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr44547.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr44547.c b/gcc/testsuite/gcc.dg/uninit-pr44547.c new file mode 100644 index 0000000..ee1035a --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr44547.c @@ -0,0 +1,61 @@ +/* PR tree-optimization/44547 - -Wuninitialized reports false warning + in nested switch statements + { dg-do compile } + { dg-options "-O1 -Wall" } */ + +__attribute__ ((noipa)) int test_O1 (int argc) +{ + switch( argc ) + { + case 1: + case 2: + case 4: + { + int n; + switch( argc ) + { + case 1: + case 2: + case 4: + n = argc; + break; + } + + return n; + + break; + } + } + + return 0; +} + + +#pragma GCC optimize ("2") + +__attribute__ ((noipa)) int test_O2 (int argc) +{ + switch( argc ) + { + case 1: + case 2: + case 4: + { + int n; + switch( argc ) + { + case 1: + case 2: + case 4: + n = argc; + break; + } + + return n; + + break; + } + } + + return 0; +} -- cgit v1.1 From e88ca9f42306e291d3cb2d34dd7f2b017a3c1e52 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 25 Mar 2021 17:23:06 -0600 Subject: PR tree-optimization/55060 - False un-initialized variable warnings gcc/testsuite/ChangeLog: PR tree-optimization/55060 * gcc.dg/uninit-pr55060.c: New. --- gcc/testsuite/gcc.dg/uninit-pr55060.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr55060.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr55060.c b/gcc/testsuite/gcc.dg/uninit-pr55060.c new file mode 100644 index 0000000..b2f2cb1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr55060.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/55060 - False un-initialized variable warnings + { dg-do compile } + { dg-options "-O1 -Wuninitialized" } */ + +static void a(int *i) { } +static void b(int p) { } +int foo(void) { + int i; + a(&i); + b(i); // { dg-bogus "\\\[-Wuninitialized" } + return 0; +} + +static void c(int *i) { } +extern void d(int p); +int bar(void) { + int i; + c(&i); + d(i); // { dg-warning "\\\[-Wuninitialized" } + return 0; +} + +extern void e(int *i); +static void f(int p) {}; +int baz(void) { + int i; + e(&i); + f(i); // { dg-bogus "\\\[-Wuninitialized" } + return 0; +} -- cgit v1.1 From 8f5e18db259c8a9790feb1d73bb0348182264f15 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sat, 13 Mar 2021 17:05:52 +0100 Subject: Fix ICE: in function_and_variable_visibility, at ipa-visibility.c:795 [PR99466] In get_emutls_init_templ_addr, only thread-local declarations that were DECL_ONE_ONLY would have a public initializer symbol, ignoring variables that were declared with __attribute__((weak)). gcc/ChangeLog: PR ipa/99466 * tree-emutls.c (get_emutls_init_templ_addr): Mark initializer of weak TLS declarations as public. gcc/testsuite/ChangeLog: PR ipa/99466 * gcc.dg/tls/pr99466-1.c: New test. * gcc.dg/tls/pr99466-2.c: New test. --- gcc/testsuite/gcc.dg/tls/pr99466-1.c | 8 ++++++++ gcc/testsuite/gcc.dg/tls/pr99466-2.c | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tls/pr99466-1.c create mode 100644 gcc/testsuite/gcc.dg/tls/pr99466-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tls/pr99466-1.c b/gcc/testsuite/gcc.dg/tls/pr99466-1.c new file mode 100644 index 0000000..446850e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/pr99466-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-require-weak "" } */ +/* { dg-require-effective-target tls_emulated } */ +/* { dg-add-options tls } */ +__attribute__((weak)) +__thread int tlsvar = 3; +/* { dg-final { scan-assembler ".weak_definition ___emutls_t.tlsvar" { target *-*-darwin* } } } */ +/* { dg-final { scan-assembler-not ".private_extern ___emutls_t.tlsvar" { target *-*-darwin* } } } */ diff --git a/gcc/testsuite/gcc.dg/tls/pr99466-2.c b/gcc/testsuite/gcc.dg/tls/pr99466-2.c new file mode 100644 index 0000000..86ffaad --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/pr99466-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-weak "" } */ +/* { dg-require-visibility "" } */ +/* { dg-require-effective-target tls_emulated } */ +/* { dg-add-options tls } */ +__attribute__((weak)) +__attribute__((visibility ("hidden"))) +__thread int tlsvar = 3; +/* { dg-final { scan-assembler ".weak_definition ___emutls_t.tlsvar" { target *-*-darwin* } } } */ +/* { dg-final { scan-assembler ".private_extern ___emutls_t.tlsvar" { target *-*-darwin* } } } */ -- cgit v1.1 From 980b12cc81979e52f491bf0dfe961d30c07fe864 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 26 Mar 2021 16:37:34 -0600 Subject: PR tree-optimization/59970 - Bogus -Wmaybe-uninitialized at low optimization levels PR tree-optimization/59970 * gcc.dg/uninit-pr59970.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr59970.c | 79 +++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr59970.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr59970.c b/gcc/testsuite/gcc.dg/uninit-pr59970.c new file mode 100644 index 0000000..145af65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr59970.c @@ -0,0 +1,79 @@ +/* PR tree-optimization/59970 - Bogus -Wmaybe-uninitialized at low optimization + levels + { dg-do compile } + { dg-options "-Wall" } */ + +#pragma GCC push_options +#pragma GCC optimize ("1") + +__attribute__ ((noipa)) int +d_demangle_callback_O1 (const char *mangled) +{ + enum { DCT_TYPE, DCT_GLOBAL_DTORS } type; + int dc; + + /* Fails for -Og and -O1. */ + if (mangled) + type = DCT_GLOBAL_DTORS; + else + type = DCT_TYPE; + + /* If both cases assign the same value, all is fine. */ + switch (type) + { + case DCT_TYPE: + dc = 0 /* 1 */; + break; + case DCT_GLOBAL_DTORS: + dc = /* 0 */ 1; + break; + + /* If this is added, all is fine. */ +#ifdef ABORT + default: + __builtin_unreachable (); +#endif + } + + return dc; // { dg-bogus "uninitialized" } +} + +#pragma GCC pop_options + + +#pragma GCC optimize ("Og") + +__attribute__ ((noipa)) int +d_demangle_callback_Og (const char *mangled) +{ + enum { DCT_TYPE, DCT_GLOBAL_DTORS } type; + int dc; + + /* Fails for -Og. */ + /* Removing either the function call or the array dereference, it'll be like + the TOGGLE1 case. */ + extern int cmp (void); + if (cmp () && mangled[0]) + type = DCT_GLOBAL_DTORS; + else + type = DCT_TYPE; + + /* If both cases assign the same value, all is fine. */ + switch (type) + { + case DCT_TYPE: + dc = 0 /* 1 */; + break; + case DCT_GLOBAL_DTORS: + dc = /* 0 */ 1; + break; + + /* If this is added, all is fine. */ +#ifdef ABORT + default: + __builtin_unreachable (); +#endif + } + + return dc; // { dg-bogus "uninitialized" } +} -- cgit v1.1 From 77093a75ca4f3a0d6d9ca77ca8905b77695a2599 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 29 Mar 2021 13:52:53 -0600 Subject: PR tree-optimization/61112 - repeated conditional triggers false positive -Wmaybe-uninitialized gcc/testsuite/ChangeLog: PR tree-optimization/61112 * gcc.dg/uninit-pr61112.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr61112.c | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr61112.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr61112.c b/gcc/testsuite/gcc.dg/uninit-pr61112.c new file mode 100644 index 0000000..1dbf756 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr61112.c @@ -0,0 +1,89 @@ +/* PR tree-optimization/61112 - repeated conditional triggers false-positive + -Wmaybe-uninitialized warning + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +int p; + +void foo_c0 (int x, int y, int z) +{ + int w; + if (x) + w = z; + if (y) + w = __LINE__; + + if (x || y) + p = w; // { dg-bogus "-Wmaybe-uninitialized" } +} + + +void foo_c5_1_1 (int x, int y, int z, int a) +{ + int w; + if (x) + w = z; + if (y) + w = __LINE__; + if (a) + w = __LINE__; + + if (x || y || a) + p = w; // { dg-bogus "-Wmaybe-uninitialized" "pr61112" { xfail *-*-* } } +} + +void foo_c5_1_2 (int x, int y, int z, int a) +{ + int w; + if (x) + w = z; + if (y) + w = __LINE__; + if (a) + w = __LINE__; + + if (x || a || y) + p = w; // { dg-bogus "-Wmaybe-uninitialized" "pr61112" { xfail *-*-* } } +} + +void foo_c5_1_3 (int x, int y, int z, int a) +{ + int w; + if (x) + w = z; + if (y) + w = __LINE__; + if (a) + w = __LINE__; + + if (a || x || y) + p = w; // { dg-bogus "-Wmaybe-uninitialized" "pr61112" { xfail *-*-* } } +} + +void foo_c5_2 (int x, int y, int z, int a) +{ + int w; + if (x) + w = __LINE__; + if (y) + w = z; + if (a) + w = __LINE__; + + if (x || y || a) + p = w; // { dg-bogus "-Wmaybe-uninitialized" } +} + +void foo_c5_3 (int x, int y, int z, int a) +{ + int w; + if (x) + w = __LINE__; + if (y) + w = __LINE__; + if (a) + w = z; + + if (x || y || a) + p = w; // { dg-bogus "-Wmaybe-uninitialized" } +} -- cgit v1.1 From fecc835e216f537d3e7edb833cb3769489b983bb Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 29 Mar 2021 15:21:32 -0600 Subject: PR tree-optimization/61677 - False positive with -Wmaybe-uninitialized gcc/testsuite/ChangeLog: PR tree-optimization/61677 * gcc.dg/uninit-pr61677.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr61677.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr61677.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr61677.c b/gcc/testsuite/gcc.dg/uninit-pr61677.c new file mode 100644 index 0000000..a982fae --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr61677.c @@ -0,0 +1,26 @@ +/* PR tree-optimization/61677 - False positive with -Wmaybe-uninitialized + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void *xmalloc (void); + +struct menu { struct menu *parent; }; + +struct jump_key { int offset; }; + +void f (struct menu *menu) +{ + int i; + struct menu *submenu[8], *location; + struct jump_key *jump; + location = menu; + for (i = 0; menu && i < 8; menu = menu->parent) + submenu[i++] = menu; + if (location) + jump = xmalloc (); + while (--i >= 0) { + menu = submenu[i]; + if (location) + jump->offset = 42; + } +} -- cgit v1.1 From af739c8797d4cdf550366d0ef48136e0073df5c9 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 29 Mar 2021 15:58:01 -0600 Subject: PR tree-optimization/61869 - Spurious uninitialized warning gcc/testsuite/ChangeLog: PR tree-optimization/61869 * gcc.dg/uninit-pr61869.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr61869.c | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr61869.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr61869.c b/gcc/testsuite/gcc.dg/uninit-pr61869.c new file mode 100644 index 0000000..ef4f436 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr61869.c @@ -0,0 +1,47 @@ +/* PR tree-optimization/61869 - Spurious uninitialized warning (lim1 pass, + pretty-printed internal var + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef struct data { + struct data *next; +} data; + +typedef struct list { + unsigned dummy; + struct list *next; + data *start; + int flags; +} list; + +typedef struct iterator { + struct data *ptr; + unsigned dummy; +} iterator; + +iterator start (list *a) { + iterator i = { + *(a->flags ? &a->start : 0), + 0 + }; + return i; +} + +void g (iterator *i); + +void f (list *b) +{ + list *a; + iterator i; // { dg-bogus "-Wmaybe-uninitialized" } + + for (a = b; a; a = a->next) + for (i = start (a); i.ptr; i.ptr = i.ptr->next) + { + if (i.ptr) + return; + } + + for (a = b; a; a = a->next) + for (i = start (a); i.ptr; i.ptr = i.ptr->next) + g(&i); +} -- cgit v1.1 From bd3d919b58466a9837e423c1255b88215f89bc9d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 30 Mar 2021 11:22:52 +0200 Subject: tree-optimization/99824 - avoid excessive integer type precision in VN VN sometimes builds new integer types to handle accesss where precision of the access type does not match the access size. The way ao_ref_init_from_vn_reference is computing the access size ignores the access type in case the ref operands have an outermost COMPONENT_REF which, in case it is an array for example, can be way larger than the access size. This can cause us to try building an integer type with precision larger than WIDE_INT_MAX_PRECISION eventually leading to memory corruption. The following adjusts ao_ref_init_from_vn_reference to only lower access sizes via the outermost COMPONENT_REF but otherwise honor the access size as specified by the access type. It also places an assert in integer type building that we remain in the limits of WIDE_INT_MAX_PRECISION. I chose the shared code where we set TYPE_MIN/MAX_VALUE because that will immediately cross the wide_ints capacity otherwise. 2021-03-30 Richard Biener PR tree-optimization/99824 * stor-layout.c (set_min_and_max_values_for_integral_type): Assert the precision is within the bounds of WIDE_INT_MAX_PRECISION. * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use the outermost component ref only to lower the access size and initialize that from the access type. * gcc.dg/torture/pr99824.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr99824.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr99824.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr99824.c b/gcc/testsuite/gcc.dg/torture/pr99824.c new file mode 100644 index 0000000..9022d4a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99824.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ + +unsigned int +strlenx(char *s) +{ + char *orig_s = s; + for (; *s; ++s) + ; + return s - orig_s; +} + +struct i2c_adapter { + char name[48]; +}; + +struct { + int instance; + struct i2c_adapter i2c_adap[]; +} * init_cx18_i2c_cx; + +const struct i2c_adapter cx18_i2c_adap_template = {""}; +int init_cx18_i2c___trans_tmp_1; + +void +init_cx18_i2c() +{ + int i = 0; + for (;; i++) { + init_cx18_i2c_cx->i2c_adap[i] = cx18_i2c_adap_template; + init_cx18_i2c___trans_tmp_1 + = strlenx(init_cx18_i2c_cx->i2c_adap[i].name); + } +} -- cgit v1.1 From a01f5fd71031bb34fd9d2792e6ec42d982c68a8e Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 24 Mar 2021 21:08:04 -0400 Subject: analyzer testsuite: fix typo gcc/testsuite/ChangeLog: * gcc.dg/analyzer/symbolic-1.c: Fix typo. --- gcc/testsuite/gcc.dg/analyzer/symbolic-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c index 9d228e6..feab9ce 100644 --- a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c @@ -1,6 +1,6 @@ #include "analyzer-decls.h" -/* The example from store2.h */ +/* The example from store.h */ void test_1 (char a, char b, char c, char d, char e, char f, int i, int j) -- cgit v1.1 From 31199d95de1304e200554bbf98b2d8a6a7298bec Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 31 Mar 2021 10:39:24 -0600 Subject: PR middle-end/65182 - -Wuninitialized fails when pointer to variable later passed to function gcc/testsuite: PR middle-end/65182 * gcc.dg/uninit-pr65182.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr65182.c | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr65182.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr65182.c b/gcc/testsuite/gcc.dg/uninit-pr65182.c new file mode 100644 index 0000000..45b538d --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr65182.c @@ -0,0 +1,44 @@ +/* PR middle-end/65182 - -Wuninitialized fails when pointer to variable + later passed to function + { dg-do compile } + { dg-options "-O0 -Wall" } */ + +void bar (int *a); + +int baz (void); + +__attribute__ ((noipa)) void foo_O0 (int *b) +{ + int a; + + if (a) // { dg-warning "\\\[-Wuninitialized" } + { + *b = 0; + return; + } + + bar (&a); + + a = baz (); + + *b = a + 2; +} + +#pragma GCC optimize ("2") + +__attribute__ ((noipa)) void foo_O2 (int *b) +{ + int a; + + if (a) // { dg-warning "\\\[-Wuninitialized" } + { + *b = 0; + return; + } + + bar (&a); + + a = baz (); + + *b = a + 3; +} -- cgit v1.1 From e4bb1bd60a9fd1bed36092a990aa5fed5d45bfa6 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 29 Mar 2021 16:13:32 -0400 Subject: analyzer: avoid printing '' for SSA names [PR99771] We don't want to print '' in our diagnostics, but PR analyzer/99771 lists various cases where -fanalyzer does, due to using the SSA_NAME for a temporary when determining the best tree to use. This can happen in two ways: (a) ...when a better expression than the SSA_NAME could be built, but finding it requires traversing the relationships in the region_model in a graph-like way, rather than by considering individual svalues and regions. (b) ...when the only remaining user of the underlying svalue is the SSA_NAME, typically due to the diagnostic referring to a temporary. I've been experimenting with fixing (a), but don't have a good fix yet. In the meantime, this patch addresses (b) by detecting if we have the SSA_NAME for a temporary, and, for the cases where it's possible, reconstructing a tree by walking the def-stmts. This fixes various cases of (b) and ameliorates some cases of (a). gcc/analyzer/ChangeLog: PR analyzer/99771 * analyzer.cc (maybe_reconstruct_from_def_stmt): New. (fixup_tree_for_diagnostic_1): New. (fixup_tree_for_diagnostic): New. * analyzer.h (fixup_tree_for_diagnostic): New decl. * checker-path.cc (call_event::get_desc): Call fixup_tree_for_diagnostic and use it for the call_with_state call. (warning_event::get_desc): Likewise for the final_event and make_label_text calls. * engine.cc (impl_region_model_context::on_state_leak): Likewise for the on_leak and add_diagnostic calls. * region-model.cc (region_model::get_representative_tree): Likewise for the result. gcc/testsuite/ChangeLog: PR analyzer/99771 * gcc.dg/analyzer/data-model-10.c: Update expected output. * gcc.dg/analyzer/malloc-ipa-13.c: Likewise. * gcc.dg/analyzer/malloc-ipa-13a.c: New test. * gcc.dg/analyzer/pr99771-1.c: New test. --- gcc/testsuite/gcc.dg/analyzer/data-model-10.c | 3 +- gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c | 3 +- gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13a.c | 38 ++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99771-1.c | 63 ++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99771-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-10.c b/gcc/testsuite/gcc.dg/analyzer/data-model-10.c index c261edc..04c9891 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-10.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-10.c @@ -12,6 +12,7 @@ test (void) if (!new_table) return NULL; new_table->m_f = (char **)malloc(sizeof(char **)); - *new_table->m_f = NULL; /* { dg-warning "dereference of possibly-NULL ''" } */ // FIXME: something better than "unknown" here + *new_table->m_f = NULL; /* { dg-warning "dereference of possibly-NULL '\\*new_table.m_f'" } */ + /* { dg-message "'\\*new_table.m_f' could be NULL" "final event wording" { target *-*-* } .-1 } */ return new_table; } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c index 2e3d80e..a08386a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13.c @@ -23,8 +23,7 @@ void test (struct foo f) do_stuff (); - calls_free (f.m_p); /* { dg-message "passing freed pointer '' in call to 'calls_free' from 'test'" } */ - // TODO: something better than '' + calls_free (f.m_p); /* { dg-message "passing freed pointer 'f\\.m_p' in call to 'calls_free' from 'test'" } */ do_stuff (); } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13a.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13a.c new file mode 100644 index 0000000..d74ef59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-13a.c @@ -0,0 +1,38 @@ +/* { dg-additional-options "-fanalyzer-verbosity=1" } */ + +#include + +void +calls_free (void *victim) +{ + free (victim); /* { dg-warning "double-'free' of 'victim'" } */ +} + +extern void do_stuff (void); + +struct foo +{ + void *m_p; +}; + +static void * __attribute__((noinline)) +test_a (struct foo f) +{ + do_stuff (); + + calls_free (f.m_p); + + do_stuff (); + + return f.m_p; +} + +void test_b (void *p) +{ + void *q; + struct foo f; + f.m_p = p; + q = test_a (f); + calls_free (q); /* { dg-message "passing freed pointer 'q' in call to 'calls_free' from 'test_b'" } */ + do_stuff (); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99771-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99771-1.c new file mode 100644 index 0000000..08449f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99771-1.c @@ -0,0 +1,63 @@ +/* Verify that we don't print "" in various diagnostics + (PR analyzer/99771). */ + +#include + +void test_1 (void) +{ + *(char*)malloc (1024) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(1024\\)'" } */ +} /* { dg-warning "leak of 'malloc\\(1024\\)'" "warning" } */ + /* { dg-message "'malloc\\(1024\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +void test_2 (size_t n) +{ + *(char*)malloc (4 * n) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(n \\* 4\\)'" "warning" } */ + /* { dg-message "'malloc\\(n \\* 4\\)' could be NULL" "final event" { target *-*-* } .-1 } */ +} /* { dg-warning "leak of 'malloc\\(n \\* 4\\)'" "warning" } */ + /* { dg-message "'malloc\\(n \\* 4\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +/* A compound example. */ + +void test_3 (size_t a, size_t b, size_t c) +{ + *(char*)malloc (a + (b * c)) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(a \\+ b \\* c\\)'" "warning" } */ + /* { dg-message "'malloc\\(a \\+ b \\* c\\)' could be NULL" "final event" { target *-*-* } .-1 } */ +} /* { dg-warning "leak of 'malloc\\(a \\+ b \\* c\\)'" "warning" } */ + /* { dg-message "'malloc\\(a \\+ b \\* c\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +void test_4 (size_t a, size_t b, size_t c) +{ + *(char *)malloc (a ? b : c) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(\\)'" "warning" } */ + /* { dg-message "'malloc\\(\\)' could be NULL" "final event" { target *-*-* } .-1 } */ +} /* { dg-warning "leak of 'malloc\\(\\)'" "warning" } */ + /* { dg-message "'malloc\\(\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +/* Unary operators. */ + +void test_5 (size_t a) +{ + *(char*)malloc (-a) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(-a\\)'" } */ +} /* { dg-warning "leak of 'malloc\\(-a\\)'" "warning" } */ + /* { dg-message "'malloc\\(-a\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +void test_6 (size_t a) +{ + *(char*)malloc (~a) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(~a\\)'" } */ +} /* { dg-warning "leak of 'malloc\\(~a\\)'" "warning" } */ + /* { dg-message "'malloc\\(~a\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +/* Field access. */ + +struct s7 { size_t sz; }; + +void test_7a(struct s7 s) +{ + *(char*)malloc (s.sz) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(s\\.sz\\)'" } */ +} /* { dg-warning "leak of 'malloc\\(s\\.sz\\)'" "warning" } */ + /* { dg-message "'malloc\\(s\\.sz\\)' leaks here" "final event" { target *-*-* } .-1 } */ + +void test_7b (struct s7 *s) +{ + *(char*)malloc (s->sz) = 42; /* { dg-warning "dereference of possibly-NULL 'malloc\\(\\*s\\.sz\\)'" } */ +} /* { dg-warning "leak of 'malloc\\(\\*s\\.sz\\)'" "warning" } */ + /* { dg-message "'malloc\\(\\*s\\.sz\\)' leaks here" "final event" { target *-*-* } .-1 } */ -- cgit v1.1 From 19d71674616e6494a60432a2a28adcd762a6c877 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Thu, 1 Apr 2021 10:12:23 +0200 Subject: sra: Fix bug in grp_write propagation (PR 97009) SRA represents parts of aggregates which are arrays accessed with unknown index as "unscalarizable regions." When there are two such regions one within another and the outer is only read whereas the inner is written to, SRA fails to propagate that write information across assignments. This means that a second aggregate can contain data while SRA thinks it does not and the pass can wrongly eliminate big chunks of assignment from that second aggregate into a third aggregate, which is what happens in PR 97009. Fixed by checking all children of unscalariable accesses for the grp_write flag. gcc/ChangeLog: 2021-03-31 Martin Jambor PR tree-optimization/97009 * tree-sra.c (access_or_its_child_written): New function. (propagate_subaccesses_from_rhs): Use it instead of a simple grp_write test. gcc/testsuite/ChangeLog: 2021-03-31 Martin Jambor PR tree-optimization/97009 * gcc.dg/tree-ssa/pr97009.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr97009.c | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr97009.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97009.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97009.c new file mode 100644 index 0000000..741dbc2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97009.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +static int __attribute__((noipa)) +get_5 (void) +{ + return 5; +} + +static int __attribute__((noipa)) +verify_5 (int v) +{ + if (v != 5) + __builtin_abort (); +} + +struct T +{ + int w; + int a[4]; +}; + +struct S +{ + int v; + int x; + struct T t[2]; + char alotofstuff[128]; +}; + +volatile int vol; + +void __attribute__((noipa)) +consume_t (struct T t) +{ + vol = t.a[0]; +} + +int __attribute__((noipa)) +foo (int l1, int l2) +{ + struct S s1, s2, s3; + int i, j; + + s1.v = get_5 (); + for (i = 0; i < l1; i++) + { + for (j = 0; j < l2; j++) + s1.t[i].a[j] = get_5 (); + consume_t(s1.t[i]); + } + + s2 = s1; + + s3 = s2; + for (i = 0; i < l1; i++) + for (j = 0; j < l2; j++) + verify_5 (s3.t[i].a[j]); +} + +int +main (int argc, char *argv[]) +{ + foo (2, 4); + return 0; +} -- cgit v1.1 From b75c4e1384c021ca94fc8e8db8e517e802b820f3 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 1 Apr 2021 09:29:14 +0200 Subject: tree-optimization/99856 - fix overwideing pattern creation This fixes an omission of promoting a bit-precision required precision to a vector element precision. 2021-04-01 Richard Biener PR tree-optimization/99856 * tree-vect-patterns.c (vect_recog_over_widening_pattern): Promote precision to vector element precision. * gcc.dg/vect/pr99856.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr99856.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr99856.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr99856.c b/gcc/testsuite/gcc.dg/vect/pr99856.c new file mode 100644 index 0000000..e5d2a45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr99856.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_unpack } */ +/* { dg-require-effective-target vect_pack_trunc } */ + +#define SHIFTFORDIV255(a)\ + ((((a) >> 8) + a) >> 8) + +#define DIV255(a)\ + SHIFTFORDIV255(a + 0x80) + +typedef unsigned char uint8_t; + +void +opSourceOver_premul(uint8_t* restrict Rrgba, + const uint8_t* restrict Srgba, + const uint8_t* restrict Drgba, int len) +{ + Rrgba = __builtin_assume_aligned (Rrgba, __BIGGEST_ALIGNMENT__); + Srgba = __builtin_assume_aligned (Rrgba, __BIGGEST_ALIGNMENT__); + Drgba = __builtin_assume_aligned (Rrgba, __BIGGEST_ALIGNMENT__); + int i = 0; + for (; i < len*4; i += 4) + { + uint8_t Sa = Srgba[i + 3]; + Rrgba[i + 0] = DIV255(Srgba[i + 0] * 255 + Drgba[i + 0] * (255 - Sa)); + Rrgba[i + 1] = DIV255(Srgba[i + 1] * 255 + Drgba[i + 1] * (255 - Sa)); + Rrgba[i + 2] = DIV255(Srgba[i + 2] * 255 + Drgba[i + 2] * (255 - Sa)); + Rrgba[i + 3] = DIV255(Srgba[i + 3] * 255 + Drgba[i + 3] * (255 - Sa)); + } +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */ -- cgit v1.1 From 5b9a65ecbeb22ef6dd3344baae97f85b645522e3 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 1 Apr 2021 10:51:03 +0200 Subject: bswap: Handle bswapping of pointers [PR96573] In GCC8/9 we used to optimize this into a bswap, but we no longer do. Handling byteswapping of pointers is easy, all we need is to allow them, for the __builtin_bswap* we already use TYPE_PRECISION to determine the precision and we cast the operand and result to the correct type if they aren't uselessly convertible to what the builtin expects. 2021-04-01 Jakub Jelinek PR tree-optimization/96573 * gimple-ssa-store-merging.c (init_symbolic_number): Handle also pointer types. * gcc.dg/pr96573.c: New test. --- gcc/testsuite/gcc.dg/pr96573.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr96573.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr96573.c b/gcc/testsuite/gcc.dg/pr96573.c new file mode 100644 index 0000000..3acf117 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr96573.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/96573 */ +/* { dg-do compile { target { lp64 || ilp32 } } } */ +/* { dg-require-effective-target bswap } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "__builtin_bswap" "optimized" } } */ + +typedef __SIZE_TYPE__ size_t; + +void * +foo (void * const p) +{ + const size_t m = sizeof (p) - 1; + const unsigned char * const o = (unsigned char*) &p; + void *n; + unsigned char * const q = (unsigned char *) &n; + unsigned char i; + for (i = 0; i <= m; ++i) + q[m - i] = o[i]; + return n; +} -- cgit v1.1 From 3064fc21aa29d8e04b23c0b52dc4f67de1da6b2f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 1 Apr 2021 12:11:39 +0200 Subject: Add testcase for PR98265 gcc/testsuite/ChangeLog: 2021-04-01 Jan Hubicka PR ipa/98265 * gcc.dg/tree-ssa/pr98265.C: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr98265.C | 348 ++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr98265.C (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98265.C b/gcc/testsuite/gcc.dg/tree-ssa/pr98265.C new file mode 100644 index 0000000..9c798e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98265.C @@ -0,0 +1,348 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +extern void __assert_fail(const char*, const char*, int, const char*); +namespace Eigen { +enum { AutoAlign }; +template +struct conditional; +template +struct conditional { + typedef Else type; +}; +template +struct remove_reference { + typedef T type; +}; +struct is_arithmetic { + enum { value }; +}; +template +struct traits; +template +struct traits : traits {}; +template +struct evaluator; +template +struct EigenBase; +template +class PlainObjectBase; +template +class Matrix; +template +class MatrixBase; +template +class CwiseNullaryOp; +template +class CwiseBinaryOp; +template +struct scalar_constant_op; +template +struct size_at_compile_time { + enum { ret = _Rows }; +}; +struct ref_selector { + typedef const Matrix& type; +}; +template +struct dense_xpr_base { + typedef MatrixBase type; +}; +template ::XprKind> +struct generic_xpr_base { + typedef typename dense_xpr_base::type type; +}; +template +struct plain_constant_type { + ; + typedef CwiseNullaryOp, + Matrix::ColsAtCompileTime, + traits::MaxRowsAtCompileTime, + traits::MaxColsAtCompileTime>> + type; +}; +struct scalar_product_op { + float operator()(float a, float b) { return a * b; } +}; +template +struct scalar_constant_op { + scalar_constant_op(float other) : m_other(other) {} + float operator()() { return m_other; } + float m_other; +}; +struct assign_op { + void assignCoeff(float& a, float b) { a = b; } +}; +template +class DenseCoeffsBase : public EigenBase { + public: + typedef typename traits::Scalar Scalar; + typedef + typename conditional::type CoeffReturnType; +}; +template +class DenseBase : public DenseCoeffsBase { + public: + enum { + RowsAtCompileTime = traits::RowsAtCompileTime, + SizeAtCompileTime = size_at_compile_time::ret, + MaxSizeAtCompileTime + }; +}; +template +class MatrixBase : public DenseBase { + public: + using DenseBase::derived; + template + CwiseBinaryOp::type> + operator*(T& scalar) { + return CwiseBinaryOp::type>( + derived(), typename plain_constant_type::type(derived().rows(), + 0, scalar)); + } +}; +template +struct EigenBase { + const Derived& derived() const { return *static_cast(this); } + Derived& const_cast_derived() const { + return *static_cast(const_cast(this)); + } +}; +template +struct binary_evaluator; +template +struct evaluator : evaluator { + evaluator(const T& xpr) : evaluator(xpr) {} +}; +template +struct evaluator { + typedef Derived PlainObjectType; + typedef typename PlainObjectType::Scalar Scalar; + evaluator(const PlainObjectType& m) : m_data(m.data()) {} + typename PlainObjectType::CoeffReturnType coeff(long row, long) { + return m_data[row]; + } + Scalar& coeffRef(long row, long) { return const_cast(m_data)[row]; } + const Scalar* m_data; +}; +template +struct evaluator> + : evaluator>> { + typedef Matrix XprType; + evaluator(const XprType& m) : evaluator>(m) {} +}; +struct nullary_wrapper { + template + float operator()(scalar_constant_op op, IndexType, IndexType) const { + return op(); + } +}; +template +struct evaluator> { + typedef CwiseNullaryOp XprType; + evaluator(XprType n) : m_functor(n.functor()) {} + template + typename XprType::CoeffReturnType coeff(IndexType row, IndexType col) { + return m_wrapper(m_functor, row, col); + } + NullaryOp m_functor; + nullary_wrapper m_wrapper; +}; +template +struct evaluator> + : binary_evaluator> { + evaluator(CwiseBinaryOp xpr) + : binary_evaluator>(xpr) {} +}; +template +struct binary_evaluator> { + typedef CwiseBinaryOp XprType; + binary_evaluator(XprType xpr) : m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {} + typename XprType::CoeffReturnType coeff(long row, long col) { + return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col)); + } + BinaryOp m_functor; + evaluator m_lhsImpl; + evaluator m_rhsImpl; +}; +template +struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling { + enum { outer, inner = Index }; + static void run(Kernel kernel) { + kernel.assignCoeffByOuterInner(outer, inner); + copy_using_evaluator_DefaultTraversal_CompleteUnrolling::run(kernel); + } +}; +template +struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling { + static void run(Kernel) {} +}; +template +struct dense_assignment_loop { + static void run(Kernel kernel) { + typedef typename Kernel::DstEvaluatorType::XprType DstXprType; + enum { size = DstXprType::SizeAtCompileTime, alignedSize = 0 }; + copy_using_evaluator_DefaultTraversal_CompleteUnrolling::run(kernel); + } +}; +template +class generic_dense_assignment_kernel { + typedef typename DstEvaluatorTypeT::XprType DstXprType; + + public: + typedef DstEvaluatorTypeT DstEvaluatorType; + typedef SrcEvaluatorTypeT SrcEvaluatorType; + generic_dense_assignment_kernel(DstEvaluatorType dst, SrcEvaluatorType src, + Functor, DstXprType& dstExpr) + : m_dst(dst), m_src(src), m_dstExpr(dstExpr) {} + long assignCoeff_col; + void assignCoeffByOuterInner(long, long inner) { + long __trans_tmp_1 = inner; + m_functor.assignCoeff(m_dst.coeffRef(__trans_tmp_1, assignCoeff_col), + m_src.coeff(__trans_tmp_1, assignCoeff_col)); + } + DstEvaluatorType m_dst; + SrcEvaluatorType m_src; + Functor m_functor; + DstXprType& m_dstExpr; +}; +template +void call_dense_assignment_loop(DstXprType& dst, SrcXprType src, Functor func) { + typedef evaluator DstEvaluatorType; + typedef evaluator SrcEvaluatorType; + SrcEvaluatorType srcEvaluator(src); + DstEvaluatorType dstEvaluator(dst); + typedef generic_dense_assignment_kernel + Kernel; + Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived()); + dense_assignment_loop::run(kernel); +} +template +void call_assignment_no_alias(Dst& dst, Src src, Func func) { + enum { NeedToTranspose }; + typename conditional::type actualDst(dst); + CwiseBinaryOp, + const CwiseNullaryOp, + const Matrix>> + __trans_tmp_4 = src; + call_dense_assignment_loop(actualDst, __trans_tmp_4, func); +} +template +struct plain_array { + float array[Size]; +}; +template +class DenseStorage { + plain_array m_data; + + public: + DenseStorage() {} + DenseStorage(const DenseStorage&); + static long rows() { return _Rows; } + const float* data() const { return m_data.array; } + float* data() { return m_data.array; } +}; +template +class PlainObjectBase : public dense_xpr_base::type { + public: + typedef typename dense_xpr_base::type Base; + typedef typename traits::Scalar Scalar; + DenseStorage m_storage; + long rows() const { return m_storage.rows(); } + const Scalar* data() const { return m_storage.data(); } + PlainObjectBase() {} + template + PlainObjectBase(const DenseBase& other) { + _set_noalias(other); + } + template + void _set_noalias(const DenseBase& other) { + call_assignment_no_alias(this->derived(), other.derived(), assign_op()); + } +}; +template +struct traits> { + typedef _Scalar Scalar; + typedef int XprKind; + enum { + RowsAtCompileTime = _Rows, + ColsAtCompileTime, + MaxRowsAtCompileTime, + MaxColsAtCompileTime, + }; +}; +template +class Matrix + : public PlainObjectBase< + Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> { + public: + typedef PlainObjectBase Base; + typedef typename traits::Scalar Scalar; + Matrix(Scalar& x, Scalar& y, Scalar& z) { + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + } + template + Matrix(const EigenBase& other) : Base(other.derived()) {} + using Base::m_storage; +}; +template +struct traits> { + typedef typename traits::XprKind XprKind; + enum { RowsAtCompileTime }; + typedef float Scalar; +}; +template +class CwiseBinaryOpImpl; +template +class CwiseBinaryOp : public CwiseBinaryOpImpl { + public: + typedef ref_selector::type LhsNested; + typedef RhsType RhsNested; + CwiseBinaryOp(const Matrix& aLhs, RhsType& aRhs) + : m_lhs(aLhs), m_rhs(aRhs) {} + remove_reference::type& lhs() { return m_lhs; } + typename remove_reference::type& rhs() { return m_rhs; } + LhsNested m_lhs; + RhsNested m_rhs; +}; +template +class CwiseBinaryOpImpl + : public generic_xpr_base, + const CwiseNullaryOp, + const Matrix>>>::type {}; +template +struct traits> + : traits {}; +template +class CwiseNullaryOp + : public dense_xpr_base>::type { + public: + CwiseNullaryOp(long rows, long, scalar_constant_op func) + : m_functor(func) { + rows ? void() : __assert_fail("", "", 1, __PRETTY_FUNCTION__); + } + scalar_constant_op functor() { return m_functor; } + scalar_constant_op m_functor; +}; +} // namespace Eigen +Eigen::Matrix should_inline(float x, float y, float z, + float scale) { + return Eigen::Matrix(x, y, z) * scale; +} + +// We should inline everything to should_inline + +/* { dg-final { scan-tree-dump-times "Function" "optimized" } } */ -- cgit v1.1 From a40015780f8cc49476741b6914bd5ee97bd10f1d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 3 Apr 2021 10:08:08 +0200 Subject: bswap: Fix up bswap_view_convert after the recent change [PR99882] Martin reported that my recent change to allow pointer types in bswap broke valgrind. The bswap_view_convert function used for the initialization of vector CONSTRUCTOR from the identity or byte-swapped pieces unfortunately didn't handle pointer types. The following patch handles it there. 2021-04-03 Jakub Jelinek PR tree-optimization/99882 * gimple-ssa-store-merging.c (bswap_view_convert): Handle val with pointer type. * gcc.dg/pr99882.c: New test. --- gcc/testsuite/gcc.dg/pr99882.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr99882.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr99882.c b/gcc/testsuite/gcc.dg/pr99882.c new file mode 100644 index 0000000..ebc074f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99882.c @@ -0,0 +1,37 @@ +/* PR tree-optimization/99882 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +void +foo (char *p, void *q) +{ + __INTPTR_TYPE__ i = (__INTPTR_TYPE__) q; + p[2] = i; + i >>= 8; + p[3] = i; + i >>= 8; + p[4] = i; + i >>= 8; + p[5] = i; + i >>= 8; + p[6] = i; + i >>= 8; + p[7] = i; + i >>= 8; + p[8] = i; + i >>= 8; + p[9] = i; +} + +void +bar (char *p, void *q) +{ + __INTPTR_TYPE__ i = (__INTPTR_TYPE__) q; + p[2] = i; + i >>= 8; + p[3] = i; + i >>= 8; + p[4] = i; + i >>= 8; + p[5] = i; +} -- cgit v1.1 From 5bba3415ec251820ba0c9533aef1bef919dfbfdd Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Sat, 3 Apr 2021 19:54:37 -0300 Subject: silence expected psabi warning in ipa-sra-19 on ppc-vxworks The default CPU for our ppc-vx7r2 toolchain has no support for altivec or vsx, so an ABI without vector support is selected. The selected calling conventions do not cover passing or returning vector types, so -Wpsabi warns about such uses. powerpc-ibm-aix* already silences these warnings with -Wno-psabi; this patch extends that to powerpc-wrs-vxworks* too. for gcc/testsuite/ChangeLog * gcc.dg/ipa/ipa-sra-19.c: Extend -Wno-psabi to ppc-vx7r2. --- gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c index 8f3bb5d..c34c89e 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ /* { dg-additional-options "-msse2" { target ia32 } } */ -/* { dg-additional-options "-Wno-psabi" { target powerpc-ibm-aix* } } */ +/* { dg-additional-options "-Wno-psabi" { target powerpc-ibm-aix* powerpc-wrs-vxworks* } } */ typedef int __attribute__((__vector_size__(16))) vectype; -- cgit v1.1 From 3cb9e3aee98a206b786d7414ad28e67fbcceba5c Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Sun, 4 Apr 2021 17:55:46 -0700 Subject: Trivial testsuite fixes for nios2-elf. nios2-elf defaults to -fno-delete-null-pointer-checks, which causes failures in tests that assume the option is enabled. Make the dependence explicit. 2021-04-04 Sandra Loosemore gcc/testsuite/ * gcc.dg/ipa/propmalloc-4.c: Add -fdelete-null-pointer-checks. * gcc.dg/tree-ssa/evrp11.c: Likewise. --- gcc/testsuite/gcc.dg/ipa/propmalloc-4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/evrp11.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c b/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c index 4c40d63..9552b73 100644 --- a/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c +++ b/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-local-pure-const-details" } */ +/* { dg-options "-O2 -fdump-tree-local-pure-const-details -fdelete-null-pointer-checks" } */ void *foo(int cond1, int cond2, int cond3) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c index f1373bd..d791305 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp -fdelete-null-pointer-checks" } */ extern void link_error (); -- cgit v1.1 From 69b66ff02353a87585329bb3cf4ac20d6dee1b16 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 5 Apr 2021 10:48:01 -0400 Subject: analyzer: fix apparent hang with -fanalyzer-verbosity=0 [PR analyzer/99886] The analyzer appeared to enter an infinite loop on malloc-1.c when -fanalyzer-verbosity=0 was used. In fact, it was slowly counting from 0 to 0xffffffff. Root cause is looping up to effectively ((unsigned)0) - 1 in diagnostic_manager::consolidate_conditions when there are no events in the path. Fixed by the following, which uses signed integers when subtracting from path->num_events () when simplifying checker_paths. gcc/analyzer/ChangeLog: PR analyzer/99886 * diagnostic-manager.cc (diagnostic_manager::prune_interproc_events): Use signed integers when subtracting one from path->num_events (). (diagnostic_manager::consolidate_conditions): Likewise. Convert next_idx to a signed int. gcc/testsuite/ChangeLog: PR analyzer/99886 * gcc.dg/analyzer/pr99886.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr99886.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99886.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99886.c b/gcc/testsuite/gcc.dg/analyzer/pr99886.c new file mode 100644 index 0000000..da768ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99886.c @@ -0,0 +1,21 @@ +/* Regression test for hang with -fanalyzer-verbosity=0. */ +/* { dg-additional-options "-fanalyzer-verbosity=0" } */ + +#include + +struct coord { + float x; + float y; +}; + +void test_34 (void) +{ + float *q; + struct coord *p = malloc (sizeof (struct coord)); + if (!p) + return; + p->x = 0.0f; + q = &p->x; + free (p); + *q = 1.0f; /* { dg-warning "use after 'free' of 'q'" } */ +}; -- cgit v1.1 From 7d8f4240c94e2e7643ac13cda1fdd0bb6ca3a3fb Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 5 Apr 2021 10:51:46 -0400 Subject: analyzer: fix ICE on zero-arg calls passed to __attribute__((nonnull)) [PR 99906] gcc/analyzer/ChangeLog: PR analyzer/99906 * analyzer.cc (maybe_reconstruct_from_def_stmt): Fix NULL dereference on calls with zero arguments. * sm-malloc.cc (malloc_state_machine::on_stmt): When handling __attribute__((nonnull)), only call get_diagnostic_tree if the result will be used. gcc/testsuite/ChangeLog: PR analyzer/99906 * gcc.dg/analyzer/pr99906.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr99906.c | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99906.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99906.c b/gcc/testsuite/gcc.dg/analyzer/pr99906.c new file mode 100644 index 0000000..bb399a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99906.c @@ -0,0 +1,3 @@ +void bar(void *) __attribute__((__nonnull__)); +void *baz(void); +void foo(void) { bar(baz()); } -- cgit v1.1 From bfeb36bd03c2168af263daa13370a20a96c42b5d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 6 Apr 2021 12:44:51 +0200 Subject: testsuite: Fix up pr96573.c on aarch64 [PR96573] On Thu, Apr 01, 2021 at 02:16:55PM +0100, Alex Coplan via Gcc-patches wrote: > FYI, I'm seeing the new test failing on aarch64: > > PASS: gcc.dg/pr96573.c (test for excess errors) > FAIL: gcc.dg/pr96573.c scan-tree-dump optimized "__builtin_bswap" The vectorizer in the aarch64 case manages to emit a VEC_PERM_EXPR instead (which is just as efficient). So, do we want to go for the following (and/or perhaps also restrict the test to a couple of targets where it works? In my last distro build it failed only on aarch64-linux, while armv7hl-linux-gnueabi and {i686,x86_64,powerpc64le,s390x}-linux were fine)? 2021-04-06 Jakub Jelinek PR tree-optimization/96573 * gcc.dg/pr96573.c: Instead of __builtin_bswap accept also VEC_PERM_EXPR with bswapping permutation. --- gcc/testsuite/gcc.dg/pr96573.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr96573.c b/gcc/testsuite/gcc.dg/pr96573.c index 3acf117..63db69d 100644 --- a/gcc/testsuite/gcc.dg/pr96573.c +++ b/gcc/testsuite/gcc.dg/pr96573.c @@ -2,7 +2,7 @@ /* { dg-do compile { target { lp64 || ilp32 } } } */ /* { dg-require-effective-target bswap } */ /* { dg-options "-O3 -fdump-tree-optimized" } */ -/* { dg-final { scan-tree-dump "__builtin_bswap" "optimized" } } */ +/* { dg-final { scan-tree-dump "__builtin_bswap\|VEC_PERM_EXPR\[^\n\r]*7, 6, 5, 4, 3, 2, 1, 0" "optimized" } } */ typedef __SIZE_TYPE__ size_t; -- cgit v1.1 From e5c170e080399fb3d24a38bbfcd66bd4675abe53 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 6 Apr 2021 13:20:44 +0200 Subject: tree-optimization/99880 - avoid vectorizing irrelevant PHI backedge defs This adds a relevancy check before trying to set the vector def of a backedge in an unvectorized PHI. 2021-04-06 Richard Biener PR tree-optimization/99880 * tree-vect-loop.c (maybe_set_vectorized_backedge_value): Only set vectorized defs of relevant PHIs. * gcc.dg/torture/pr99880.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr99880.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr99880.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr99880.c b/gcc/testsuite/gcc.dg/torture/pr99880.c new file mode 100644 index 0000000..7e09899 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99880.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +unsigned a; +int b, c, d, e; +void f() { + b = 5; + for (; b <= 51; b++) + ; + unsigned int g = -8; + while (g) { + g += 5; + int h = 10; + do { + h -= a = 1; + for (; a; a++) + ; + c *= c >= d >= b; + } while (h); + c -= e; + } +} -- cgit v1.1 From d11bcbe166c03f722c0e0d41d6e87ac445758fba Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 7 Apr 2021 10:02:07 +0200 Subject: tree-optimization/99947 - avoid v.safe_push (v[0]) This avoids (again) the C++ pitfall of pushing a reference to sth being reallocated. 2021-04-07 Richard Biener PR tree-optimization/99947 * tree-vect-loop.c (vectorizable_induction): Pre-allocate steps vector to avoid pushing elements from the reallocated vector. * gcc.dg/torture/pr99947.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr99947.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr99947.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr99947.c b/gcc/testsuite/gcc.dg/torture/pr99947.c new file mode 100644 index 0000000..2cf3ec6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99947.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +int a, b, d, e; +short c; +void f() { + for (; e; e++) { + int g = 6; + for (; g > 2; g--) { + int i = -8; + while (i < 20) { + i += 5; + a += b; + } + c *= d; + } + b--; + } +} -- cgit v1.1 From c01ae2ab6b227e21835d128c90e974dce4604be9 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 7 Apr 2021 13:17:05 +0200 Subject: tree-optimization/99954 - fix loop distribution memcpy classification This fixes bogus classification of a copy as memcpy. We cannot use plain dependence analysis to decide between memcpy and memmove when it computes no dependence. Instead we have to try harder later which the patch does for the gcc.dg/tree-ssa/ldist-24.c testcase by resorting to tree-affine to compute the difference between src and dest and compare against the copy size. 2021-04-07 Richard Biener PR tree-optimization/99954 * tree-loop-distribution.c: Include tree-affine.h. (generate_memcpy_builtin): Try using tree-affine to prove non-overlap. (loop_distribution::classify_builtin_ldst): Always classify as PKIND_MEMMOVE. * gcc.dg/torture/pr99954.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr99954.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr99954.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr99954.c b/gcc/testsuite/gcc.dg/torture/pr99954.c new file mode 100644 index 0000000..7d44703 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99954.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +#include + +#define CONTAINER_KIND union + +typedef CONTAINER_KIND container { int value; } container; + +void move(container* end, container* start) { + container* p; + for (p = end; p > start; p--) { + (p)->value = (p-1)->value; + } +} + +#define N 100 + +int main(int argc, char* argv[]) { + container vals[N]; + int i; + for (i=0; i Date: Wed, 7 Apr 2021 15:21:55 +0100 Subject: vect: Don't split store groups if we have IFN_STORE_LANES [PR99873] As noted in the PR, we were no longer using ST3 for the testcase and instead stored each lane individually. This is because we'd split the store group during SLP and couldn't recover when SLP failed. However, we can also get better code with ST3 and ST4 even if SLP would have succeeded, such as for vect-complex-5.c. I'm not sure exactly where the cut-off point is, but it seems reasonable to allow the split if either of the new groups would operate on full vectors *within* rather than across scalar loop iterations. E.g. on a Cortex-A57, pr99873_3.c performs better using ST4 while pr99873_2.c performs better with SLP. Another factor is that SLP can handle smaller iteration counts than IFN_STORE_LANES can, but we don't have the infrastructure to choose reliably based on that. gcc/ PR tree-optimization/99873 * tree-vect-slp.c (vect_slp_prefer_store_lanes_p): New function. (vect_build_slp_instance): Don't split store groups that could use IFN_STORE_LANES. gcc/testsuite/ * gcc.dg/vect/slp-21.c: Only expect 2 of the loops to use SLP if IFN_STORE_LANES is available. * gcc.dg/vect/vect-complex-5.c: Expect no loops to use SLP if IFN_STORE_LANES is available. * gcc.target/aarch64/pr99873_1.c: New test. * gcc.target/aarch64/pr99873_2.c: Likewise. * gcc.target/aarch64/pr99873_3.c: Likewise. * gcc.target/aarch64/sve/pr99873_1.c: Likewise. * gcc.target/aarch64/sve/pr99873_2.c: Likewise. * gcc.target/aarch64/sve/pr99873_3.c: Likewise. --- gcc/testsuite/gcc.dg/vect/slp-21.c | 4 ++-- gcc/testsuite/gcc.dg/vect/vect-complex-5.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/slp-21.c b/gcc/testsuite/gcc.dg/vect/slp-21.c index bf8f434..8539397 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-21.c +++ b/gcc/testsuite/gcc.dg/vect/slp-21.c @@ -210,7 +210,7 @@ int main (void) Not all vect_perm targets support that, and it's a bit too specific to have its own effective-target selector, so we just test targets directly. */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { aarch64*-*-* arm*-*-* powerpc64*-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! { aarch64*-*-* arm*-*-* powerpc64*-*-* } } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target powerpc64*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! powerpc64*-*-* } } } } } */ /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { ! { vect_strided4 } } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-5.c b/gcc/testsuite/gcc.dg/vect/vect-complex-5.c index 81fdb67c..addcf60 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-complex-5.c +++ b/gcc/testsuite/gcc.dg/vect/vect-complex-5.c @@ -40,4 +40,5 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail { ! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { ! vect_load_lanes } xfail { ! vect_hw_misalign } } } } */ -- cgit v1.1 From 3a66c289a3f395e50de79424e1e6f401a4dc1ab7 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 8 Apr 2021 09:46:03 -0400 Subject: analyzer: fix leak false +ves due to maybe-clobbered regions [PR99042,PR99774] Prior to this patch, program_state::detect_leaks worked by finding all live svalues in the old state and in the new state, and calling on_svalue_leak for each svalue that has changed from being live to not being live. PR analyzer/99042 and PR analyzer/99774 both describe false leak diagnostics from -fanalyzer (a false FILE * leak in git, and a false malloc leak in qemu, respectively). In both cases the root cause of the false leak diagnostic relates to svalues no longer being explicitly bound in the store due to regions being conservatively clobbered, due to an unknown function being called, or due to a write through a pointer that could alias the region, respectively. We have a transition from an svalue being explicitly live to not being explicitly live - but only because the store is being conservative, clobbering the binding. The leak detection is looking for transitions from "definitely live" to "not definitely live", when it should be looking for transitions from "definitely live" to "definitely not live". This patch introduces a new class to temporarily capture information about svalues that were explicitly live, but for which a region bound to them got clobbered for conservative reasons. This new "uncertainty_t" class is passed around to capture the data long enough for use in program_state::detect_leaks, where it is used to only complain about svalues that were definitely live and are now both not definitely live *or* possibly-live i.e. definitely not-live. The class also captures for which svalues we can't meaningfully track sm-state anymore, and resets the svalues back to the "start" state. Together, these changes fix the false leak reports. gcc/analyzer/ChangeLog: PR analyzer/99042 PR analyzer/99774 * engine.cc (impl_region_model_context::impl_region_model_context): Add uncertainty param and use it to initialize m_uncertainty. (impl_region_model_context::get_uncertainty): New. (impl_sm_context::get_fndecl_for_call): Add NULL for new uncertainty param when constructing impl_region_model_context. (impl_sm_context::get_state): Likewise. (impl_sm_context::set_next_state): Likewise. (impl_sm_context::warn): Likewise. (exploded_node::on_stmt): Add uncertainty param and use it when constructing impl_region_model_context. (exploded_node::on_edge): Add uncertainty param and pass to on_edge call. (exploded_node::detect_leaks): Create uncertainty_t and pass to impl_region_model_context. (exploded_graph::get_or_create_node): Create uncertainty_t and pass to prune_for_point. (maybe_process_run_of_before_supernode_enodes): Create uncertainty_t and pass to impl_region_model_context. (exploded_graph::process_node): Create uncertainty_t instances and pass around as needed. * exploded-graph.h (impl_region_model_context::impl_region_model_context): Add uncertainty param. (impl_region_model_context::get_uncertainty): New decl. (impl_region_model_context::m_uncertainty): New field. (exploded_node::on_stmt): Add uncertainty param. (exploded_node::on_edge): Likewise. * program-state.cc (sm_state_map::on_liveness_change): Get uncertainty from context and use it to unset sm-state from svalues as appropriate. (program_state::on_edge): Add uncertainty param and use it when constructing impl_region_model_context. Fix indentation. (program_state::prune_for_point): Add uncertainty param and use it when constructing impl_region_model_context. (program_state::detect_leaks): Get any uncertainty from ctxt and use it to get maybe-live svalues for dest_state, rather than definitely-live ones; use this when determining which svalues have leaked. (selftest::test_program_state_merging): Create uncertainty_t and pass to impl_region_model_context. * program-state.h (program_state::on_edge): Add uncertainty param. (program_state::prune_for_point): Likewise. * region-model-impl-calls.cc (call_details::get_uncertainty): New. (region_model::impl_call_memcpy): Pass uncertainty to mark_region_as_unknown call. (region_model::impl_call_memset): Likewise. (region_model::impl_call_strcpy): Likewise. * region-model-reachability.cc (reachable_regions::handle_sval): Also add sval to m_mutable_svals. * region-model.cc (region_model::on_assignment): Pass any uncertainty from ctxt to the store::set_value call. (region_model::handle_unrecognized_call): Get any uncertainty from ctxt and use it to record mutable svalues at the unknown call. (region_model::get_reachable_svalues): Add uncertainty param and use it to mark any maybe-bound svalues as being reachable. (region_model::set_value): Pass any uncertainty from ctxt to the store::set_value call. (region_model::mark_region_as_unknown): Add uncertainty param and pass it on to the store::mark_region_as_unknown call. (region_model::update_for_call_summary): Add uncertainty param and pass it on to the region_model::mark_region_as_unknown call. * region-model.h (call_details::get_uncertainty): New decl. (region_model::get_reachable_svalues): Add uncertainty param. (region_model::mark_region_as_unknown): Add uncertainty param. (region_model_context::get_uncertainty): New vfunc. (noop_region_model_context::get_uncertainty): New vfunc implementation. * store.cc (dump_svalue_set): New. (uncertainty_t::dump_to_pp): New. (uncertainty_t::dump): New. (binding_cluster::clobber_region): Pass NULL for uncertainty to remove_overlapping_bindings. (binding_cluster::mark_region_as_unknown): Add uncertainty param and pass it to remove_overlapping_bindings. (binding_cluster::remove_overlapping_bindings): Add uncertainty param. Use it to record any svalues that were in clobbered bindings. (store::set_value): Add uncertainty param. Pass it to binding_cluster::mark_region_as_unknown when handling symbolic regions. (store::mark_region_as_unknown): Add uncertainty param and pass it to binding_cluster::mark_region_as_unknown. (store::remove_overlapping_bindings): Add uncertainty param and pass it to binding_cluster::remove_overlapping_bindings. * store.h (binding_cluster::mark_region_as_unknown): Add uncertainty param. (binding_cluster::remove_overlapping_bindings): Likewise. (store::set_value): Likewise. (store::mark_region_as_unknown): Likewise. gcc/testsuite/ChangeLog: PR analyzer/99042 PR analyzer/99774 * gcc.dg/analyzer/pr99042.c: New test. * gcc.dg/analyzer/pr99774-1.c: New test. * gcc.dg/analyzer/pr99774-2.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr99042.c | 53 +++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99774-1.c | 61 +++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr99774-2.c | 144 ++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99042.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99774-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99774-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99042.c b/gcc/testsuite/gcc.dg/analyzer/pr99042.c new file mode 100644 index 0000000..c3d124f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99042.c @@ -0,0 +1,53 @@ +#include + +struct foo { + FILE *file; +}; + +extern void unknown_fn (); +extern void unknown_fn2 (const struct foo *f); + +int test_1 (struct foo *p) +{ + if ((p->file = fopen("test.txt", "w")) == NULL) + return 1; + unknown_fn (); + return 0; /* { dg-bogus "leak" } */ +} + +int test_2 (struct foo *p) +{ + if ((p->file = fopen("test.txt", "w")) == NULL) + return 1; + return 0; /* { dg-bogus "leak" } */ +} + +int test_3 (void) +{ + struct foo f; + struct foo *p = &f; + if ((p->file = fopen("test.txt", "w")) == NULL) + return 1; + unknown_fn (); + return 0; /* { dg-warning "leak" } */ +} + +int test_4 (void) +{ + struct foo f; + struct foo *p = &f; + if ((p->file = fopen("test.txt", "w")) == NULL) + return 1; + return 0; /* { dg-warning "leak" } */ +} + +int test_5 (void) +{ + struct foo f; + struct foo *p = &f; + if ((p->file = fopen("test.txt", "w")) == NULL) + return 1; + /* Although p is const, the underlying FILE * is not and could be closed. */ + unknown_fn2 (p); + return 0; /* { dg-bogus "leak" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c new file mode 100644 index 0000000..620cf65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c @@ -0,0 +1,61 @@ +/* Reproducer for report from -Wanalyzer-malloc-leak + Reduced from + https://git.qemu.org/?p=qemu.git;a=blob;f=subprojects/libvhost-user/libvhost-user.c;h=fab7ca17ee1fb27bcfc338527d1aeb9f923aade5;hb=HEAD#l1184 + which is licensed under GNU GPLv2 or later. */ + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint64_t; +typedef unsigned long uint64_t; +typedef long unsigned int size_t; + +extern void *calloc(size_t __nmemb, size_t __size) + __attribute__((__nothrow__, __leaf__)) + __attribute__((__malloc__)) + __attribute__((__alloc_size__(1, 2))) + __attribute__((__warn_unused_result__)); + +typedef struct VuDescStateSplit { + uint8_t inflight; + uint64_t counter; +} VuDescStateSplit; + +typedef struct VuVirtqInflight { + uint16_t desc_num; + VuDescStateSplit desc[]; +} VuVirtqInflight; + +typedef struct VuVirtqInflightDesc { + uint16_t index; + uint64_t counter; +} VuVirtqInflightDesc; + +typedef struct VuVirtq { + VuVirtqInflight *inflight; + VuVirtqInflightDesc *resubmit_list; + uint16_t resubmit_num; + uint64_t counter; + int inuse; +} VuVirtq; + +int vu_check_queue_inflights(VuVirtq *vq) { + int i = 0; + + if (vq->inuse) { + vq->resubmit_list = calloc(vq->inuse, sizeof(VuVirtqInflightDesc)); + if (!vq->resubmit_list) { + return -1; + } + + for (i = 0; i < vq->inflight->desc_num; i++) { + if (vq->inflight->desc[i].inflight) { + vq->resubmit_list[vq->resubmit_num].index = i; /* { dg-bogus "leak" } */ + vq->resubmit_list[vq->resubmit_num].counter = + vq->inflight->desc[i].counter; + vq->resubmit_num++; + } + } + } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99774-2.c b/gcc/testsuite/gcc.dg/analyzer/pr99774-2.c new file mode 100644 index 0000000..d9704de --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr99774-2.c @@ -0,0 +1,144 @@ +#include + +struct st +{ + void *m_f; +}; + +struct node +{ + struct node *m_next; +}; + +extern void unknown_fn (void *); +extern void const_unknown_fn (const void *); + +void +test_1 (struct st *p, struct st *q) +{ + p->m_f = malloc (1024); + q->m_f = NULL; /* { dg-bogus "leak" } */ + free (p->m_f); +} + +void +test_2 (void) +{ + struct st s; + s.m_f = malloc (1024); + unknown_fn (&s); + free (s.m_f); +} + +void +test_3 (void) +{ + struct st s; + s.m_f = malloc (1024); + const_unknown_fn (&s); + free (s.m_f); +} + +void +test_4 (void) +{ + struct st s; + s.m_f = malloc (1024); + unknown_fn (&s); +} /* { dg-bogus "leak" } */ + +void +test_5 (void) +{ + struct st s; + s.m_f = malloc (1024); + /* s is const, but the pointer could still be freed; hence not a leak. */ + const_unknown_fn (&s); +} /* { dg-bogus "leak" } */ + +void +test_6 (void) +{ + struct st s; + s.m_f = malloc (1024); +} /* { dg-warning "leak" } */ + +struct st +test_7 (void) +{ + struct st s; + s.m_f = malloc (1024); + return s; +} /* { dg-bogus "leak" } */ + +struct node * +test_8 (void) +{ + struct node *n1 = malloc (sizeof (struct node)); + if (!n1) + return NULL; + n1->m_next = malloc (sizeof (struct node)); + return n1; +} + +void +test_9 (void) +{ + struct node *n1 = malloc (sizeof (struct node)); + if (!n1) + return; + n1->m_next = malloc (sizeof (struct node)); + /* Could free n1 and n1->m_next. */ + unknown_fn (n1); +} + +void +test_10 (void) +{ + struct node *n1 = malloc (sizeof (struct node)); + if (!n1) + return; + n1->m_next = malloc (sizeof (struct node)); + /* Could free n1->m_next, but not n1. */ + const_unknown_fn (n1); /* { dg-warning "leak of 'n1'" } */ +} + +void +test_11 (void) +{ + struct node *n1 = malloc (sizeof (struct node)); + if (!n1) + return; + n1->m_next = malloc (sizeof (struct node)); + /* Could free n1->m_next, but not n1. */ + unknown_fn (n1->m_next); /* { dg-warning "leak of 'n1'" } */ +} + +void +test_12a (void) +{ + int *ip = malloc (sizeof (int)); + *ip = 42; /* { dg-warning "dereference of possibly-NULL 'ip'" } */ + free (ip); +} + +void +test_12b (void) +{ + int *ip = malloc (sizeof (int)); + unknown_fn (ip); + /* Might not be a null-deref, as unknown_fn could abort on NULL. */ + *ip = 42; + free (ip); +} + +void +test_12c (void) +{ + int *ip = malloc (sizeof (int)); + /* Might not be a null-deref, as const_unknown_fn could abort on NULL. + Right now we don't have a great way of handling this. */ + const_unknown_fn (ip); + *ip = 42; /* { dg-bogus "dereference of possibly-NULL 'ip'" "" { xfail *-*-* } } */ + free (ip); +} -- cgit v1.1 From 860c5caf8cbb87055c02b1e77d04f658d2c75880 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 8 Apr 2021 15:00:05 +0100 Subject: testsuite: Fix gcc.dg/vect/pr99102.c pr99102.c needs to override the default options to exercise the original problem, but that means that it also needs to respecify the dump flags. gcc/testsuite/ * gcc.dg/vect/pr99102.c: Add -fdump-tree-vect-details. --- gcc/testsuite/gcc.dg/vect/pr99102.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr99102.c b/gcc/testsuite/gcc.dg/vect/pr99102.c index 62d4d33..6c1a13f 100644 --- a/gcc/testsuite/gcc.dg/vect/pr99102.c +++ b/gcc/testsuite/gcc.dg/vect/pr99102.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -ftree-vectorize" } */ +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */ /* { dg-additional-options "-msve-vector-bits=256" { target aarch64_sve256_hw } } */ long a[44]; short d, e = -7; -- cgit v1.1 From a708de07a1075b4707e640466b987fd724e823b7 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 9 Apr 2021 13:43:17 +0100 Subject: testsuite: Fix gcc.dg/vect/pr65947-7.c This test was failing on aarch64 targets because we inlined the test function into main, making it vectorisable. gcc/testsuite/ * gcc.dg/vect/pr65947-7.c: Add a noipa attribute. Expect the loop to vectorized if vect_fold_extract_last. --- gcc/testsuite/gcc.dg/vect/pr65947-7.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-7.c b/gcc/testsuite/gcc.dg/vect/pr65947-7.c index 287f57e..16cdcd1 100644 --- a/gcc/testsuite/gcc.dg/vect/pr65947-7.c +++ b/gcc/testsuite/gcc.dg/vect/pr65947-7.c @@ -9,7 +9,7 @@ extern void abort (void) __attribute__ ((noreturn)); /* Condition reduction with comparison is a different type to the data. Will fail to vectorize. */ -int +int __attribute__ ((noipa)) condition_reduction (short *a, int min_v, int *b) { int last = N + 65; @@ -52,4 +52,5 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" } } */ +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target vect_fold_extract_last } } } */ +/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! vect_fold_extract_last } } } } */ -- cgit v1.1 From 00138f9b2b96b61f49605fa261012a330b2668b1 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 9 Apr 2021 13:43:18 +0100 Subject: testsuite: Add some vect_variable_length XFAILs This patch adds XFAILs for some tests that fail with variable-length vectors. For pr96573.c I'd wondered about instead extending the regexp. The code we generate isn't very good though, so it doesn't seem worth matching. (Fixing the bad code is on the todo list.) gcc/testsuite/ * g++.dg/tree-ssa/pr83518.C: XFAIL for vect_variable_length. * gcc.dg/pr96573.c: Likewise. * gcc.dg/tree-ssa/pr84512.c: Likewise. * gcc.dg/vect/bb-slp-43.c: Likewise. * gcc.dg/vect/slp-reduc-11.c: Likewise. --- gcc/testsuite/gcc.dg/pr96573.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr84512.c | 2 +- gcc/testsuite/gcc.dg/vect/bb-slp-43.c | 2 +- gcc/testsuite/gcc.dg/vect/slp-reduc-11.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr96573.c b/gcc/testsuite/gcc.dg/pr96573.c index 63db69d..c7d8f9e 100644 --- a/gcc/testsuite/gcc.dg/pr96573.c +++ b/gcc/testsuite/gcc.dg/pr96573.c @@ -2,7 +2,7 @@ /* { dg-do compile { target { lp64 || ilp32 } } } */ /* { dg-require-effective-target bswap } */ /* { dg-options "-O3 -fdump-tree-optimized" } */ -/* { dg-final { scan-tree-dump "__builtin_bswap\|VEC_PERM_EXPR\[^\n\r]*7, 6, 5, 4, 3, 2, 1, 0" "optimized" } } */ +/* { dg-final { scan-tree-dump "__builtin_bswap\|VEC_PERM_EXPR\[^\n\r]*7, 6, 5, 4, 3, 2, 1, 0" "optimized" { xfail vect_variable_length } } } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c b/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c index 3c02701..496c78b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c @@ -13,4 +13,4 @@ int foo() } /* Listed targets xfailed due to PR84958. */ -/* { dg-final { scan-tree-dump "return 285;" "optimized" { xfail { amdgcn*-*-* } } } } */ +/* { dg-final { scan-tree-dump "return 285;" "optimized" { xfail { amdgcn*-*-* || vect_variable_length } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-43.c b/gcc/testsuite/gcc.dg/vect/bb-slp-43.c index 40bd2e0..a65d951 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-43.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-43.c @@ -14,4 +14,4 @@ f (int *restrict x, short *restrict y) } /* { dg-final { scan-tree-dump-not "mixed mask and nonmask" "slp2" } } */ -/* { dg-final { scan-tree-dump-not "vector operands from scalars" "slp2" { target { { vect_int && vect_bool_cmp } && { vect_unpack && vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-not "vector operands from scalars" "slp2" { target { { vect_int && vect_bool_cmp } && { vect_unpack && vect_hw_misalign } } xfail vect_variable_length } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-11.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-11.c index a2f86fb..260d65c 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-reduc-11.c +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-11.c @@ -16,5 +16,5 @@ double dotprod(const double *a, const double *b, unsigned long long n) /* We should use a SLP reduction even without -ffast-math by using a VF of one. */ -/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */ /* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */ -- cgit v1.1 From 7a493fcd27d6a1af896c4f5ef4ab1e0afe8a839d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 10 Apr 2021 12:46:09 +0200 Subject: rtlanal: Another fix for VOIDmode MEMs [PR98601] This is a sequel to the PR85022 changes, inline-asm can (unfortunately) introduce VOIDmode MEMs and in PR85022 they have been changed so that we don't pretend we know their size (as opposed to assuming they have zero size). This time we ICE in rtx_addr_can_trap_p_1 because it assumes that all memory but BLKmode has known size. The patch just treats VOIDmode MEMs like BLKmode in that regard. And, the STRICT_ALIGNMENT change is needed because VOIDmode has GET_MODE_SIZE of 0 and we don't want to check if something is a multiple of 0. 2021-04-10 Jakub Jelinek PR rtl-optimization/98601 * rtlanal.c (rtx_addr_can_trap_p_1): Allow in assert unknown size not just for BLKmode, but also for VOIDmode. For STRICT_ALIGNMENT unaligned_mems handle VOIDmode like BLKmode. * gcc.dg/torture/pr98601.c: New test. --- gcc/testsuite/gcc.dg/torture/pr98601.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr98601.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr98601.c b/gcc/testsuite/gcc.dg/torture/pr98601.c new file mode 100644 index 0000000..ee9d076 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr98601.c @@ -0,0 +1,14 @@ +/* PR rtl-optimization/98601 */ +/* { dg-do compile } */ + +void +foo (void *p) +{ + asm ("" : "=m" (*p)); /* { dg-warning "dereferencing 'void \\*' pointer" } */ +} + +void +bar (void *p) +{ + asm volatile ("" : : "m" (*p)); /* { dg-warning "dereferencing 'void \\*' pointer" } */ +} -- cgit v1.1 From 22aede7a1228617661105048a91fddd8797e141b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 10 Apr 2021 12:49:01 +0200 Subject: expand: Fix up LTO ICE with COMPOUND_LITERAL_EXPR [PR99849] The gimplifier optimizes away COMPOUND_LITERAL_EXPRs, but they can remain in the form of ADDR_EXPR of COMPOUND_LITERAL_EXPRs in static initializers. By the TREE_STATIC check I meant to check that the underlying decl of the compound literal is a global rather than automatic variable which obviously can't be referenced in static initializers, but unfortunately with LTO it might end up in another partition and thus be DECL_EXTERNAL instead. 2021-04-10 Jakub Jelinek PR lto/99849 * expr.c (expand_expr_addr_expr_1): Test is_global_var rather than just TREE_STATIC on COMPOUND_LITERAL_EXPR_DECLs. * gcc.dg/lto/pr99849_0.c: New test. --- gcc/testsuite/gcc.dg/lto/pr99849_0.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/lto/pr99849_0.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/lto/pr99849_0.c b/gcc/testsuite/gcc.dg/lto/pr99849_0.c new file mode 100644 index 0000000..d489cee --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr99849_0.c @@ -0,0 +1,23 @@ +/* PR lto/99849 */ +/* { dg-lto-do link } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target shared } */ +/* { dg-extra-ld-options { -shared } } */ +/* { dg-lto-options { { -flto -flto-partition=1to1 -O2 -Wno-incompatible-pointer-types -Wno-discarded-qualifiers -fPIC } } } */ + +struct { struct A *a; } *b; +struct B { int *b; }; +struct C { int *c; }; +const struct D { struct C d; } d; +struct A { struct { struct C e; }; }; +struct E { void *e; } e = { &( &(const struct D) { (void *) &d })->d }; +struct C f = { &( &(const struct D) { (void *) &d })->d }; +struct A g[] = { &e, &f }; +void foo () { b->a = g; } +struct E h = { foo }; +void bar (); +int baz () { bar (h); } +struct B i = { (int *) baz }; +void qux (); +void corge () { qux (i); } +void *j __attribute__((__used__)) = corge; -- cgit v1.1 From 9f7d77bd6d65aa1cf2e195d3776052705c6e636b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 10 Apr 2021 17:01:54 +0200 Subject: c: Avoid clobbering TREE_TYPE (error_mark_node) [PR99990] The following testcase ICEs during error recovery, because finish_decl overwrites TREE_TYPE (error_mark_node), which better should stay always to be error_mark_node. 2021-04-10 Jakub Jelinek PR c/99990 * c-decl.c (finish_decl): Don't overwrite TREE_TYPE of error_mark_node. * gcc.dg/pr99990.c: New test. --- gcc/testsuite/gcc.dg/pr99990.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr99990.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr99990.c b/gcc/testsuite/gcc.dg/pr99990.c new file mode 100644 index 0000000..6878b00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99990.c @@ -0,0 +1,12 @@ +/* PR c/99990 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +#include + +void +foo () +{ + va_arg (0, long); /* { dg-error "first argument to 'va_arg' not of type 'va_list'" } */ + void *b[] = 0; /* { dg-error "invalid initializer" } */ +} -- cgit v1.1 From ec633d3777bd71f7bde5e671b61ec18e5b7b43ea Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Sat, 10 Apr 2021 16:23:23 -0400 Subject: analyzer: fix ICE on assignment from STRING_CST when building path [PR100011] gcc/analyzer/ChangeLog: PR analyzer/100011 * region-model.cc (region_model::on_assignment): Avoid NULL dereference if ctxt is NULL when assigning from a STRING_CST. gcc/testsuite/ChangeLog: PR analyzer/100011 * gcc.dg/analyzer/pr100011.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr100011.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr100011.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr100011.c b/gcc/testsuite/gcc.dg/analyzer/pr100011.c new file mode 100644 index 0000000..228cfdf --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr100011.c @@ -0,0 +1,16 @@ +/* { dg-require-effective-target signal } */ + +#include +#include + +void terminate(int sig) +{ + char buf[64] = { 0 }; + exit(1); /* { dg-warning "call to 'exit' from within signal handler" } */ +} + +int main(int argc, char **argv) +{ + signal(0, terminate); /* { dg-message "registering 'terminate' as signal handler" } */ + return 0; +} -- cgit v1.1 From 9c1c8ad8339d551ac91a7af5614f29b9a687189a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 13 Apr 2021 01:00:48 +0200 Subject: combine: Don't fold away side-effects in simplify_and_const_int_1 [PR99830] Here is an alternate patch for the PR99830 bug. As discussed on IRC and in the PR, the reason why a (clobber:TI (const_int 0)) has been propagated into the debug insns is that it got optimized away during simplification from the i3 instruction pattern. And that happened because simplify_and_const_int_1 (SImode, varop, 255) with varop of (ashift:SI (subreg:SI (and:TI (clobber:TI (const_int 0 [0])) (const_int 255 [0xff])) 0) (const_int 16 [0x10])) was called and through nonzero_bits determined that (whatever << 16) & 255 is const0_rtx. It is, but if there are side-effects in varop and such clobbers are considered as such, we shouldn't optimize those away. 2021-04-13 Jakub Jelinek PR debug/99830 * combine.c (simplify_and_const_int_1): Don't optimize varop away if it has side-effects. * gcc.dg/pr99830.c: New test. --- gcc/testsuite/gcc.dg/pr99830.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr99830.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr99830.c b/gcc/testsuite/gcc.dg/pr99830.c new file mode 100644 index 0000000..75226f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99830.c @@ -0,0 +1,10 @@ +/* PR debug/99830 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fno-expensive-optimizations -fno-split-wide-types -g" } */ + +int foo (long a, __int128 b, short c, int d, unsigned e, __int128 f) +{ + __builtin_memmove (2 + (char *) &f, foo, 1); + c >>= (char) f; + return c; +} -- cgit v1.1 From 17f3c2b8ac477b07ca0aafbc7d74ba305dc1ee33 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 12 Apr 2021 21:13:40 -0400 Subject: gimple UIDs, LTO and -fanalyzer [PR98599] gimple.h has this comment for gimple's uid field: /* UID of this statement. This is used by passes that want to assign IDs to statements. It must be assigned and used by each pass. By default it should be assumed to contain garbage. */ unsigned uid; and gimple_set_uid has: Please note that this UID property is supposed to be undefined at pass boundaries. This means that a given pass should not assume it contains any useful value when the pass starts and thus can set it to any value it sees fit. which suggests that any pass can use the uid field as an arbitrary scratch space. PR analyzer/98599 reports a case where this error occurs in LTO mode: fatal error: Cgraph edge statement index out of range on certain inputs with -fanalyzer. The error occurs in the LTRANS phase after -fanalyzer runs in the WPA phase. The analyzer pass writes to the uid fields of all stmts. The error occurs when LTRANS is streaming callgraph edges back in. The LTO format uses stmt uids to associate call stmts with callgraph edges between WPA and LTRANS. For example, in lto-cgraph.c, lto_output_edge writes out the gimple_uid, and input_edge reads it back in. lto_prepare_function_for_streaming has code to renumber the stmt UIDs when the code is streamed back out, but for some reason this isn't called for clones: 307 /* Do body modifications needed for streaming before we fork out 308 worker processes. */ 309 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 310 if (!node->clone_of && gimple_has_body_p (node->decl)) 311 lto_prepare_function_for_streaming (node); Hence the combination of -fanalyzer and -flto will fail in LTRANS's stream-in if any function clones are encountered. It's not fully clear to me why this isn't done for clones, and what the correct fix should be to allow arbitrary changes to uids within WPA passes. In the meantime, this patch works around the issue by updating the analyzer to save and restore the UIDs, fixing the error. gcc/analyzer/ChangeLog: PR analyzer/98599 * supergraph.cc (saved_uids::make_uid_unique): New. (saved_uids::restore_uids): New. (supergraph::supergraph): Replace assignments to stmt->uid with calls to m_stmt_uids.make_uid_unique. (supergraph::~supergraph): New. * supergraph.h (class saved_uids): New. (supergraph::~supergraph): New decl. (supergraph::m_stmt_uids): New field. gcc/testsuite/ChangeLog: PR analyzer/98599 * gcc.dg/analyzer/pr98599-a.c: New test. * gcc.dg/analyzer/pr98599-b.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr98599-a.c | 8 ++++++++ gcc/testsuite/gcc.dg/analyzer/pr98599-b.c | 1 + 2 files changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr98599-a.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr98599-b.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98599-a.c b/gcc/testsuite/gcc.dg/analyzer/pr98599-a.c new file mode 100644 index 0000000..2bbf37b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr98599-a.c @@ -0,0 +1,8 @@ +/* { dg-do link } */ +/* { dg-require-effective-target lto } */ +/* { dg-additional-options "-Os -flto" } */ +/* { dg-additional-sources pr98599-b.c } */ + +int b(int x); +int a() { b(5); } +int main() { a(); } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98599-b.c b/gcc/testsuite/gcc.dg/analyzer/pr98599-b.c new file mode 100644 index 0000000..cfdeb3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr98599-b.c @@ -0,0 +1 @@ +int b(int x) { return x; } -- cgit v1.1 From 07b27384de56ce2f6a93007d018743ef9d5c8cc4 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Tue, 13 Apr 2021 04:08:08 +0200 Subject: gcc.dg/analyzer/data-model-1.c: Inverse xfail for cris-*-*, PR99212 See PR99212. Now, cris-elf isn't the only target for which this line shows a failure; pru-unknown-elf and m68k-unknown-linux-gnu are two others. I'll leave adjustments to the respective maintainers, but trivially appending more triplets should work: no extra bracketing needed. A specific effective_target specifier would as always be perferable, but I couldn't without accountable effort find out what was the common factor. Besides cris-elf, sanity-checked for native x86_64-*-linux*. gcc/testsuite: PR analyzer/99212 * gcc.dg/analyzer/data-model-1.c (test_45): Inverse xfail at line 971 for cris-*-*. --- gcc/testsuite/gcc.dg/analyzer/data-model-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index afd1556..c0f5463 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -968,8 +968,8 @@ void test_45 (void) { struct ubits bits; bits.b0 = 1; - __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ + __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" "desired, PR99212" { xfail { ! { cris-*-* } } } } */ + /* { dg-warning "UNKNOWN" "status quo, PR99212" { target { *-*-* } xfail { cris-*-* } } .-1 } */ // TODO(xfail): ^^^^ bits.b456 = 5; -- cgit v1.1 From f9810422f6768b914aabfcbffe64f535bdd18452 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 13 Apr 2021 12:05:53 +0200 Subject: tree-optimization/100053 - fix predication in VN This avoids doing optimistic dominance queries involving non-executable backedges when validating recorded predicated values in VN because we have no way to force re-evaluating validity when optimistically not executable edges become executable later. 2021-04-13 Richard Biener PR tree-optimization/100053 * tree-ssa-sccvn.c (vn_nary_op_get_predicated_value): Do not use optimistic dominance queries for backedges to validate predicated values. (dominated_by_p_w_unex): Add parameter to ignore executable state on backedges. (rpo_elim::eliminate_avail): Adjust. * gcc.dg/torture/pr100053.c: New testcase. * gcc.dg/tree-ssa/ssa-fre-93.c: Likewise. --- gcc/testsuite/gcc.dg/torture/pr100053.c | 25 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c | 21 +++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100053.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100053.c b/gcc/testsuite/gcc.dg/torture/pr100053.c new file mode 100644 index 0000000..3d17675 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100053.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +int __attribute__((returns_twice,noipa)) x() { return 0; } +void __attribute__((noipa)) ar() {} +void __attribute__((noipa)) as() { __builtin_abort (); } +int a1, a2, a3; +void __attribute__((noipa)) v(int init) +{ + if (!init) { + as(); + if (a1) + goto aq; + x (); + } + ar(); +aq: + if (!init) + as(); +} + +int main() +{ + v(1); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c new file mode 100644 index 0000000..7f66b7e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1" } */ + +void bar (); +void foo (int pred, int *other) +{ + *other = 0; + if (*other) + goto cnt; + if (pred) + { + *other = 1; +cnt: + if (!pred) + bar (); + } +} + +/* The first VN pass should figure that if (!pred) is false because + if (*other) is and thus the predicate test is redundant. */ +/* { dg-final { scan-tree-dump-not "bar" "fre1" } } */ -- cgit v1.1 From 8084ab15a3e300e3b2c537e56e0f3a1b00778aec Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 13 Apr 2021 13:46:21 -0600 Subject: PR middle-end/86058 - TARGET_MEM_REF causing incorrect message for -Wmaybe-uninitialized warning gcc/testsuite/ChangeLog: PR middle-end/86058 * gcc.dg/pr86058.c: New test. --- gcc/testsuite/gcc.dg/pr86058.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr86058.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr86058.c b/gcc/testsuite/gcc.dg/pr86058.c new file mode 100644 index 0000000..0b030b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr86058.c @@ -0,0 +1,18 @@ +/* PR middle-end/86058 - TARGET_MEM_REF causing incorrect message for + -Wmaybe-uninitialized warning + { dg-do compile } + { dg-options "-O2 -Wuninitialized -Wmaybe-uninitialized" } */ + +extern void foo (int *); + +void zip (int *out, int indx) +{ + int arr[10]; + + for (int i = 0; i < indx; ++i) + out[i] = arr[i] + 1; // { dg-warning "'arr\\\[i]' may be used uninitialized" "pr?????" { xfail *-*-* } } + // { dg-warning "'arr' may be used uninitialized" "actual" { target *-*-* } .-1 } + + foo (arr); + foo (out); +} -- cgit v1.1 From 785209fc464ee3efec2b2a8e8244b7292c251ad8 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 14 Apr 2021 10:43:22 -0600 Subject: PR testsuite/100073 - test case gcc.dg/pr86058.c fails on arm, powerpc64 gcc/testsuite/ChangeLog: * gcc.dg/pr86058.c: Limit to just x86_64. --- gcc/testsuite/gcc.dg/pr86058.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr86058.c b/gcc/testsuite/gcc.dg/pr86058.c index 0b030b0..e39b720 100644 --- a/gcc/testsuite/gcc.dg/pr86058.c +++ b/gcc/testsuite/gcc.dg/pr86058.c @@ -1,8 +1,9 @@ /* PR middle-end/86058 - TARGET_MEM_REF causing incorrect message for -Wmaybe-uninitialized warning - { dg-do compile } + The test fails on a number of non-x86_64 targets due to pr100073. + { dg-do compile { target x86_64-*-* } } { dg-options "-O2 -Wuninitialized -Wmaybe-uninitialized" } */ - + extern void foo (int *); void zip (int *out, int indx) @@ -10,9 +11,9 @@ void zip (int *out, int indx) int arr[10]; for (int i = 0; i < indx; ++i) - out[i] = arr[i] + 1; // { dg-warning "'arr\\\[i]' may be used uninitialized" "pr?????" { xfail *-*-* } } + out[i] = arr[i] + 1; // { dg-warning "'arr\\\[i]' may be used uninitialized" "pr99944" { xfail *-*-* } } // { dg-warning "'arr' may be used uninitialized" "actual" { target *-*-* } .-1 } - + foo (arr); foo (out); } -- cgit v1.1 From 417c36cfd620bf2b047852c2aa9ac49004aed2bc Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Thu, 15 Apr 2021 08:03:47 +0200 Subject: re PR tree-optimization/93210 (Sub-optimal code optimization on struct/combound constexpr (gcc vs. clang)) Regarding test gcc.dg/pr93210.c, on different targets GIMPLE code may slightly differ which is why the scan-tree-dump-times directive may fail. For example, for a RETURN_EXPR on x86_64 we have return 0x11100f0e0d0c0a090807060504030201; whereas on IBM Z the first operand is a RESULT_DECL like = 0x102030405060708090a0c0d0e0f1011; return ; gcc/testsuite/ChangeLog: * gcc.dg/pr93210.c: Adapt regex in order to also support a RESULT_DECL as an operand for a RETURN_EXPR. --- gcc/testsuite/gcc.dg/pr93210.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr93210.c b/gcc/testsuite/gcc.dg/pr93210.c index ec4194b..134d32b 100644 --- a/gcc/testsuite/gcc.dg/pr93210.c +++ b/gcc/testsuite/gcc.dg/pr93210.c @@ -1,7 +1,7 @@ /* PR tree-optimization/93210 */ /* { dg-do run } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ -/* { dg-final { scan-tree-dump-times "return \[0-9]\[0-9a-fA-FxX]*;" 31 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "(?:return| =) \[0-9]\[0-9a-fA-FxX]*;" 31 "optimized" } } */ #ifdef __SIZEOF_INT128__ typedef unsigned __int128 L; -- cgit v1.1 From 4d1fa72894e3fbc5f331d2e8984e990307396124 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 15 Apr 2021 14:08:03 +0200 Subject: testsuite: enable pr86058.c also on i?86-*-* [PR100073] The test also works with -m32 or -mx32 the same as it does for -m64, therefore it should be enabled for i?86-*-* x86_64-*-* targets, x86_64-*-* alone is never right. 2021-04-15 Jakub Jelinek PR testsuite/100073 * gcc.dg/pr86058.c: Enable also on i?86-*-*. --- gcc/testsuite/gcc.dg/pr86058.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr86058.c b/gcc/testsuite/gcc.dg/pr86058.c index e39b720..89628c9 100644 --- a/gcc/testsuite/gcc.dg/pr86058.c +++ b/gcc/testsuite/gcc.dg/pr86058.c @@ -1,7 +1,7 @@ /* PR middle-end/86058 - TARGET_MEM_REF causing incorrect message for -Wmaybe-uninitialized warning - The test fails on a number of non-x86_64 targets due to pr100073. - { dg-do compile { target x86_64-*-* } } + The test fails on a number of non-x86 targets due to pr100073. + { dg-do compile { target i?86-*-* x86_64-*-* } } { dg-options "-O2 -Wuninitialized -Wmaybe-uninitialized" } */ extern void foo (int *); -- cgit v1.1 From 2dbbbe893f75f587c48111ab4c97cf5e74fb91bb Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 15 Apr 2021 14:09:56 -0600 Subject: PR middle-end/89230 - Bogus uninited usage warning with printf gcc/testsuite/ChangeLog: * gcc.dg/uninit-pr89230-1.c: New test. * gcc.dg/uninit-pr89230-2.c: Same. --- gcc/testsuite/gcc.dg/uninit-pr89230-1.c | 25 +++++++++++++++ gcc/testsuite/gcc.dg/uninit-pr89230-2.c | 54 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr89230-1.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pr89230-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr89230-1.c b/gcc/testsuite/gcc.dg/uninit-pr89230-1.c new file mode 100644 index 0000000..1c07c4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr89230-1.c @@ -0,0 +1,25 @@ +/* PR middle-end/89230 - Bogus uninited usage warning with printf + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct S { int i, j; }; + +/* attribute__ ((malloc)) */ struct S* f (void); + +int g (void) +{ + struct S *p = f (), *q; + + if (p->i || !(q = f ()) || p->j != q->i) + { + __builtin_printf ("%i", p->i); + + if (p->i) + return 1; + + if (!q) // { dg-bogus "\\\[-Wmaybe-uninitialized" } + return 2; + } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr89230-2.c b/gcc/testsuite/gcc.dg/uninit-pr89230-2.c new file mode 100644 index 0000000..473d2da --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr89230-2.c @@ -0,0 +1,54 @@ +/* PR middle-end/89230 - Bogus uninited usage warning with printf + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void* memset (void*, int, size_t); +extern int printf (const char*, ...); +extern int rand (void); + +struct S +{ + int a; + int b; +}; + +struct H +{ + int c; + int d; +}; + +void getblk (void* blk) +{ + struct S* s = (struct S*) blk; + memset (blk, 0, 512); + s->a = rand () & 1; +} + +struct H* gethdr (void* blk) +{ + memset (blk, 0, 512); + return rand () & 1 ? (struct H*) blk : 0; +} + +int main (void) +{ + char blk[512], tmp[512]; + struct S *s = (struct S*) blk; + struct H *h; + + getblk (blk); + + if (s->a || !(h = gethdr (tmp)) || s->a != h->d) { + + printf ("%d\n", s->b); + if (s->a) + printf ("s->a = %d\n", s->a); + else if (!h) + printf ("!h\n"); + else + printf ("h->d = %d\n", h->d); + } +} -- cgit v1.1 From 58fe131b91007793c0f12f5fe6cab3f1a017d0fa Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Thu, 15 Apr 2021 21:51:08 +0200 Subject: gcc.dg/pr84877.c: Xfail for cris-*-* Unfortunately it appears that this PR is on nobody's radar. Xfailing it to get an arguably artificial zero regression state (since T0=2007-01-05) helps my autotester. Caveat: the pass/fail state of this test, as long as stack alignment isn't adjusted, is dependent on the alignment of the stack at the entry of main, so depending on the target, e.g. the size and number of environment variables at invocation time can affect the result (including simulator runs where environment variables are propagated to the target). gcc/testsuite: PR middle-end/84877 * gcc.dg/pr84877.c: Xfail for cris-*-*. --- gcc/testsuite/gcc.dg/pr84877.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr84877.c b/gcc/testsuite/gcc.dg/pr84877.c index 8a34dd4..8551d27 100644 --- a/gcc/testsuite/gcc.dg/pr84877.c +++ b/gcc/testsuite/gcc.dg/pr84877.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do run { xfail { cris-*-* } } } */ /* { dg-options "-O2" } */ #include -- cgit v1.1 From da879e01ecd35737c18be1da3324f4560aba1961 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 15 Apr 2021 15:49:30 -0600 Subject: Propagate type attribute when merging extern declarations at local scope. Resolves: PR c/99420 - bogus -Warray-parameter on a function redeclaration in function scope PR c/99972 - missing -Wunused-result on a call to a locally redeclared warn_unused_result function gcc/c/ChangeLog: PR c/99420 PR c/99972 * c-decl.c (pushdecl): Always propagate type attribute. gcc/testsuite/ChangeLog: PR c/99420 PR c/99972 * gcc.dg/Warray-parameter-9.c: New test. * gcc.dg/Wnonnull-6.c: New test. * gcc.dg/Wreturn-type3.c: New test. * gcc.dg/Wunused-result.c: New test. * gcc.dg/attr-noreturn.c: New test. * gcc.dg/attr-returns-nonnull.c: New test. --- gcc/testsuite/gcc.dg/Warray-parameter-9.c | 54 +++++++++++++++++ gcc/testsuite/gcc.dg/Wnonnull-6.c | 93 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/Wreturn-type3.c | 54 +++++++++++++++++ gcc/testsuite/gcc.dg/Wunused-result.c | 50 ++++++++++++++++ gcc/testsuite/gcc.dg/attr-noreturn.c | 64 ++++++++++++++++++++ gcc/testsuite/gcc.dg/attr-returns-nonnull.c | 58 ++++++++++++++++++ 6 files changed, 373 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-9.c create mode 100644 gcc/testsuite/gcc.dg/Wnonnull-6.c create mode 100644 gcc/testsuite/gcc.dg/Wreturn-type3.c create mode 100644 gcc/testsuite/gcc.dg/Wunused-result.c create mode 100644 gcc/testsuite/gcc.dg/attr-noreturn.c create mode 100644 gcc/testsuite/gcc.dg/attr-returns-nonnull.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-9.c b/gcc/testsuite/gcc.dg/Warray-parameter-9.c new file mode 100644 index 0000000..b5d3d96 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-parameter-9.c @@ -0,0 +1,54 @@ +/* PR c/99420 - bogus -Warray-parameter on a function redeclaration + in function scope + { dg-do compile } + { dg-options "-Wall" } */ + +extern int a1[1], a2[2], a3[3], a4[4]; + +void fa1 (int [1]); // { dg-message "previously declared as 'int\\\[1]'" } +void fa1 (int [1]); + + +void nested_decl (void) +{ + void fa2 (int [2]); + + fa2 (a1); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } + fa2 (a2); + fa2 (a3); + + void fa3 (int [3]); + + fa3 (a2); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } + fa3 (a3); +} + + +void nested_redecl (void) +{ + void fa1 (int [2]); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" } + + fa1 (a1 + 1); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } + fa1 (a1); + + void fa2 (int [2]); // { dg-bogus "\\\[-Warray-parameter" } + + fa2 (a1); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } + fa2 (a2); + fa2 (a3); + + void fa3 (int [3]); // { dg-bogus "\\\[-Warray-parameter" } + + fa3 (a2); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } + fa3 (a3); + + void fa4 (int [4]); +} + +void fa4 (int [5]); // { dg-warning "\\\[-Warray-parameter" } + +void call_fa4 (void) +{ + fa4 (a4); + fa4 (a3); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } +} diff --git a/gcc/testsuite/gcc.dg/Wnonnull-6.c b/gcc/testsuite/gcc.dg/Wnonnull-6.c new file mode 100644 index 0000000..48f09da --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wnonnull-6.c @@ -0,0 +1,93 @@ +/* Verify that attribute nonnull on global and local function declarations + or those to pointers to functions is merged. + { dg-do compile } + { dg-options "-Wall" } */ + +void fnonnull_local_local (void) +{ + extern __attribute__ ((nonnull)) void fnonnull1 (void*); + + fnonnull1 (0); // { dg-warning "\\\[-Wnonnull" } +} + +void gnonnull_local_local (void) +{ + extern void fnonnull1 (void*); + + fnonnull1 (0); // { dg-warning "\\\[-Wnonnull" } +} + + +void fnonnull_local_global (void) +{ + extern __attribute__ ((nonnull)) void fnonnull2 (void*); + + fnonnull2 (0); // { dg-warning "\\\[-Wnonnull" } +} + +extern void fnonnull2 (void*); + +void gnonnull_local_global (void) +{ + fnonnull2 (0); // { dg-warning "\\\[-Wnonnull" } +} + + +extern __attribute__ ((nonnull)) void fnonnull3 (void*); + +void fnonnull_global_local (void) +{ + fnonnull3 (0); // { dg-warning "\\\[-Wnonnull" } +} + +void gnonnull_global_local (void) +{ + extern void fnonnull3 (void*); + + fnonnull3 (0); // { dg-warning "\\\[-Wnonnull" } +} + + +void pfnonnull_local_local (void) +{ + extern __attribute__ ((nonnull)) void (*pfnonnull1) (void*); + + pfnonnull1 (0); // { dg-warning "\\\[-Wnonnull" } +} + +void gpnonnull_local_local (void) +{ + extern void (*pfnonnull1) (void*); + + pfnonnull1 (0); // { dg-warning "\\\[-Wnonnull" "pr?????" { xfail *-*-* } } +} + + +void pfnonnull_local_global (void) +{ + extern __attribute__ ((nonnull)) void (*pfnonnull2) (void*); + + pfnonnull2 (0); // { dg-warning "\\\[-Wnonnull" } +} + +extern void (*pfnonnull2) (void*); + +void gpnonnull_local_global (void) +{ + pfnonnull2 (0); // { dg-warning "\\\[-Wnonnull" "pr?????" { xfail *-*-* } } +} + + +extern __attribute__ ((nonnull)) void (*pfnonnull3) (void*); + +void pfnonnull_global_local (void) +{ + pfnonnull3 (0); // { dg-warning "\\\[-Wnonnull" } +} + +void gpnonnull_global_local (void) +{ + extern void (*pfnonnull3) (void*); + + pfnonnull3 (0); // { dg-warning "\\\[-Wnonnull" } +} diff --git a/gcc/testsuite/gcc.dg/Wreturn-type3.c b/gcc/testsuite/gcc.dg/Wreturn-type3.c new file mode 100644 index 0000000..93596b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wreturn-type3.c @@ -0,0 +1,54 @@ +/* Verify that attribute noreturn on global and local function declarations + is merged. + { dg-do compile } + { dg-options "-Wall" } */ + +int fnr_local_local (void) +{ + __attribute__ ((noreturn)) void fnr1 (void); + + fnr1 (); + // no return, no warning (good) +} + +int gnr_local_local (void) +{ + void fnr1 (void); + + fnr1 (); + // no return, no warning (good) +} + + +int fnr_local_global (void) +{ + __attribute__ ((noreturn)) void fnr2 (void); + + fnr2 (); + // no return, no warning (good) +} + +void fnr2 (void); + +int gnr_local_global (void) +{ + fnr2 (); + // no return, no warning (good) +} + + +__attribute__ ((noreturn)) void fnr3 (void); + +int fnr_global_local (void) +{ + fnr3 (); + // no return, no warning (good) +} + +int gnr_global_local (void) +{ + void fnr3 (void); + + fnr3 (); + // no return, no warning (good) +} diff --git a/gcc/testsuite/gcc.dg/Wunused-result.c b/gcc/testsuite/gcc.dg/Wunused-result.c new file mode 100644 index 0000000..c0bb9ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wunused-result.c @@ -0,0 +1,50 @@ +/* PR c/99972 - missing -Wunused-result on a call to a locally redeclared + warn_unused_result function + { dg-do compile } + { dg-options "-Wall" } */ + +void gwur_local_local (void) +{ + __attribute__ ((warn_unused_result)) int fwur1 (void); + + fwur1 (); // { dg-warning "\\\[-Wunused-result" } +} + +void hwur_local_local (void) +{ + /* Verify the attribute from the declaration above is copied/merged + into the declaration below. */ + int fwur1 (void); + + fwur1 (); // { dg-warning "\\\[-Wunused-result" } +} + + +void gwur_local_global (void) +{ + __attribute__ ((warn_unused_result)) int fwur2 (void); + + fwur2 (); // { dg-warning "\\\[-Wunused-result" } +} + +int fwur2 (void); + +void hwur_local_global (void) +{ + fwur2 (); // { dg-warning "\\\[-Wunused-result" } +} + + +__attribute__ ((warn_unused_result)) int fwur3 (void); + +void gwur_global_local (void) +{ + fwur3 (); // { dg-warning "\\\[-Wunused-result" } +} + +void hwur_global_local (void) +{ + int fwur3 (void); + + fwur3 (); // { dg-warning "\\\[-Wunused-result" } +} diff --git a/gcc/testsuite/gcc.dg/attr-noreturn.c b/gcc/testsuite/gcc.dg/attr-noreturn.c new file mode 100644 index 0000000..8d58f6e --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-noreturn.c @@ -0,0 +1,64 @@ +/* Verify that attribute noreturn on global and local function declarations + is merged. + { dg-do compile } + { dg-options "-Wall -fdump-tree-optimized" } */ + +void foo (void); + +int fnr_local_local (void) +{ + __attribute__ ((noreturn)) void fnr1 (void); + + fnr1 (); + + foo (); +} + +int gnr_local_local (void) +{ + void fnr1 (void); + + fnr1 (); + + foo (); +} + + +int fnr_local_global (void) +{ + __attribute__ ((noreturn)) void fnr2 (void); + + fnr2 (); + + foo (); +} + +void fnr2 (void); + +int gnr_local_global (void) +{ + fnr2 (); + + foo (); +} + + +__attribute__ ((noreturn)) void fnr3 (void); + +int fnr_global_local (void) +{ + fnr3 (); + + foo (); +} + +int gnr_global_local (void) +{ + void fnr3 (void); + + fnr3 (); + + foo (); +} + +/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/attr-returns-nonnull.c b/gcc/testsuite/gcc.dg/attr-returns-nonnull.c new file mode 100644 index 0000000..22ee30a --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-returns-nonnull.c @@ -0,0 +1,58 @@ +/* Verify that attribute returns_nonnull on global and local function + declarations is merged. + { dg-do compile } + { dg-options "-Wall -fdump-tree-optimized" } */ + +void foo (void); + + +void frnn_local_local (void) +{ + __attribute__ ((returns_nonnull)) void* frnn1 (void); + + if (!frnn1 ()) + foo (); +} + +void gnr_local_local (void) +{ + void* frnn1 (void); + + if (!frnn1 ()) + foo (); +} + +void frnn_local_global (void) +{ + __attribute__ ((returns_nonnull)) void* frnn2 (void); + + if (!frnn2 ()) + foo (); +} + +void* frnn2 (void); + +void gnr_local_global (void) +{ + if (!frnn2 ()) + foo (); +} + +__attribute__ ((returns_nonnull)) void* frnn3 (void); + +void frnn_global_local (void) +{ + if (!frnn3 ()) + foo (); +} + +void gnr_global_local (void) +{ + void* frnn3 (void); + + if (!frnn3 ()) + foo (); +} + + +/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */ -- cgit v1.1 From 76c7e7d6b003a17d183d0571bf9b34c691819d25 Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Fri, 16 Apr 2021 07:48:34 +0200 Subject: testsuite: Fix unroll-and-jam.c on IBM Z For z10 and newer inner loops are completely unrolled which leaves no inner loops to jam which renders this testcase to fail. Reverting max-completely-peel-times to the default value fixes this testcase. gcc/testsuite/ChangeLog: * gcc.dg/unroll-and-jam.c: Revert max-completely-peel-times to the default value on IBM Z. --- gcc/testsuite/gcc.dg/unroll-and-jam.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/unroll-and-jam.c b/gcc/testsuite/gcc.dg/unroll-and-jam.c index 7eb6421..b8f4f16 100644 --- a/gcc/testsuite/gcc.dg/unroll-and-jam.c +++ b/gcc/testsuite/gcc.dg/unroll-and-jam.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-options "-O3 -floop-unroll-and-jam -fno-tree-loop-im --param unroll-jam-min-percent=0 -fdump-tree-unrolljam-details" } */ +/* { dg-additional-options "--param max-completely-peel-times=16" { target { s390*-*-* } } } */ /* { dg-require-effective-target int32plus } */ #include -- cgit v1.1 From 330ae1e54305f4755258d89469c1ad0d8479ef4c Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Fri, 16 Apr 2021 16:03:07 +0200 Subject: testsuite: Fix pr83403-{1,2}.c on IBM Z For z10 and newer inner loops are completely unrolled which means store motion is not applied. Reverting max-completely-peeled-insns to the default value fixes these testcases. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr83403-1.c: Revert max-completely-peeled-insns to the default value on IBM Z. * gcc.dg/tree-ssa/pr83403-2.c: Likewise. --- gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c | 1 + 2 files changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c index 748375b..bfc703d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */ +/* { dg-additional-options "--param max-completely-peeled-insns=200" { target { s390*-*-* } } } */ #define TYPE unsigned int diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c index ca2e6bb..9130d9b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */ +/* { dg-additional-options "--param max-completely-peeled-insns=200" { target { s390*-*-* } } } */ #define TYPE int -- cgit v1.1 From eb8c931e0dbf1d7d9bc1279cab68a963e8f3c299 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Wed, 17 Mar 2021 09:08:42 +0100 Subject: testsuite: Move gimplefe-4[0|1] tests. The gimplefe-40.c and gimplefe-41.c test cases require vect_* effective targets even though they reside in gcc.dg. By default e.g. DEFAULT_VECTCFLAGS which is used to add target-specific machine or build flags is only applied in the ./vect subdirectory. Move these tests there. gcc/testsuite/ChangeLog: * gcc.dg/gimplefe-40.c: Moved to... * gcc.dg/vect/gimplefe-40.c: ...here. * gcc.dg/gimplefe-41.c: Moved to... * gcc.dg/vect/gimplefe-41.c: ...here. --- gcc/testsuite/gcc.dg/gimplefe-40.c | 24 -------------------- gcc/testsuite/gcc.dg/gimplefe-41.c | 40 --------------------------------- gcc/testsuite/gcc.dg/vect/gimplefe-40.c | 24 ++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/gimplefe-41.c | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 64 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/gimplefe-40.c delete mode 100644 gcc/testsuite/gcc.dg/gimplefe-41.c create mode 100644 gcc/testsuite/gcc.dg/vect/gimplefe-40.c create mode 100644 gcc/testsuite/gcc.dg/vect/gimplefe-41.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gimplefe-40.c b/gcc/testsuite/gcc.dg/gimplefe-40.c deleted file mode 100644 index 3c5bb4c..0000000 --- a/gcc/testsuite/gcc.dg/gimplefe-40.c +++ /dev/null @@ -1,24 +0,0 @@ -/* { dg-do compile { target { int128 && vect_float } } } */ -/* { dg-options "-fgimple -Wno-psabi -w" } */ -/* { dg-additional-options "-maltivec" { target { powerpc*-*-* && powerpc_altivec_ok } } } */ - -typedef float v4sf __attribute__((vector_size(16))); -v4sf __GIMPLE (ssa) -load (const void * p) -{ - __int128 unsigned _3; - v4sf _4; - v4sf _6; - float _5; - - __BB(2): - _3 = __MEM <__int128 unsigned, 8> ((char *)p_2(D)); - _4 = __VIEW_CONVERT (_3); -#if __SIZEOF_FLOAT__ == 4 - _5 = __BIT_FIELD_REF (_4, 32, 64); -#else - _5 = 1.0f; -#endif - _6 = __BIT_INSERT (_4, _5, 0); - return _6; -} diff --git a/gcc/testsuite/gcc.dg/gimplefe-41.c b/gcc/testsuite/gcc.dg/gimplefe-41.c deleted file mode 100644 index e52a3a5..0000000 --- a/gcc/testsuite/gcc.dg/gimplefe-41.c +++ /dev/null @@ -1,40 +0,0 @@ -/* { dg-do compile { target { vect_double && vect_long_long } } } */ -/* { dg-options "-fgimple -Wno-psabi -w" } */ -/* { dg-additional-options "-msse2" { target x86_64-*-* i?86-*-* } } */ - -typedef double __v2df __attribute__ ((__vector_size__ (16))); -typedef unsigned long long __v2di __attribute__ ((__vector_size__ (16))); - -__v2df __GIMPLE (ssa) -_mm_add_sd (__v2df x, __v2df y) -{ - __v2df z; - double _1; - double _2; - double _3; - __v2df _7; - - __BB(2): - _1 = __BIT_FIELD_REF (x_4(D), 64u, 0u); - _2 = __BIT_FIELD_REF (y_5(D), 64u, 0u); - _3 = _1 + _2; - _7 = _Literal (__v2df) {_3, _3}; - z_6 = __VEC_PERM (x_4(D), _7, _Literal (__v2di) { 2ul, 1ul }); - return z_6; -} - -__v2df __GIMPLE (ssa) -_mm_add_sd2 (__v2df x, __v2df y) -{ - __v2df z; - double _1; - double _2; - double _3; - - __BB(2): - _1 = __BIT_FIELD_REF (x_4(D), 64u, 0u); - _2 = __BIT_FIELD_REF (y_5(D), 64u, 0u); - _3 = _1 + _2; - z_6 = __BIT_INSERT (x_4(D), _3, 0); - return z_6; -} diff --git a/gcc/testsuite/gcc.dg/vect/gimplefe-40.c b/gcc/testsuite/gcc.dg/vect/gimplefe-40.c new file mode 100644 index 0000000..3c5bb4c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/gimplefe-40.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target { int128 && vect_float } } } */ +/* { dg-options "-fgimple -Wno-psabi -w" } */ +/* { dg-additional-options "-maltivec" { target { powerpc*-*-* && powerpc_altivec_ok } } } */ + +typedef float v4sf __attribute__((vector_size(16))); +v4sf __GIMPLE (ssa) +load (const void * p) +{ + __int128 unsigned _3; + v4sf _4; + v4sf _6; + float _5; + + __BB(2): + _3 = __MEM <__int128 unsigned, 8> ((char *)p_2(D)); + _4 = __VIEW_CONVERT (_3); +#if __SIZEOF_FLOAT__ == 4 + _5 = __BIT_FIELD_REF (_4, 32, 64); +#else + _5 = 1.0f; +#endif + _6 = __BIT_INSERT (_4, _5, 0); + return _6; +} diff --git a/gcc/testsuite/gcc.dg/vect/gimplefe-41.c b/gcc/testsuite/gcc.dg/vect/gimplefe-41.c new file mode 100644 index 0000000..e52a3a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/gimplefe-41.c @@ -0,0 +1,40 @@ +/* { dg-do compile { target { vect_double && vect_long_long } } } */ +/* { dg-options "-fgimple -Wno-psabi -w" } */ +/* { dg-additional-options "-msse2" { target x86_64-*-* i?86-*-* } } */ + +typedef double __v2df __attribute__ ((__vector_size__ (16))); +typedef unsigned long long __v2di __attribute__ ((__vector_size__ (16))); + +__v2df __GIMPLE (ssa) +_mm_add_sd (__v2df x, __v2df y) +{ + __v2df z; + double _1; + double _2; + double _3; + __v2df _7; + + __BB(2): + _1 = __BIT_FIELD_REF (x_4(D), 64u, 0u); + _2 = __BIT_FIELD_REF (y_5(D), 64u, 0u); + _3 = _1 + _2; + _7 = _Literal (__v2df) {_3, _3}; + z_6 = __VEC_PERM (x_4(D), _7, _Literal (__v2di) { 2ul, 1ul }); + return z_6; +} + +__v2df __GIMPLE (ssa) +_mm_add_sd2 (__v2df x, __v2df y) +{ + __v2df z; + double _1; + double _2; + double _3; + + __BB(2): + _1 = __BIT_FIELD_REF (x_4(D), 64u, 0u); + _2 = __BIT_FIELD_REF (y_5(D), 64u, 0u); + _3 = _1 + _2; + z_6 = __BIT_INSERT (x_4(D), _3, 0); + return z_6; +} -- cgit v1.1 From 2f422b550ff6351d312e6c81a00b488d9280bfff Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 19 Apr 2021 10:07:35 +0200 Subject: preprocessor/100142 - revert unwanted change in last commit This reverts a s/column_offset/column/ change in the fix for PR99446. 2021-04-19 Richard Biener PR preprocessor/100142 libcpp/ * line-map.c (linemap_position_for_loc_and_offset): Revert unintended s/column_offset/column/ change. gcc/testsuite/ * gcc.dg/pr100142.c: New testcase. * g++.dg/diagnostic/pr72803.C: Revert last change. --- gcc/testsuite/gcc.dg/pr100142.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100142.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100142.c b/gcc/testsuite/gcc.dg/pr100142.c new file mode 100644 index 0000000..aec146c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100142.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fpreprocessed" } */ + +void +foo (void) +{ + assert (1); /* { dg-warning "implicit" } */ +} -- cgit v1.1 From cb60e56d4ac2958c422c003221ca0cff6a537e0b Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Wed, 21 Apr 2021 08:27:29 +0200 Subject: testsuite: Fix gcc.dg/vect/bb-slp-39.c on IBM Z On IBM Z the aliasing stores are realized through one element vector instructions, if no cost model for vectorization is used which is the default according to vect.exp. Fixed by changing the number of times the pattern must be found in the dump. gcc/testsuite/ChangeLog: * gcc.dg/vect/bb-slp-39.c: Change number of times the pattern must match for target IBM Z only. --- gcc/testsuite/gcc.dg/vect/bb-slp-39.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-39.c b/gcc/testsuite/gcc.dg/vect/bb-slp-39.c index 255bb10..ee596cf 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-39.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-39.c @@ -16,4 +16,5 @@ void foo (double *p) } /* See that we vectorize three SLP instances. */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "slp2" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "slp2" { target { ! s390*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 5 "slp2" { target { s390*-*-* } } } } */ -- cgit v1.1 From b4e17490c917746dc523cd1b4441000b66530695 Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Wed, 21 Apr 2021 10:44:54 +0200 Subject: testsuite: Xfail gcc.dg/vect/pr71264.c on IBM Z The test fails for targets with V4QImode support which is the case for IBM Z. gcc/testsuite/ChangeLog: * gcc.dg/vect/pr71264.c: Xfail on IBM Z due to V4QImode support. --- gcc/testsuite/gcc.dg/vect/pr71264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr71264.c b/gcc/testsuite/gcc.dg/vect/pr71264.c index 5f6407a..dc849bf 100644 --- a/gcc/testsuite/gcc.dg/vect/pr71264.c +++ b/gcc/testsuite/gcc.dg/vect/pr71264.c @@ -19,5 +19,5 @@ void test(uint8_t *ptr, uint8_t *mask) } } -/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail sparc*-*-* } } } */ +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail s390*-*-* sparc*-*-* } } } */ -- cgit v1.1 From d8f953819e8f72e646f22c7803d79bd2b56d1e30 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 21 Apr 2021 12:46:51 +0200 Subject: testsuite/100176 - fix struct-layout-1_generate.c compile With -Werror=return-type we run into compile fails complaining about missing return stmts. 2021-04-21 Richard Biener PR testsuite/100176 * g++.dg/compat/struct-layout-1_generate.c: Add missing return. * gcc.dg/compat/struct-layout-1_generate.c: Likewise. --- gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c index 75e902c..35dff89 100644 --- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c +++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c @@ -1280,6 +1280,8 @@ subvalues (struct entry *e, char *p, char *letter) if (e[0].len != 0) output_FNB ('B', e); return 1; + default: + return 0; } } -- cgit v1.1 From 3bb6a9c01f1e9b5daf9b37fca57e90804ba90d66 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 22 Apr 2021 11:32:29 +0200 Subject: Fix various typos. PR testsuite/100159 PR testsuite/100192 gcc/ChangeLog: * builtins.c (expand_builtin): Fix typos and missing comments. * dwarf2out.c (gen_subprogram_die): Likewise. (gen_struct_or_union_type_die): Likewise. gcc/fortran/ChangeLog: * frontend-passes.c (optimize_expr): Fix typos and missing comments. gcc/testsuite/ChangeLog: * g++.dg/template/nontype29.C: Fix typos and missing comments. * gcc.dg/Warray-bounds-64.c: Likewise. * gcc.dg/Warray-parameter.c: Likewise. * gcc.dg/Wstring-compare.c: Likewise. * gcc.dg/format/gcc_diag-11.c: Likewise. * gfortran.dg/array_constructor_3.f90: Likewise. * gfortran.dg/matmul_bounds_9.f90: Likewise. * gfortran.dg/pr78033.f90: Likewise. * gfortran.dg/pr96325.f90: Likewise. --- gcc/testsuite/gcc.dg/Warray-bounds-64.c | 2 +- gcc/testsuite/gcc.dg/Warray-parameter.c | 2 +- gcc/testsuite/gcc.dg/Wstring-compare.c | 10 +++++----- gcc/testsuite/gcc.dg/format/gcc_diag-11.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-64.c b/gcc/testsuite/gcc.dg/Warray-bounds-64.c index 88b88de..f5ebc3d 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-64.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-64.c @@ -7,7 +7,7 @@ asks for. { dg-do compile } - { dg-options "-O2 -Wall -Warray-parameter -Wno-vla-paramater" } */ + { dg-options "-O2 -Wall -Warray-parameter -Wno-vla-parameter" } */ #define NOIPA __attribute__ ((noipa)) diff --git a/gcc/testsuite/gcc.dg/Warray-parameter.c b/gcc/testsuite/gcc.dg/Warray-parameter.c index 42be310..6c5195a 100644 --- a/gcc/testsuite/gcc.dg/Warray-parameter.c +++ b/gcc/testsuite/gcc.dg/Warray-parameter.c @@ -5,7 +5,7 @@ Also verify that the array/pointer argument form in a mismatched redeclaration doesn't override the form in the initial declaration. { dg-do compile } - { dg-options "-Wall -Warray-parameter -Wno-vla-paramater" } */ + { dg-options "-Wall -Warray-parameter -Wno-vla-parameter" } */ /* Redclarations with the same or equivalent array form should not be dianosed. T[0] is diagnosed by -Wpedantic for being invalid diff --git a/gcc/testsuite/gcc.dg/Wstring-compare.c b/gcc/testsuite/gcc.dg/Wstring-compare.c index d1534bf..239bbfe 100644 --- a/gcc/testsuite/gcc.dg/Wstring-compare.c +++ b/gcc/testsuite/gcc.dg/Wstring-compare.c @@ -21,7 +21,7 @@ extern char b4[4]; void strcmp_array_lit (void) { if (strcmp (a4, "1234")) // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" } - // { dg-bogus "in this expreession" "unwanted note" { target *-*-* } .-1 } + // { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 } sink (0, a4); int cmp; @@ -44,7 +44,7 @@ void strcmp_array_pstr (void) { if (strcmp (a4, s4)) // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" } - // { dg-bogus "in this expreession" "unwanted note" { target *-*-* } .-1 } + // { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 } sink (1, a4); else sink (0, a4); @@ -86,7 +86,7 @@ void strcmp_array_copy (void) { strcpy (s, "1234"); if (strcmp (a4, s)) // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" } - // { dg-bogus "in this expreession" "unwanted note" { target *-*-* } .-1 } + // { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 } sink (1, a4); else sink (0, a4); @@ -131,7 +131,7 @@ void strcmp_member_array_lit (const struct S *p) void strncmp_array_lit (void) { if (strncmp (a4, "12345", 5)) // { dg-warning "'strncmp' of a string of length 5, an array of size 4 and bound of 5 evaluates to nonzero" } - // { dg-bogus "in this expreession" "unwanted note" { target *-*-* } .-1 } + // { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 } sink (0, a4); int cmp; @@ -161,7 +161,7 @@ void strncmp_strarray_copy (void) char b[6]; strcpy (b, "12345"); if (strncmp (a, b, 5)) // { dg-warning "'strncmp' of strings of length 4 and 5 and bound of 5 evaluates to nonzero" } - // { dg-bogus "in this expreession" "unwanted note" { target *-*-* } .-1 } + // { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 } sink (0, a, b); } diff --git a/gcc/testsuite/gcc.dg/format/gcc_diag-11.c b/gcc/testsuite/gcc.dg/format/gcc_diag-11.c index 262e7e5..80d24b6 100644 --- a/gcc/testsuite/gcc.dg/format/gcc_diag-11.c +++ b/gcc/testsuite/gcc.dg/format/gcc_diag-11.c @@ -375,7 +375,7 @@ void test_cdiag_identifier (tree t, gimple *gc) cdiag ("ident z_ with trailing underscore"); /* { dg-warning "unquoted identifier or keyword 'z_'" } */ cdiag ("v_ variable"); /* { dg-warning "unquoted identifier or keyword 'v_'" } */ cdiag ("call foo_bar"); /* { dg-warning "unquoted identifier or keyword 'foo_bar'" } */ - cdiag ("unqoted x_y ident"); /* { dg-warning "unquoted identifier or keyword 'x_y'" } */ + cdiag ("unquoted x_y ident"); /* { dg-warning "unquoted identifier or keyword 'x_y'" } */ cdiag ("size_t type"); /* { dg-warning "unquoted identifier or keyword 'size_t'" } */ cdiag ("bigger than INT_MAX");/* { dg-warning "unquoted identifier or keyword 'INT_MAX'" } */ -- cgit v1.1 From 0d923657c2fefac8aeb8eb317fe5c7e7c55880c9 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 24 Apr 2021 09:35:16 +0100 Subject: Add dg-final option-based target selectors This patch adds target selectors of the form: { any-opts "opt1" ... "optn" } { no-opts "opt1" ... "optn" } for skipping or xfailing tests based on compiler options. It only works for dg-final selectors. The patch then uses no-opts to exclude -O0 and (sometimes) -Og from some guality.exp xfails. AFAICT (based on gcc-testresults) these tests pass for those options for all targets. gcc/ * doc/sourcebuild.texi: Document no-opts and any-opts target selectors. gcc/testsuite/ * lib/target-supports-dg.exp (selector_expression): Handle any-opts and no-opts. * gcc.dg/guality/pr41353-1.c: Exclude -O0 from xfail. * gcc.dg/guality/pr59776.c: Likewise. * gcc.dg/guality/pr54970.c: Likewise -O0 and -Og. --- gcc/testsuite/gcc.dg/guality/pr41353-1.c | 2 +- gcc/testsuite/gcc.dg/guality/pr54970.c | 16 ++++++++-------- gcc/testsuite/gcc.dg/guality/pr59776.c | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/guality/pr41353-1.c b/gcc/testsuite/gcc.dg/guality/pr41353-1.c index cd30632..6639a52 100644 --- a/gcc/testsuite/gcc.dg/guality/pr41353-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr41353-1.c @@ -22,7 +22,7 @@ f2 (int i, int j) { j += i; /* { dg-final { gdb-test .+4 "i" "37" } } */ - /* { dg-final { gdb-test .+3 "j" "28 + 37" { xfail *-*-* } } } */ + /* { dg-final { gdb-test .+3 "j" "28 + 37" { xfail { no-opts "-O0" } } } } */ int i1 = 2 * i; /* { dg-final { gdb-test .+2 "i1" "2 * 37" } } */ int i2 = 3 * i; /* { dg-final { gdb-test .+1 "i2" "3 * 37" } } */ return j; diff --git a/gcc/testsuite/gcc.dg/guality/pr54970.c b/gcc/testsuite/gcc.dg/guality/pr54970.c index 2e0bc57..e60cc04 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54970.c +++ b/gcc/testsuite/gcc.dg/guality/pr54970.c @@ -8,39 +8,39 @@ int main () { - int a[] = { 1, 2, 3 }; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { *-*-* } } } } */ + int a[] = { 1, 2, 3 }; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { no-opts "-O0" "-Og" } } } } */ int *p = a + 2; /* { dg-final { gdb-test .+3 "a\[1\]" "2" } } */ int *q = a + 1; /* { dg-final { gdb-test .+2 "a\[2\]" "3" } } */ /* { dg-final { gdb-test .+1 "*p" "3" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "2" } } */ - *p += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { *-*-* } } } } */ + *p += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { no-opts "-O0" "-Og" } } } } */ /* { dg-final { gdb-test .+3 "a\[1\]" "2" } } */ /* { dg-final { gdb-test .+2 "a\[2\]" "13" } } */ /* { dg-final { gdb-test .+1 "*p" "13" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "2" } } */ - *q += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { *-*-* } } } } */ + *q += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { no-opts "-O0" "-Og" } } } } */ /* { dg-final { gdb-test .+3 "a\[1\]" "12" } } */ /* { dg-final { gdb-test .+2 "a\[2\]" "13" } } */ /* { dg-final { gdb-test .+1 "*p" "13" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "12" } } */ __builtin_memcpy (&a, (int [3]) { 4, 5, 6 }, sizeof (a)); - /* { dg-final { gdb-test .+4 "a\[0\]" "4" { xfail { *-*-* } } } } */ + /* { dg-final { gdb-test .+4 "a\[0\]" "4" { xfail { no-opts "-O0" "-Og" } } } } */ /* { dg-final { gdb-test .+3 "a\[1\]" "5" } } */ /* { dg-final { gdb-test .+2 "a\[2\]" "6" } } */ /* { dg-final { gdb-test .+1 "*p" "6" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "5" } } */ - *p += 20; /* { dg-final { gdb-test .+4 "a\[0\]" "4" { xfail { *-*-* } } } } */ + *p += 20; /* { dg-final { gdb-test .+4 "a\[0\]" "4" { xfail { no-opts "-O0" "-Og" } } } } */ /* { dg-final { gdb-test .+3 "a\[1\]" "5" } } */ /* { dg-final { gdb-test .+2 "a\[2\]" "26" } } */ /* { dg-final { gdb-test .+1 "*p" "26" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "5" } } */ - *q += 20; /* { dg-final { gdb-test .+8 "a\[0\]" "4" { xfail { *-*-* } } } } */ + *q += 20; /* { dg-final { gdb-test .+8 "a\[0\]" "4" { xfail { no-opts "-O0" "-Og" } } } } */ /* { dg-final { gdb-test .+7 "a\[1\]" "25" } } */ /* { dg-final { gdb-test .+6 "a\[2\]" "26" } } */ /* { dg-final { gdb-test .+5 "*p" "26" } } */ /* { dg-final { gdb-test .+4 "p\[-1\]" "25" } } */ - /* { dg-final { gdb-test .+3 "p\[-2\]" "4" { xfail { *-*-* } } } } */ - /* { dg-final { gdb-test .+2 "q\[-1\]" "4" { xfail { *-*-* } } } } */ + /* { dg-final { gdb-test .+3 "p\[-2\]" "4" { xfail { no-opts "-O0" "-Og" } } } } */ + /* { dg-final { gdb-test .+2 "q\[-1\]" "4" { xfail { no-opts "-O0" "-Og" } } } } */ /* { dg-final { gdb-test .+1 "q\[1\]" "26" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "25" } } */ return 0; diff --git a/gcc/testsuite/gcc.dg/guality/pr59776.c b/gcc/testsuite/gcc.dg/guality/pr59776.c index 7c95a9f..9777f62 100644 --- a/gcc/testsuite/gcc.dg/guality/pr59776.c +++ b/gcc/testsuite/gcc.dg/guality/pr59776.c @@ -12,11 +12,11 @@ foo (struct S *p) struct S s1, s2; /* { dg-final { gdb-test pr59776.c:17 "s1.f" "5.0" } } */ s1 = *p; /* { dg-final { gdb-test pr59776.c:17 "s1.g" "6.0" } } */ s2 = s1; /* { dg-final { gdb-test pr59776.c:17 "s2.f" "0.0" } } */ - *(int *) &s2.f = 0; /* { dg-final { gdb-test pr59776.c:17 "s2.g" "6.0" { xfail *-*-* } } } */ + *(int *) &s2.f = 0; /* { dg-final { gdb-test pr59776.c:17 "s2.g" "6.0" { xfail { no-opts "-O0" } } } } */ asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s1.f" "5.0" } } */ asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s1.g" "6.0" } } */ s2 = s1; /* { dg-final { gdb-test pr59776.c:20 "s2.f" "5.0" } } */ - asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s2.g" "6.0" { xfail *-*-* } } } */ + asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s2.g" "6.0" { xfail { no-opts "-O0" } } } } */ asm volatile (NOP : : : "memory"); } -- cgit v1.1 From f31ddad8ac8f11b8b11ab0c39f2e0740fd40ba8e Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 24 Apr 2021 09:35:16 +0100 Subject: Adjust guality xfails for aarch64*-*-* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch gives clean guality.exp test results for aarch64-linux-gnu with modern (top-of-tree) gdb. For people using older gdbs, it will trade one set of noisy results for another set. I still think it's better to have the xfails based on one “clean†and “modern†run rather than have FAILs and XPASSes for all runs. It's hard to tell which of these results are aarch64-specific and which aren't. If other target maintainers want to do something similar, and are prepared to assume the same gdb version, then it should become clearer over time which ones are target-specific and which aren't. There are no new skips here, so changes in test results will still show up as XPASSes. I've not analysed the failures or filed PRs for them. In some ways the guality directory itself seems like the best place to start looking for xfails, if someone's interested in working in this area. gcc/testsuite/ * gcc.dg/guality/example.c: Update aarch64*-*-* xfails. * gcc.dg/guality/guality.c: Likewise. * gcc.dg/guality/inline-params.c: Likewise. * gcc.dg/guality/loop-1.c: Likewise. * gcc.dg/guality/pr36728-1.c: Likewise. * gcc.dg/guality/pr36728-2.c: Likewise. * gcc.dg/guality/pr36728-3.c: Likewise. * gcc.dg/guality/pr41447-1.c: Likewise. * gcc.dg/guality/pr54200.c: Likewise. * gcc.dg/guality/pr54519-1.c: Likewise. * gcc.dg/guality/pr54519-2.c: Likewise. * gcc.dg/guality/pr54519-3.c: Likewise. * gcc.dg/guality/pr54519-4.c: Likewise. * gcc.dg/guality/pr54519-5.c: Likewise. * gcc.dg/guality/pr54519-6.c: Likewise. * gcc.dg/guality/pr54693-2.c: Likewise. * gcc.dg/guality/pr56154-1.c: Likewise. * gcc.dg/guality/pr59776.c: Likewise. * gcc.dg/guality/pr68860-1.c: Likewise. * gcc.dg/guality/pr68860-2.c: Likewise. * gcc.dg/guality/pr90074.c: Likewise. * gcc.dg/guality/pr90716.c: Likewise. * gcc.dg/guality/sra-1.c: Likewise. --- gcc/testsuite/gcc.dg/guality/example.c | 3 ++- gcc/testsuite/gcc.dg/guality/guality.c | 2 +- gcc/testsuite/gcc.dg/guality/inline-params.c | 2 +- gcc/testsuite/gcc.dg/guality/loop-1.c | 2 +- gcc/testsuite/gcc.dg/guality/pr36728-1.c | 2 +- gcc/testsuite/gcc.dg/guality/pr36728-2.c | 30 ++++++++++++++-------------- gcc/testsuite/gcc.dg/guality/pr36728-3.c | 2 +- gcc/testsuite/gcc.dg/guality/pr41447-1.c | 1 + gcc/testsuite/gcc.dg/guality/pr54200.c | 2 +- gcc/testsuite/gcc.dg/guality/pr54519-1.c | 8 ++++---- gcc/testsuite/gcc.dg/guality/pr54519-2.c | 2 +- gcc/testsuite/gcc.dg/guality/pr54519-3.c | 8 ++++---- gcc/testsuite/gcc.dg/guality/pr54519-4.c | 2 +- gcc/testsuite/gcc.dg/guality/pr54519-5.c | 2 +- gcc/testsuite/gcc.dg/guality/pr54519-6.c | 2 +- gcc/testsuite/gcc.dg/guality/pr54693-2.c | 2 +- gcc/testsuite/gcc.dg/guality/pr56154-1.c | 2 +- gcc/testsuite/gcc.dg/guality/pr59776.c | 12 +++++------ gcc/testsuite/gcc.dg/guality/pr68860-1.c | 2 +- gcc/testsuite/gcc.dg/guality/pr68860-2.c | 2 +- gcc/testsuite/gcc.dg/guality/pr90074.c | 4 ++-- gcc/testsuite/gcc.dg/guality/pr90716.c | 2 +- gcc/testsuite/gcc.dg/guality/sra-1.c | 8 ++++---- 23 files changed, 53 insertions(+), 51 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/guality/example.c b/gcc/testsuite/gcc.dg/guality/example.c index 26d25c2..6f1c017 100644 --- a/gcc/testsuite/gcc.dg/guality/example.c +++ b/gcc/testsuite/gcc.dg/guality/example.c @@ -1,5 +1,6 @@ -/* { dg-do run { xfail *-*-* } } */ +/* { dg-do run { xfail { ! aarch64*-*-* } } } */ /* { dg-options "-g" } */ +/* { dg-xfail-run-if "" aarch64*-*-* "*" { "-O[01g]" } } */ #define GUALITY_DONT_FORCE_LIVE_AFTER -1 diff --git a/gcc/testsuite/gcc.dg/guality/guality.c b/gcc/testsuite/gcc.dg/guality/guality.c index db015e6..a4de564 100644 --- a/gcc/testsuite/gcc.dg/guality/guality.c +++ b/gcc/testsuite/gcc.dg/guality/guality.c @@ -1,4 +1,4 @@ -/* { dg-do run { xfail *-*-* } } */ +/* { dg-do run { xfail { ! aarch64*-*-* } } } */ /* { dg-options "-g" } */ /* { dg-require-effective-target alloca } */ diff --git a/gcc/testsuite/gcc.dg/guality/inline-params.c b/gcc/testsuite/gcc.dg/guality/inline-params.c index f4c5f15..6be240a 100644 --- a/gcc/testsuite/gcc.dg/guality/inline-params.c +++ b/gcc/testsuite/gcc.dg/guality/inline-params.c @@ -3,7 +3,7 @@ inlining inlines the functions too early to test the real IPA passes (such as IPA-CP). */ /* { dg-options "-g -fno-early-inlining -fno-ipa-sra" } */ -/* { dg-xfail-run-if "" { "*-*-*" } { "-O2" "-O3" "-Os" } } */ +/* { dg-xfail-run-if "" { ! aarch64*-*-* } { "-O2" "-O3" "-Os" } } */ #define GUALITY_DONT_FORCE_LIVE_AFTER -1 diff --git a/gcc/testsuite/gcc.dg/guality/loop-1.c b/gcc/testsuite/gcc.dg/guality/loop-1.c index 8da447d..1b1f6d3 100644 --- a/gcc/testsuite/gcc.dg/guality/loop-1.c +++ b/gcc/testsuite/gcc.dg/guality/loop-1.c @@ -17,6 +17,6 @@ foo (int n) /* The following works only with final value replacement or with the NOP but not without (which means -Og). Vectorization breaks it, so disable that. At -O3 it currently fails, PR89983. */ - __asm__ volatile (NOP : : "g" (i) : "memory"); /* { dg-final { gdb-test . "i" "1" } } */ + __asm__ volatile (NOP : : "g" (i) : "memory"); /* { dg-final { gdb-test . "i" "1" { xfail { aarch64*-*-* && { any-opts "-ftracer" } } } } } */ } int main() { foo(1); } diff --git a/gcc/testsuite/gcc.dg/guality/pr36728-1.c b/gcc/testsuite/gcc.dg/guality/pr36728-1.c index 0ab475a..5864c2a 100644 --- a/gcc/testsuite/gcc.dg/guality/pr36728-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr36728-1.c @@ -32,7 +32,7 @@ foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) /* { dg-final { gdb-test 16 "arg5" "5" } } */ /* { dg-final { gdb-test 16 "arg6" "6" } } */ /* { dg-final { gdb-test 16 "arg7" "30" } } */ -/* { dg-final { gdb-test 16 "y" "2" } } */ +/* { dg-final { gdb-test 16 "y" "2" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ /* { dg-final { gdb-test 18 "arg1" "1" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 18 "arg2" "2" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 18 "arg3" "3" } } */ diff --git a/gcc/testsuite/gcc.dg/guality/pr36728-2.c b/gcc/testsuite/gcc.dg/guality/pr36728-2.c index 7ba8663..6e8d775 100644 --- a/gcc/testsuite/gcc.dg/guality/pr36728-2.c +++ b/gcc/testsuite/gcc.dg/guality/pr36728-2.c @@ -25,21 +25,21 @@ foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) and arg2. So it is expected that these values are unavailable in some of these tests. */ -/* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */ -/* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */ -/* { dg-final { gdb-test 16 "arg3" "3" } } */ -/* { dg-final { gdb-test 16 "arg4" "4" } } */ -/* { dg-final { gdb-test 16 "arg5" "5" } } */ -/* { dg-final { gdb-test 16 "arg6" "6" } } */ -/* { dg-final { gdb-test 16 "arg7" "30" } } */ -/* { dg-final { gdb-test 16 "y" "2" } } */ -/* { dg-final { gdb-test 18 "arg1" "1" { target { ! "s390*-*-*" } } } } */ -/* { dg-final { gdb-test 18 "arg2" "2" { target { ! "s390*-*-*" } } } } */ -/* { dg-final { gdb-test 18 "arg3" "3" } } */ -/* { dg-final { gdb-test 18 "arg4" "4" } } */ -/* { dg-final { gdb-test 18 "arg5" "5" } } */ -/* { dg-final { gdb-test 18 "arg6" "6" } } */ -/* { dg-final { gdb-test 18 "arg7" "30" } } */ +/* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "arg3" "3" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "arg4" "4" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "arg5" "5" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "arg6" "6" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "arg7" "30" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 16 "y" "2" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ +/* { dg-final { gdb-test 18 "arg1" "1" { target { ! "s390*-*-*" } xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 18 "arg2" "2" { target { ! "s390*-*-*" } xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 18 "arg3" "3" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 18 "arg4" "4" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 18 "arg5" "5" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 18 "arg6" "6" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ +/* { dg-final { gdb-test 18 "arg7" "30" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-O3" } } } } } */ /* { dg-final { gdb-test 18 "*x" "(char) 25" } } */ /* { dg-final { gdb-test 18 "y" "2" } } */ diff --git a/gcc/testsuite/gcc.dg/guality/pr36728-3.c b/gcc/testsuite/gcc.dg/guality/pr36728-3.c index 4700d50..589009b 100644 --- a/gcc/testsuite/gcc.dg/guality/pr36728-3.c +++ b/gcc/testsuite/gcc.dg/guality/pr36728-3.c @@ -30,7 +30,7 @@ foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) /* { dg-final { gdb-test 14 "arg5" "5" } } */ /* { dg-final { gdb-test 14 "arg6" "6" } } */ /* { dg-final { gdb-test 14 "arg7" "30" } } */ -/* { dg-final { gdb-test 14 "y" "2" } } */ +/* { dg-final { gdb-test 14 "y" "2" { xfail { aarch64*-*-* && { any-opts "-O3" } } } } } */ /* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 16 "arg3" "3" } } */ diff --git a/gcc/testsuite/gcc.dg/guality/pr41447-1.c b/gcc/testsuite/gcc.dg/guality/pr41447-1.c index 308ef94..9fde33e 100644 --- a/gcc/testsuite/gcc.dg/guality/pr41447-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr41447-1.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-options "-g" } */ +/* { dg-xfail-run-if "" { aarch64*-*-* } { "-O2" "-O3" "-Os" } { "-fno-fat-lto-objects" } } */ #include "guality.h" diff --git a/gcc/testsuite/gcc.dg/guality/pr54200.c b/gcc/testsuite/gcc.dg/guality/pr54200.c index e873d1b..ba14221 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54200.c +++ b/gcc/testsuite/gcc.dg/guality/pr54200.c @@ -17,7 +17,7 @@ foo (int z, int x, int b) else { int a = (x + z) + b; - return a; /* { dg-final { gdb-test . "z" "3" } } */ + return a; /* { dg-final { gdb-test . "z" "3" { xfail { aarch64*-*-* && { no-opts "-O0" "-Og" } } } } } */ } } diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-1.c b/gcc/testsuite/gcc.dg/guality/pr54519-1.c index a4105ab..81703eb 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54519-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr54519-1.c @@ -16,11 +16,11 @@ fn2 (int x, int y, int z) { fn1 (x); fn1 (x); /* { dg-final { gdb-test .+2 "x" "36" } } */ - if (x == 36) /* { dg-final { gdb-test .+1 "y" "25" } } */ - fn1 (x); /* { dg-final { gdb-test . "z" "6" } } */ + if (x == 36) /* { dg-final { gdb-test .+1 "y" "25" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ + fn1 (x); /* { dg-final { gdb-test . "z" "6" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); /* { dg-final { gdb-test .+2 "x" "98" } } */ - if (x == 98) /* { dg-final { gdb-test .+1 "y" "117" } } */ - fn1 (x); /* { dg-final { gdb-test . "z" "8" } } */ + if (x == 98) /* { dg-final { gdb-test .+1 "y" "117" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ + fn1 (x); /* { dg-final { gdb-test . "z" "8" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); fn1 (x + a); } diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-2.c b/gcc/testsuite/gcc.dg/guality/pr54519-2.c index 6bc1683..e1368bf 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54519-2.c +++ b/gcc/testsuite/gcc.dg/guality/pr54519-2.c @@ -14,7 +14,7 @@ fn2 (int x, int y) if (y) { fn1 (x); /* { dg-final { gdb-test .+1 "x" "6" } } */ - fn1 (x); /* { dg-final { gdb-test . "y" "25" } } */ + fn1 (x); /* { dg-final { gdb-test . "y" "25" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); fn1 (x); y = -2 + x; diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-3.c b/gcc/testsuite/gcc.dg/guality/pr54519-3.c index da18247..fabab96 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54519-3.c +++ b/gcc/testsuite/gcc.dg/guality/pr54519-3.c @@ -16,11 +16,11 @@ fn2 (int x, int y, int z) { fn1 (x); fn1 (x); /* { dg-final { gdb-test .+2 "x" "36" } } */ - if (x == 36) /* { dg-final { gdb-test .+1 "y" "25" } } */ - fn1 (x); /* { dg-final { gdb-test . "z" "6" } } */ + if (x == 36) /* { dg-final { gdb-test .+1 "y" "25" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ + fn1 (x); /* { dg-final { gdb-test . "z" "6" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); /* { dg-final { gdb-test .+2 "x" "98" } } */ - if (x == 98) /* { dg-final { gdb-test .+1 "y" "117" } } */ - fn1 (x); /* { dg-final { gdb-test . "z" "8" } } */ + if (x == 98) /* { dg-final { gdb-test .+1 "y" "117" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ + fn1 (x); /* { dg-final { gdb-test . "z" "8" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); fn1 (x + a); } diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-4.c b/gcc/testsuite/gcc.dg/guality/pr54519-4.c index c82de58..fd8465f 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54519-4.c +++ b/gcc/testsuite/gcc.dg/guality/pr54519-4.c @@ -14,7 +14,7 @@ fn2 (int x, int y) if (y) { fn1 (x); /* { dg-final { gdb-test .+1 "x" "6" } } */ - fn1 (x); /* { dg-final { gdb-test . "y" "25" } } */ + fn1 (x); /* { dg-final { gdb-test . "y" "25" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); fn1 (x); y = -2 + x; diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-5.c b/gcc/testsuite/gcc.dg/guality/pr54519-5.c index 0903fbf..76fa1e3 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54519-5.c +++ b/gcc/testsuite/gcc.dg/guality/pr54519-5.c @@ -14,7 +14,7 @@ fn2 (int x, int y) if (y) { fn1 (x); /* { dg-final { gdb-test .+1 "x" "6" } } */ - fn1 (x); /* { dg-final { gdb-test . "y" "25" } } */ + fn1 (x); /* { dg-final { gdb-test . "y" "25" { xfail { aarch64*-*-* && { any-opts "-flto" } } } } } */ fn1 (x); fn1 (x); y = -2 + x; diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-6.c b/gcc/testsuite/gcc.dg/guality/pr54519-6.c index bb3fb5f..732c268 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54519-6.c +++ b/gcc/testsuite/gcc.dg/guality/pr54519-6.c @@ -7,7 +7,7 @@ static inline void f1 (int x, int y) { - asm volatile (NOP); /* { dg-final { gdb-test .+1 "x" "2" } } */ + asm volatile (NOP); /* { dg-final { gdb-test .+1 "x" "2" { xfail { aarch64*-*-* && { any-opts "-Os" } } } } } */ asm volatile (NOP); /* { dg-final { gdb-test . "y" "0" } } */ } diff --git a/gcc/testsuite/gcc.dg/guality/pr54693-2.c b/gcc/testsuite/gcc.dg/guality/pr54693-2.c index 1741a38..68aa6c6 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54693-2.c +++ b/gcc/testsuite/gcc.dg/guality/pr54693-2.c @@ -19,7 +19,7 @@ foo (int x, int y, int z) { /* { dg-final { gdb-test .+2 "i" "v + 1" } } */ /* { dg-final { gdb-test .+1 "x" "10 - i" } } */ bar (i); /* { dg-final { gdb-test . "y" "20 - 2 * i" } } */ - /* { dg-final { gdb-test .-1 "z" "30 - 3 * i" } } */ + /* { dg-final { gdb-test .-1 "z" "30 - 3 * i" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-Os" } } } } } */ i++, x--, y -= 2, z -= 3; } } diff --git a/gcc/testsuite/gcc.dg/guality/pr56154-1.c b/gcc/testsuite/gcc.dg/guality/pr56154-1.c index 4f02bc9..d6da4a7 100644 --- a/gcc/testsuite/gcc.dg/guality/pr56154-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr56154-1.c @@ -17,7 +17,7 @@ foo (int fd, union U x) asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-1.c:17 "x.a" "4" } } */ z = x.a; x.a = 6; - asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-1.c:20 "x.a" "6" } } */ + asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-1.c:20 "x.a" "6" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ return result; } diff --git a/gcc/testsuite/gcc.dg/guality/pr59776.c b/gcc/testsuite/gcc.dg/guality/pr59776.c index 9777f62..0e48559 100644 --- a/gcc/testsuite/gcc.dg/guality/pr59776.c +++ b/gcc/testsuite/gcc.dg/guality/pr59776.c @@ -9,13 +9,13 @@ struct S { float f, g; }; __attribute__((noipa)) void foo (struct S *p) { - struct S s1, s2; /* { dg-final { gdb-test pr59776.c:17 "s1.f" "5.0" } } */ - s1 = *p; /* { dg-final { gdb-test pr59776.c:17 "s1.g" "6.0" } } */ - s2 = s1; /* { dg-final { gdb-test pr59776.c:17 "s2.f" "0.0" } } */ + struct S s1, s2; /* { dg-final { gdb-test pr59776.c:17 "s1.f" "5.0" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ + s1 = *p; /* { dg-final { gdb-test pr59776.c:17 "s1.g" "6.0" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ + s2 = s1; /* { dg-final { gdb-test pr59776.c:17 "s2.f" "0.0" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ *(int *) &s2.f = 0; /* { dg-final { gdb-test pr59776.c:17 "s2.g" "6.0" { xfail { no-opts "-O0" } } } } */ - asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s1.f" "5.0" } } */ - asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s1.g" "6.0" } } */ - s2 = s1; /* { dg-final { gdb-test pr59776.c:20 "s2.f" "5.0" } } */ + asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s1.f" "5.0" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ + asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s1.g" "6.0" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ + s2 = s1; /* { dg-final { gdb-test pr59776.c:20 "s2.f" "5.0" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ asm volatile (NOP : : : "memory"); /* { dg-final { gdb-test pr59776.c:20 "s2.g" "6.0" { xfail { no-opts "-O0" } } } } */ asm volatile (NOP : : : "memory"); } diff --git a/gcc/testsuite/gcc.dg/guality/pr68860-1.c b/gcc/testsuite/gcc.dg/guality/pr68860-1.c index 8c8d835..bbd9d6e 100644 --- a/gcc/testsuite/gcc.dg/guality/pr68860-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr68860-1.c @@ -31,7 +31,7 @@ foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int a /* { dg-final { gdb-test 14 "arg6" "6" } } */ /* { dg-final { gdb-test 14 "arg7" "30" } } */ /* { dg-final { gdb-test 14 "arg8" "7" } } */ -/* { dg-final { gdb-test 14 "y" "2" } } */ +/* { dg-final { gdb-test 14 "y" "2" { xfail { aarch64*-*-* && { { any-opts "-O2" "-O3" } && { no-opts "-flto" } } } } } } */ /* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 16 "arg3" "3" } } */ diff --git a/gcc/testsuite/gcc.dg/guality/pr68860-2.c b/gcc/testsuite/gcc.dg/guality/pr68860-2.c index 070efbc..a18a04e 100644 --- a/gcc/testsuite/gcc.dg/guality/pr68860-2.c +++ b/gcc/testsuite/gcc.dg/guality/pr68860-2.c @@ -31,7 +31,7 @@ foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int a /* { dg-final { gdb-test 14 "arg6" "6" } } */ /* { dg-final { gdb-test 14 "arg7" "30" } } */ /* { dg-final { gdb-test 14 "arg8" "7" } } */ -/* { dg-final { gdb-test 14 "y" "2" } } */ +/* { dg-final { gdb-test 14 "y" "2" { xfail { aarch64*-*-* && { any-opts "-O3" } } } } } */ /* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */ /* { dg-final { gdb-test 16 "arg3" "3" } } */ diff --git a/gcc/testsuite/gcc.dg/guality/pr90074.c b/gcc/testsuite/gcc.dg/guality/pr90074.c index 1294928..2fd8842 100644 --- a/gcc/testsuite/gcc.dg/guality/pr90074.c +++ b/gcc/testsuite/gcc.dg/guality/pr90074.c @@ -25,7 +25,7 @@ int main() debug stmt for the final value of the loop during loop distribution which would fix the UNSUPPORTED cases. c is optimized out at -Og for no obvious reason. */ - optimize_me_not(); /* { dg-final { gdb-test . "i + 1" "8" } } */ - /* { dg-final { gdb-test .-1 "c + 1" "2" } } */ + optimize_me_not(); /* { dg-final { gdb-test . "i + 1" "8" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ + /* { dg-final { gdb-test .-1 "c + 1" "2" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/guality/pr90716.c b/gcc/testsuite/gcc.dg/guality/pr90716.c index b2f5c9d..fe7e556 100644 --- a/gcc/testsuite/gcc.dg/guality/pr90716.c +++ b/gcc/testsuite/gcc.dg/guality/pr90716.c @@ -20,6 +20,6 @@ int main() Instead test j + 1 which will make the test UNSUPPORTED if i is optimized out. Since the test previously had wrong debug with j == 0 this is acceptable. */ - optimize_me_not(); /* { dg-final { gdb-test . "j + 1" "9" } } */ + optimize_me_not(); /* { dg-final { gdb-test . "j + 1" "9" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ return 0; } diff --git a/gcc/testsuite/gcc.dg/guality/sra-1.c b/gcc/testsuite/gcc.dg/guality/sra-1.c index 8ad57cf..e9b920e 100644 --- a/gcc/testsuite/gcc.dg/guality/sra-1.c +++ b/gcc/testsuite/gcc.dg/guality/sra-1.c @@ -18,7 +18,7 @@ f1 (int k) asm ("" : "+r" (a.i)); a.j++; bar (a.i); /* { dg-final { gdb-test .+1 "a.i" "4" } } */ - bar (a.j); /* { dg-final { gdb-test . "a.j" "14" } } */ + bar (a.j); /* { dg-final { gdb-test . "a.j" "14" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ return a.i + a.j; } @@ -29,7 +29,7 @@ f2 (int k) asm ("" : "+r" (a[0])); a[1]++; bar (a[0]); /* { dg-final { gdb-test .+1 "a\[0\]" "4" } } */ - bar (a[1]); /* { dg-final { gdb-test . "a\[1\]" "14" } } */ + bar (a[1]); /* { dg-final { gdb-test . "a\[1\]" "14" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ return a[0] + a[1]; } @@ -39,8 +39,8 @@ f3 (int k) struct B a = { 4, k + 6 }; asm ("" : "+r" (a.i)); a.j++; - bar (a.i); /* { dg-final { gdb-test .+1 "a.i" "4" } } */ - bar (a.j); /* { dg-final { gdb-test . "a.j" "14" } } */ + bar (a.i); /* { dg-final { gdb-test .+1 "a.i" "4" { xfail { aarch64*-*-* && { any-opts "-Og" } } } } } */ + bar (a.j); /* { dg-final { gdb-test . "a.j" "14" { xfail { aarch64*-*-* && { any-opts "-Og" "-fno-fat-lto-objects" } } } } } */ return a.i + a.j; } -- cgit v1.1 From 577d05fc914338cd7ddc254f3bee4532331f5c13 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 9 Mar 2021 09:29:29 +0100 Subject: tree-optimization/99473 - more cselim This fixes the pre-condition on cselim to include all references and decls when they end up as auto-var. Bootstrapped/tested on x86_64-linux 2021-03-09 Richard Biener PR tree-optimization/99473 * tree-ssa-phiopt.c (cond_store_replacement): Handle all stores. * gcc.dg/tree-ssa/pr99473-1.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c new file mode 100644 index 0000000..a9fd542 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fallow-store-data-races -fdump-tree-cselim-details" } */ + +void f (int*); + +void g3 (int i) +{ + int x = 0; + if (i) + x = i; + f (&x); +} + +/* { dg-final { scan-tree-dump "Conditional store replacement happened" "cselim" } } */ -- cgit v1.1 From bf3040836f41f0d719e6ec53820a692c443469d5 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 26 Apr 2021 12:55:24 +0200 Subject: Add XFAIL for gcc.dg/pr84877.c on the SPARC The maximum supported alignment is 64-bit on 32-bit mode. gcc/testsuite/ * gcc.dg/pr84877.c: XFAIL on SPARC as well. --- gcc/testsuite/gcc.dg/pr84877.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr84877.c b/gcc/testsuite/gcc.dg/pr84877.c index 8551d27..234fcd2 100644 --- a/gcc/testsuite/gcc.dg/pr84877.c +++ b/gcc/testsuite/gcc.dg/pr84877.c @@ -1,4 +1,4 @@ -/* { dg-do run { xfail { cris-*-* } } } */ +/* { dg-do run { xfail { cris-*-* sparc*-*-* } } } */ /* { dg-options "-O2" } */ #include -- cgit v1.1 From 7d6bb80931b429631f63e0fd27bee95f32eb57a9 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 26 Mar 2021 09:50:03 +0100 Subject: tree-optimization/99776 - relax condition on vector ctor element extract This relaxes the condition for the match.pd pattern doing vector ctor element extracts to not require type identity but only size equality. Since we vectorize pointer data as unsigned integer data such mismatches have to be tolerated to optimize scalar code uses of vector results. 2021-03-26 Richard Biener PR tree-optimization/99776 * match.pd (bit_field_ref (ctor)): Relax element extract type compatibility checks. * gcc.dg/tree-ssa/ssa-fre-91.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c new file mode 100644 index 0000000..4999a3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-91.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-fre4" } */ + +extern void foo(void); + +static int a[2], b, *c[2]; + +int main() { + for (b = 0; b < 2; b++) + c[b] = &a[1]; + if (!c[0]) + foo(); + return 0; +} + +/* Even when vectorizing we should eliminate the call to foo. */ +/* { dg-final { scan-tree-dump-not "foo" "fre4" } } */ -- cgit v1.1 From acfe5290406cc70485df8899d14982278a9371f8 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 27 Apr 2021 09:41:38 +0200 Subject: tree-optimization/100278 - handle mismatched code in TBAA adjust of PRE PRE has code to adjust TBAA behavior for refs that expects the base operation code to match. The testcase shows a case where we have a VAR_DECL vs. a MEM_REF so add code to give up in such cases. 2021-04-27 Richard Biener PR tree-optimization/100278 * tree-ssa-pre.c (compute_avail): Give up when we cannot adjust TBAA beacuse of mismatching bases. * gcc.dg/tree-ssa/pr100278.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/pr100278.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr100278.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100278.c b/gcc/testsuite/gcc.dg/tree-ssa/pr100278.c new file mode 100644 index 0000000..8d70228 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr100278.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void a() +{ +#if defined __s390__ + register int b asm("r5"); +#elif defined __x86_64__ + register int b asm("eax"); +#else + volatile int b; +#endif + if (b) + b = 1; + for (; b;) + ; +} -- cgit v1.1 From 3bc0d418a5d214a8ba57857656ca5c618df1a4bb Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 27 Apr 2021 10:45:32 +0200 Subject: testsuite/100272 - fix some malformed dg directives The bug points out several malformed dg directives, the following fixes the obvious ones where the testcases keep working after the change. 2021-04-27 Richard Biener PR testsuite/100272 * g++.dg/diagnostic/ptrtomem1.C: Fix dg directives. * g++.dg/ipa/pr45572-2.C: Likewise. * g++.dg/template/spec26.C: Likewise. * gcc.dg/pr20126.c: Likewise. * gcc.dg/tree-ssa/pr20739.c: Likewise. --- gcc/testsuite/gcc.dg/pr20126.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/pr20739.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr20126.c b/gcc/testsuite/gcc.dg/pr20126.c index 257832a..a421ce1 100644 --- a/gcc/testsuite/gcc.dg/pr20126.c +++ b/gcc/testsuite/gcc.dg/pr20126.c @@ -1,5 +1,5 @@ -/* dg-do run */ -/* dg-options "-O2" */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ /* PR target/20126 was not really target-specific, but rather a loop's failure to take into account the possibility that a DEST_ADDR giv diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20739.c b/gcc/testsuite/gcc.dg/tree-ssa/pr20739.c index c1e7b58..d7fff14 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr20739.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr20739.c @@ -1,7 +1,7 @@ /* PR middle-end/20739 */ -/* dg-do compile */ -/* dg-options "-O" */ +/* { dg-do compile } */ +/* { dg-options "-O" } */ /* We used to fail to compile this because gimplification dropped the conversion that added the const qualifier to the sub-expression -- cgit v1.1 From dfdc02bf29670c1c7f5f2820b6db11c66c258716 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 27 Apr 2021 11:02:03 +0200 Subject: testsuite/100272 - undo PRE disabling for gcc.dg/tree-ssa/predcom-1.c This re-enables PRE and fixes the malformed dg directive pointed out in the PR. It all works as desired and I forgot why I disabled this in the past. 2021-04-27 Richard Biener PR testsuite/100272 * gcc.dg/tree-ssa/predcom-1.c: Re-enable PRE and fix malformed dg directive. --- gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c b/gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c index 4bc2ea5..f68be2b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-do run } */ -/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */ +/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */ void abort (void); @@ -45,6 +45,5 @@ int main(void) /* Verify that both loops were transformed and unrolled. */ /* { dg-final { scan-tree-dump-times "Unrolling 2 times." 2 "pcom"} } */ -/* Also check that we undid the transformation previously made by PRE. - ??? PRE now does the predictive commoning in count_averages. */ -/* dg-final { scan-tree-dump-times "looparound ref" 1 "pcom" } */ +/* Also check that we undid the transformation previously made by PRE. */ +/* { dg-final { scan-tree-dump-times "looparound ref" 1 "pcom" } } */ -- cgit v1.1 From d1d01a66012a93cc8cb7dafbe1b5ec453ec96b59 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 13 Apr 2021 10:12:03 +0200 Subject: tree-optimization/100051 - disambiguate access size vs decl This adds disambiguation of the access size vs. the decl size in the pointer based vs. decl based disambiguator. We have a TBAA based check like this already but that's fend off when seeing alias-sets of zero or when -fno-strict-aliasing is in effect. Also the perceived dynamic type could be smaller than the actual access. 2021-04-13 Richard Biener PR tree-optimization/100051 * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Add disambiguator based on access size vs. decl size. * gcc.dg/tree-ssa/ssa-fre-92.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c new file mode 100644 index 0000000..c67fcea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +extern void foo(void); +int a, c, *f, **d = &f; +char b; +int main() +{ + if (a) { + b = 0; + int *g = &c; + *g = 0; + f = *d; + *d = f; + if ((2 ^ b) == 0) + foo(); + } + return 0; +} + +/* { dg-final { scan-tree-dump-not "foo" "fre1" } } */ -- cgit v1.1 From 75f8900159133ce069ef1d2edf3b67c7bc82e305 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 27 Apr 2021 14:47:54 +0200 Subject: match.pd: Add some __builtin_ctz (x) cmp cst simplifications [PR95527] This patch adds some ctz simplifications (e.g. ctz (x) >= 3 can be done by testing if the low 3 bits are zero, etc.). In addition, I've noticed that in the CLZ case, the #ifdef CLZ_DEFINED_VALUE_AT_ZERO don't really work as intended, they are evaluated during genmatch and the macro is not defined then (but, because of the missing tm.h includes it isn't defined in gimple-match.c or generic-match.c either). And when tm.h is included, defaults.h is included which defines a fallback version of that macro. For GCC 12, I wonder if it wouldn't be better to say in addition to __builtin_c[lt]z* is always UB at zero that it would be undefined for .C[LT]Z ifn too if it has just one operand and use a second operand to be the constant we expect at zero. 2021-04-27 Jakub Jelinek PR tree-optimization/95527 * generic-match-head.c: Include tm.h. * gimple-match-head.c: Include tm.h. * match.pd (CLZ == INTEGER_CST): Don't use #ifdef CLZ_DEFINED_VALUE_AT_ZERO, only test CLZ_DEFINED_VALUE_AT_ZERO if clz == CFN_CLZ. Add missing val declaration. (CTZ cmp CST): New simplifications. * gcc.dg/tree-ssa/pr95527-2.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr95527-2.c | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr95527-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95527-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95527-2.c new file mode 100644 index 0000000..b4ae2be --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95527-2.c @@ -0,0 +1,57 @@ +/* PR tree-optimization/95527 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ +/* { dg-final { scan-tree-dump "a & 7\\) == 0" "original" } } */ +/* { dg-final { scan-tree-dump "b & 63\\) != 0" "original" } } */ +/* { dg-final { scan-tree-dump-times "return 0;" 2 "original" } } */ +/* { dg-final { scan-tree-dump-times "return 1;" 2 "original" } } */ +/* { dg-final { scan-tree-dump "g & 15\\) == 8" "original" } } */ +/* { dg-final { scan-tree-dump "h & 255\\) != 128" "original" } } */ + +int +f1 (int a) +{ + return __builtin_ctz (a) >= 3; +} + +int +f2 (int b) +{ + return __builtin_ctz (b) < 6; +} + +int +f3 (int c) +{ + return __builtin_ctz (c) < 0; +} + +int +f4 (int d) +{ + return __builtin_ctz (d) >= 0; +} + +int +f5 (int e) +{ + return __builtin_ctz (e) >= __SIZEOF_INT__ * __CHAR_BIT__; +} + +int +f6 (int f) +{ + return __builtin_ctz (f) < __SIZEOF_INT__ * __CHAR_BIT__; +} + +int +f7 (int g) +{ + return __builtin_ctz (g) == 3; +} + +int +f8 (int h) +{ + return __builtin_ctz (h) != 7; +} -- cgit v1.1 From d8e1f1d24179690fd9c0f63c27b12e030010d9ea Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 7 Apr 2021 12:09:44 +0200 Subject: tree-optimization/99912 - schedule DSE before SRA For the testcase in the PR the main SRA pass is unable to do some important scalarizations because dead stores of addresses make the candiate variables disqualified. The following patch adds another DSE pass before SRA forming a DCE/DSE pair and moves the DSE pass that is currently closely after SRA up to after the next DCE pass, forming another DCE/DSE pair now residing after PRE. 2021-04-07 Richard Biener PR tree-optimization/99912 * passes.def (pass_all_optimizations): Add pass_dse before the first pass_dce, move the first pass_dse before the pass_dce following pass_pre. * gcc.dg/tree-ssa/ldist-33.c: Disable PRE and LIM. * gcc.dg/tree-ssa/pr96789.c: Adjust dump file scanned. * gcc.dg/tree-ssa/ssa-dse-28.c: Likewise. * gcc.dg/tree-ssa/ssa-dse-29.c: Likewise. --- gcc/testsuite/gcc.dg/tree-ssa/ldist-33.c | 5 ++++- gcc/testsuite/gcc.dg/tree-ssa/pr96789.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-28.c | 3 ++- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-33.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-33.c index 9e0cedf..67846a5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-33.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-33.c @@ -1,5 +1,8 @@ /* { dg-do compile { target size32plus } } */ -/* { dg-options "-O2 -ftree-loop-distribution -ftree-loop-distribute-patterns -fdump-tree-ldist-details" } */ +/* The desire is to show we can generate a memset from the outer loop + store. Both store motion and PRE expose a DSE opportunity for this + zeroing - while desirable this defeats the purpose of this testcase. */ +/* { dg-options "-O2 -fno-tree-loop-im -fno-tree-pre -ftree-loop-distribution -ftree-loop-distribute-patterns -fdump-tree-ldist-details" } */ #define N (1024) double a[N][N], b[N][N], c[N][N]; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c index 5704952..4d4d4c8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c @@ -58,4 +58,4 @@ bar (int16_t res[16], uint8_t *val1, uint8_t *val2) } } -/* { dg-final { scan-tree-dump {Deleted dead store:.*tmp} "dse3" } } */ +/* { dg-final { scan-tree-dump {Deleted dead store:.*tmp} "dse4" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-28.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-28.c index b81cabe..3bf4e76 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-28.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-28.c @@ -17,5 +17,6 @@ int foo (int *p, int b) /* { dg-final { scan-tree-dump-not "Deleted dead store" "dse1"} } */ /* { dg-final { scan-tree-dump-not "Deleted dead store" "dse2"} } */ -/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse4"} } */ +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse3"} } */ +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse5"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c index f4ef89c..4990ae0 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c @@ -22,5 +22,6 @@ foo(int cond, struct z *s) /* { dg-final { scan-tree-dump-times "Deleted dead store" 3 "dse1"} } */ /* { dg-final { scan-tree-dump-not "Deleted dead store" "dse2"} } */ -/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse4"} } */ +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse3"} } */ +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse5"} } */ -- cgit v1.1 From 83d26d0e1b3625ab6c2d83610a13976b52f63e0a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 27 Apr 2021 15:42:47 +0200 Subject: veclower: Fix up vec_shl matching of VEC_PERM_EXPR [PR100239] The following testcase ICEs at -O0, because lower_vec_perm sees the _1 = { 0, 0, 0, 0, 0, 0, 0, 0 }; _2 = VEC_COND_EXPR <_1, { -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 0, 0, 0, 0, 0, 0, 0 }>; _3 = { 6, 0, 0, 0, 0, 0, 0, 0 }; _4 = VEC_PERM_EXPR <{ 0, 0, 0, 0, 0, 0, 0, 0 }, _2, _3>; and as the ISA is SSE2, there is no support for the particular permutation nor for variable mask permutation. But, the code to match vec_shl matches it, because the permutation has the first operand a zero vector and the mask picks all elements randomly from that vector. So, in the end that isn't a vec_shl, but the permutation could be in theory optimized into the first argument. As we keep it as is, it will fail during expansion though, because that for vec_shl correctly requires that it actually is a shift: unsigned firstidx = 0; for (unsigned int i = 0; i < nelt; i++) { if (known_eq (sel[i], nelt)) { if (i == 0 || firstidx) return NULL_RTX; firstidx = i; } else if (firstidx ? maybe_ne (sel[i], nelt + i - firstidx) : maybe_ge (sel[i], nelt)) return NULL_RTX; } if (firstidx == 0) return NULL_RTX; first = firstidx; The if (firstidx == 0) return NULL; is what is missing a counterpart on the lower_vec_perm side. As with optimize != 0 we fold it in other spots, I think it is not needed to optimize this cornercase in lower_vec_perm (which would mean we'd need to recurse on the newly created _4 = { 0, 0, 0, 0, 0, 0, 0, 0 }; whether it is supported or not). 2021-04-27 Jakub Jelinek PR tree-optimization/100239 * tree-vect-generic.c (lower_vec_perm): Don't accept constant permutations with all indices from the first zero element as vec_shl. * gcc.dg/pr100239.c: New test. --- gcc/testsuite/gcc.dg/pr100239.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100239.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100239.c b/gcc/testsuite/gcc.dg/pr100239.c new file mode 100644 index 0000000..1ade810 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100239.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/100239 */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +typedef short __attribute__((__vector_size__ (8 * sizeof (short)))) V; +V v, w; + +void +foo (void) +{ + w = __builtin_shuffle (v != v, 0 < (V) {}, (V) {192} >> 5); +} -- cgit v1.1 From f7ee6a1e8ac62950dd32874bf75e748a2895d595 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 28 Apr 2021 10:41:41 +0200 Subject: tree-optimization/100292 - avoid invalid GIMPLE from vector lowering We have to avoid folding the condition when building a COND_EXPR since we no longer gimplify the whole thing. The folding done at COND_EXPR build time will deal with possible simplifications. 2021-04-28 Richard Biener PR tree-optimization/100292 * tree-vect-generic.c (expand_vector_condition): Do not fold the comparisons. * gcc.dg/pr100292.c: New testcase. --- gcc/testsuite/gcc.dg/pr100292.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100292.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100292.c b/gcc/testsuite/gcc.dg/pr100292.c new file mode 100644 index 0000000..675a60c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100292.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +typedef unsigned char __attribute__((__vector_size__ (4))) V; + +extern void bar (V v); + +void +foo (char c) +{ + bar (c <= (V) 127); +} -- cgit v1.1 From 16683cefc636636ba6fed23fe0de89ed19bc7876 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 28 Apr 2021 14:07:41 -0300 Subject: fix asm-not pattern in dwarf2/inline5.c The test is supposed to check that the abstract lexical block of a function that was inlined doesn't have attributes, and that the concrete inlined lexical block does. There are two patterns to verify the absence of attributes in the abstract lexical block, one for the case in which the concrete block appears after the abstract one, and another for the case in which it's before. The former has a problem that is not visible when asm comments start with a single character, but that becomes apparent when they start with "/ ". The pattern starts by matching the abstract DW_TAG_lexical_block DIE header, and checking that the next line has, after any of the comment-starter characters (e.g. '/'), there are one or more blanks ' +', and then a character other than the '(' that would start another DIE. The problem is that '[.../...]+ +[^(].*' matches '/ (DIE...', because '[^(]' may match the second blank, and after that anything goes. So we end up recognizing the pattern, as if it was an abstract lexical block with an attribute. This could be minimally fixed by changing '[^(]' to '[^ (]', but the pattern that matches concrete before abstract checks for an explicit DW_AT after the abstract DIE, so I'm using that in the other pattern as well. For reference, the lines that start the unwanted match are: .uleb128 0xc / (DIE (0xa4) DW_TAG_lexical_block) .uleb128 0xd / (DIE (0xa5) DW_TAG_variable) for gcc/testsuite/ChangeLog * gcc.dg/debug/dwarf2/inline5.c: Adjust pattern to avoid mismatch when asm comments start with "/ ". --- gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c index bd34f0d..3b50e9f 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c @@ -9,7 +9,7 @@ /* We do not know which is output first so look for both invalid abstract origins on the lexical blocks (knowing that the abstract instance has no attribute following the DW_TAG_lexical_block. */ -/* { dg-final { scan-assembler-not "\\(DIE \\(0x(\[0-9a-f\]*)\\) DW_TAG_lexical_block\\)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +\[^(\].*DW_TAG_lexical_block\\)\[^#/!@;\\|x\]*x\\1\[^#/!@;\\|\]*\[#/!@;\\|\] +DW_AT_abstract_origin" { xfail { { *-*-aix* || *-*-solaris2.* } && { ! gas } } } } } */ +/* { dg-final { scan-assembler-not "\\(DIE \\(0x(\[0-9a-f\]*)\\) DW_TAG_lexical_block\\)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +DW_AT.*DW_TAG_lexical_block\\)\[^#/!@;\\|x\]*x\\1\[^#/!@;\\|\]*\[#/!@;\\|\] +DW_AT_abstract_origin" { xfail { { *-*-aix* || *-*-solaris2.* } && { ! gas } } } } } */ /* { dg-final { scan-assembler-not "DW_TAG_lexical_block\\)\[^#/!@;\\|x\]*x(\[0-9a-f\]*)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +DW_AT_abstract_origin.*\\(DIE \\(0x\\1\\) DW_TAG_lexical_block\\)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +DW_AT" } } */ int foo (int i) -- cgit v1.1 From cc806126215c3f4dc187eff3bf923458d8cc6b4f Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 29 Apr 2021 00:50:35 +0000 Subject: c: C2x changes to function type compatibility WG14 N2432, the C2x removal of old-style function definitions, also changed the function type compatibility rules so that an unprototyped declaration can be compatible with a non-variadic prototyped declaration even if some function arguments are changed by the default argument promotions. I missed that change in the initial implementation for GCC of the rest of the N2432 changes, but discussion on the WG14 reflector in February suggests that this is indeed an intended change. Implement this in the C front end. Note that while this may be of use in some cases for use of pointers to unprototyped function types as a kind of generic function pointer, it's *not* possible to call such a function without a prototype visible, without getting runtime undefined behavior from the (promoted) type used in the call being incompatible with the (unpromoted) type in the prototype. Note also that GCC has a longstanding extension to allow compatibility of such a prototype with an old-style definition specifying the same type as in the prototype (which is not valid in ISO C, before old-style definitions were removed in C2x). Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c/ * c-typeck.c (function_types_compatible_p): For C2X, treat unprototyped function as compatible with non-variadic prototyped function even if some argument types are changed by the default argument promotions. gcc/testsuite/ * gcc.dg/c11-unproto-1.c, gcc.dg/c11-unproto-2.c, gcc.dg/c2x-unproto-1.c, gcc.dg/c2x-unproto-2.c: New tests. --- gcc/testsuite/gcc.dg/c11-unproto-1.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/c11-unproto-2.c | 21 +++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-unproto-1.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-unproto-2.c | 21 +++++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/c11-unproto-1.c create mode 100644 gcc/testsuite/gcc.dg/c11-unproto-2.c create mode 100644 gcc/testsuite/gcc.dg/c2x-unproto-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-unproto-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/c11-unproto-1.c b/gcc/testsuite/gcc.dg/c11-unproto-1.c new file mode 100644 index 0000000..ea9e807 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-unproto-1.c @@ -0,0 +1,24 @@ +/* Test compatibility of unprototyped and prototyped function types (C2x makes + the case of types affected by default argument promotions compatible). Test + valid-in-C2x usages are not accepted for C11. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +void f1 (); /* { dg-message "previous declaration" } */ +void f1 (float); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ + +void f2 (float); /* { dg-message "previous declaration" } */ +void f2 (); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ + +void f3 (); /* { dg-message "previous declaration" } */ +void f3 (char); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ + +void f4 (char); /* { dg-message "previous declaration" } */ +void f4 (); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ + +/* Built-in function case. */ +float sqrtf (); /* { dg-warning "conflicting types for built-in function" } */ diff --git a/gcc/testsuite/gcc.dg/c11-unproto-2.c b/gcc/testsuite/gcc.dg/c11-unproto-2.c new file mode 100644 index 0000000..0557ae3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-unproto-2.c @@ -0,0 +1,21 @@ +/* Test compatibility of unprototyped and prototyped function types (C2x makes + the case of types affected by default argument promotions compatible). Test + invalid-in-C2x usages, in C11 mode. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +void f1 (); /* { dg-message "previous declaration" } */ +void f1 (int, ...); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ + +void f2 (int, ...); /* { dg-message "previous declaration" } */ +void f2 (); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ + +void f3 (); /* { dg-message "previous declaration" } */ +void f3 (char, ...); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ + +void f4 (char, ...); /* { dg-message "previous declaration" } */ +void f4 (); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/c2x-unproto-1.c b/gcc/testsuite/gcc.dg/c2x-unproto-1.c new file mode 100644 index 0000000..45d68f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-unproto-1.c @@ -0,0 +1,20 @@ +/* Test compatibility of unprototyped and prototyped function types (C2x makes + the case of types affected by default argument promotions compatible). Test + valid-in-C2x usages. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +void f1 (); +void f1 (float); + +void f2 (float); +void f2 (); + +void f3 (); +void f3 (char); + +void f4 (char); +void f4 (); + +/* Built-in function case. */ +float sqrtf (); diff --git a/gcc/testsuite/gcc.dg/c2x-unproto-2.c b/gcc/testsuite/gcc.dg/c2x-unproto-2.c new file mode 100644 index 0000000..f826b7c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-unproto-2.c @@ -0,0 +1,21 @@ +/* Test compatibility of unprototyped and prototyped function types (C2x makes + the case of types affected by default argument promotions compatible). Test + invalid-in-C2x usages. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +void f1 (); /* { dg-message "previous declaration" } */ +void f1 (int, ...); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ + +void f2 (int, ...); /* { dg-message "previous declaration" } */ +void f2 (); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ + +void f3 (); /* { dg-message "previous declaration" } */ +void f3 (char, ...); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ + +void f4 (char, ...); /* { dg-message "previous declaration" } */ +void f4 (); /* { dg-error "conflicting types" } */ +/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */ -- cgit v1.1 From 2c8bffa184dffba7976ba807ef0a1bbb6f66aa2d Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Apr 2021 19:11:34 -0600 Subject: PR middle-end/100250 - ICE related to -Wmaybe-uninitialized gcc/ChangeLog: PR middle-end/100250 * attribs.c (attr_access::array_as_string): Avoid dereferencing a pointer when it's null. gcc/testsuite/ChangeLog: PR middle-end/100250 * gcc.dg/uninit-pr100250.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr100250.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr100250.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr100250.c b/gcc/testsuite/gcc.dg/uninit-pr100250.c new file mode 100644 index 0000000..8e7a787 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr100250.c @@ -0,0 +1,29 @@ +/* PR middle-end/100250 - ICE related to -Wmaybe-uninitialized + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +extern void f (int D, const int[D], const int[D]); + +void g (int D, const int a[D], const int b[D], const int c[D], const int d[D]) +{ + int c2[D]; + + for (int i = 0; i < D; i++) { + + if (a[i] >= D) __builtin_abort (); + if (b[i] != d[a[i]]) __builtin_abort (); + + c2[a[i]] = c[i]; + } + + f (D, d, c2); +} + +void h (int D, const int d[D]) +{ + int a[D]; + int b[D]; + int c[D]; + + g (D, a, b, c, d); // { dg-warning "-Wmaybe-uninitialized" } +} -- cgit v1.1 From b58dc0b803057c0e6032e0d9bd92cd834f72c75c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 27 Apr 2021 14:32:27 +0200 Subject: tree-optimization/99912 - delete trivially dead stmts during DSE DSE performs a backwards walk over stmts removing stores but it leaves removing resulting dead SSA defs to later passes. This eats into its own alias walking budget if the removed stores kept loads live. The following patch adds removal of trivially dead SSA defs which helps in this situation and reduces the amount of garbage followup passes need to deal with. 2021-04-28 Richard Biener PR tree-optimization/99912 * tree-ssa-dse.c (dse_dom_walker::m_need_cfg_cleanup): New. (dse_dom_walker::todo): Likewise. (dse_dom_walker::dse_optimize_stmt): Move VDEF check to the caller. (dse_dom_walker::before_dom_children): Remove trivially dead SSA defs and schedule CFG cleanup if we removed all PHIs in a block. (pass_dse::execute): Get TODO as computed by the DOM walker and return it. Wipe dominator info earlier. * gcc.dg/pr95580.c: Disable DSE. * gcc.dg/Wrestrict-8.c: Place a use after each memcpy. * c-c++-common/ubsan/overflow-negate-3.c: Make asms volatile to prevent them from being removed. * c-c++-common/ubsan/overflow-sub-4.c: Likewise. --- gcc/testsuite/gcc.dg/Wrestrict-8.c | 4 +++- gcc/testsuite/gcc.dg/pr95580.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wrestrict-8.c b/gcc/testsuite/gcc.dg/Wrestrict-8.c index 24946b0..62e8bbc 100644 --- a/gcc/testsuite/gcc.dg/Wrestrict-8.c +++ b/gcc/testsuite/gcc.dg/Wrestrict-8.c @@ -7,7 +7,9 @@ typedef __SIZE_TYPE__ size_t; extern void* memcpy (void* restrict, const void* restrict, size_t); -#define T(d, s, n) memcpy (d, s, n) +void foo (void *); + +#define T(d, s, n) do { memcpy (d, s, n); foo (d); } while (0) struct S1 { char c; } a8_1[8]; diff --git a/gcc/testsuite/gcc.dg/pr95580.c b/gcc/testsuite/gcc.dg/pr95580.c index 330a313..77d8150 100644 --- a/gcc/testsuite/gcc.dg/pr95580.c +++ b/gcc/testsuite/gcc.dg/pr95580.c @@ -1,6 +1,6 @@ /* PR c/95580 */ /* { dg-do compile } */ -/* { dg-options "-O1 -W -fno-tree-dce" } */ +/* { dg-options "-O1 -W -fno-tree-dce -fno-tree-dse" } */ void bar (void); -- cgit v1.1 From 4cf3b10f27b1994cf4a9eb12079d85412ebc7cad Mon Sep 17 00:00:00 2001 From: Roman Zhuykov Date: Fri, 30 Apr 2021 11:08:03 +0300 Subject: modulo-sched: skip loops with strange register defs [PR100225] PR84878 fix adds an assertion which can fail, e.g. when stack pointer is adjusted inside the loop. We have to prevent it and search earlier for any 'strange' instruction. The solution is to skip the whole loop if using 'note_stores' we found that one of hard registers is in 'df->regular_block_artificial_uses' set. Also patch properly prohibit not single-set instruction in loop body. gcc/ChangeLog: PR rtl-optimization/100225 PR rtl-optimization/84878 * modulo-sched.c (sms_schedule): Use note_stores to skip loops where we have an instruction which touches (writes) any hard register from df->regular_block_artificial_uses set. Allow not-single-set instruction only right before basic block tail. gcc/testsuite/ChangeLog: PR rtl-optimization/100225 PR rtl-optimization/84878 * gcc.dg/pr100225.c: New test. libgomp/ChangeLog: * testsuite/libgomp.oacc-c-c++-common/atomic_capture-3.c: New test. --- gcc/testsuite/gcc.dg/pr100225.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100225.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100225.c b/gcc/testsuite/gcc.dg/pr100225.c new file mode 100644 index 0000000..b321634 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100225.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/100225 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fmodulo-sched" } */ + +void +vorbis_synthesis_lapout (void); + +void +ov_info (int **lappcm, int ov_info_i) +{ + while (ov_info_i < 1) + lappcm[ov_info_i++] = __builtin_alloca (1); + + vorbis_synthesis_lapout (); +} -- cgit v1.1 From b9bc4467cc78201f362b5390d53640b0feaa8d40 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 30 Apr 2021 11:13:42 +0200 Subject: tree-optimization/96513 - add testcase for fixed bug This adds a testcase for a bug that was fixed with the hybrid SLP detection rewrite. 2021-04-30 Richard Biener PR tree-optimization/96513 * gcc.dg/torture/pr96513.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr96513.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr96513.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr96513.c b/gcc/testsuite/gcc.dg/torture/pr96513.c new file mode 100644 index 0000000..5ee040e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr96513.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +typedef struct { + short a; + short b; +} c; +c *d; +int e, f, i, j, k, l, m, n, o, p; +c g, h; +void q() { + do { + if (o) { + (*d).a = (*d).b = d[e].a = d[e].a * 3 + 1 >> 15; + d[e].b = d[e].b * 3 + 1 >> 15; + } + n = -(d[e].b * g.b) >> 5; + m = d[e].b * g.a + 1 >> 5; + l = d[f].a * -d[f].b * h.b + 1 >> 5; + k = d[f].a * h.b + d[f].b * h.a + 1 >> 5; + j = n + l; + i = m - k; + (*d).a += j; + d[e].a -= i; + ++d; + } while (--p); +} -- cgit v1.1 From 92f59e47f5a468b96b12b15233a6729904b1a1ee Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Tue, 6 Apr 2021 11:41:49 -0400 Subject: aix: Redesign section encoding and selection AIX symbol references can refer to either the symbol (a label) or a symbol with a qualifier (the storage mapping class). The storage mapping class provide information about the underlying COFF section into which the symbol will be placed, e.g. [RO] for read-only in the text section, [RW] for read-writer in the data section, or [BS] for the BSS section. A label is distinct from a qualname in the assembler language, e.g., foo and foo[RW] are different, but the symbol table of an object file strips the storage mapping class from the name, so that it no longer is relevant when referring to symbols across object files and libraries. .csect .data[RW] i: is a label "i" in the .data CSECT, which has storage mapping class [RW] so that it is placed in the read-write COFF section. .csect i[RW] is a CSECT "i[RW]". BSS does not allow interior labels. The AIX port of GCC had been emitting the storage mapping class where appropriate but not consistently using the storage mapping class on the DECL or SYM name. This patch updates the section encoding to properly place storage mapping class on symbol names and remove the decorations placed when emitting the symbol. The mapping classes correspond to sections and the encoding choices must exactly match the section choices made by get_section, so the logic for the computation of reloc in get_variable_section is split into its own function that XCOFF encode section info can call. gcc/ChangeLog: * varasm.c (compute_reloc_for_var): Split out from... (get_variable_section): Use it. * output.h (compute_reloc_for_var): Declare. * config/rs6000/rs6000-protos.h (rs6000_xcoff_asm_output_aligned_decl_common): Change alignment to unsigned int. * config/rs6000/rs6000.c (rs6000_legitimize_tls_address_aix): Don't append storage mapping class to symbol. (rs6000_xcoff_asm_named_section): Add BS and UL mapping classes. Don't convert TLS BSS to common. (rs6000_xcoff_unique_section): Don't fall back to select_secton. (rs6000_xcoff_section_type_flags): Add SECTION_BSS if DECL is bss_initializer. (rs6000_xcoff_asm_globalize_decl_name): Don't strip storage mapping class. (rs6000_xcoff_asm_output_aligned_decl_common): Align is unsigned int. If align is 0 from TLS class, use the same rules as varasm.c If not common, switch to BSS section manually. If common, emit appropriate comm or lcomm directive. (rs6000_xcoff_encode_section_info): Add logic to append all storage mapping classes. (rs6000_asm_weaken_decl): Adjust for qualname symbols. * config/rs6000/xcoff.h (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Use rs6000_xcoff_asm_output_aligned_decl_common. (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Use rs6000_xcoff_asm_output_aligned_decl_common. (ASM_OUTPUT_TLS_COMMON): Use rs6000_xcoff_asm_output_aligned_decl_common. gcc/testsuite/ChangeLog: * g++.dg/ext/visibility/fvisibility-inlines-hidden-4.C: Expect [BS] mapping class on AIX. * gcc.c-torture/compile/pr61159.c: XFAIL on AIX. * gcc.c-torture/execute/alias-2.c: Same. * gcc.dg/alias-7.c: Same. --- gcc/testsuite/gcc.dg/alias-7.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/alias-7.c b/gcc/testsuite/gcc.dg/alias-7.c index 591c302..e0c24bd 100644 --- a/gcc/testsuite/gcc.dg/alias-7.c +++ b/gcc/testsuite/gcc.dg/alias-7.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-require-alias "" } */ /* { dg-options "-O2" } */ +/* { dg-skip-if "weak alias" { powerpc-ibm-aix* } } */ extern void abort (void); -- cgit v1.1 From ed3c43224cc4e378dbab066122bc63536ccb1276 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 3 May 2021 09:17:55 +0200 Subject: Perform reverse program order walk for GIMPLE DSE The following changes the post-dominator domwalk done by GIMPLE DSE to a reverse program order walk. This enables 2% more stmts do be DSEd during bootstrap and in particular for testcases like the one added where it is important to visit post dominators in a particular order. 2021-05-03 Richard Biener * tree-ssa-dse.c: Do not include domwalk.h but cfganal.h. (dse_dom_walker): Remove. (dse_dom_walker::dse_optimize_stmt): Rename... (dse_optimize_stmt): ... to this, pass in live_bytes sbitmap. (dse_dom_walker::before_dom_children): Inline ... (pass_dse::execute): ... here. Perform a reverse program order walk. * gcc.dg/tree-ssa/ssa-dse-41.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-41.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-41.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-41.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-41.c new file mode 100644 index 0000000..9128eea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-41.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-dse1" } */ + +int a[2]; +void foo(int i, int k) +{ + a[0] = i; + if (k) + a[0] = a[i] + k; + else + a[0] = a[i] + 3; + a[0] = 0; +} + +/* Only the last store remains. */ +/* { dg-final { scan-tree-dump-times " = " 1 "dse1" } } */ -- cgit v1.1 From 32955416d8040b1fa1ba21cd4179b3264e6c5bd6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 3 May 2021 12:07:58 +0200 Subject: Improve PHI handling in DSE This improves handling of PHI defs when walking uses in dse_classify_store to track two PHI defs. This happens when there are CFG merges and one PHI feeds into another. If we decide to want more then using a sbitmap for this might be the way to go. 2021-05-03 Richard Biener * tree-ssa-dse.c (dse_classify_store): Track two PHI defs. * gcc.dg/tree-ssa/ssa-dse-42.c: New testcase. * gcc.dg/pr81192.c: Disable DSE. --- gcc/testsuite/gcc.dg/pr81192.c | 4 +++- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-42.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-42.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c index 71bbc13..6cab605 100644 --- a/gcc/testsuite/gcc.dg/pr81192.c +++ b/gcc/testsuite/gcc.dg/pr81192.c @@ -1,4 +1,4 @@ -/* { dg-options "-Os -fdump-tree-pre-details -fdisable-tree-evrp" } */ +/* { dg-options "-Os -fdump-tree-pre-details -fdisable-tree-evrp -fno-tree-dse" } */ /* Disable tree-evrp because the new version of evrp sees : @@ -16,6 +16,8 @@ produces # iftmp.2_12 = PHI <2147483647(3), iftmp.2_11(4)> which causes the situation being tested to dissapear before we get to PRE. */ +/* Likewise disable DSE which also elides the tail merging "opportunity". */ + #if __SIZEOF_INT__ == 2 #define unsigned __UINT32_TYPE__ #define int __INT32_TYPE__ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-42.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-42.c new file mode 100644 index 0000000..34108c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-42.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-dse1" } */ + +int a[2]; +void foo(int i, int k, int j) +{ + a[0] = i; + if (k) + a[0] = a[i] + k; + else + { + if (j) + a[1] = 1; + a[0] = a[i] + 3; + } + a[0] = 0; +} + +/* The last stores to a[0] and a[1] remain. */ +/* { dg-final { scan-tree-dump-times " = " 2 "dse1" } } */ -- cgit v1.1 From e2c378a5ef42744c3d6bebce8b0f028f59f65b35 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 May 2021 08:52:57 -0600 Subject: Fix test results on cr16 and xstormy16 gcc/testsuite * gcc.dg/tree-ssa/ssa-dse-26.c: Update expected output for cr16 and xstormy16 targets. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index 271e666..1321fec 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -31,8 +31,8 @@ constraint_equal (struct constraint a, struct constraint b) } /* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* } } } } } */ /* The c6x port generates significantly different gimple which changes the SRA and DSE decisions. Verify we remove all @@ -42,3 +42,6 @@ constraint_equal (struct constraint a, struct constraint b) /* { dg-final { scan-tree-dump-times "Deleted dead store: x::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ /* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ +/* And more special cases +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-*} } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-*} } } */ -- cgit v1.1 From b4579166f8f0e8d171d9cdb05c6cbf469c1c3e38 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 May 2021 09:07:41 -0600 Subject: Fix test results on or1k gcc/testsuite * gcc.dg/tree-ssa/ssa-dse-26.c: Update expected output for or1k too. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index 1321fec..ff3c36b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -31,8 +31,8 @@ constraint_equal (struct constraint a, struct constraint b) } /* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } } } */ /* The c6x port generates significantly different gimple which changes the SRA and DSE decisions. Verify we remove all @@ -43,5 +43,5 @@ constraint_equal (struct constraint a, struct constraint b) /* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ /* And more special cases -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-*} } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-*} } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } */ -- cgit v1.1 From 8a359a3375198c73f55d272d2ea7fe0207851af9 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 May 2021 09:18:01 -0600 Subject: Fix test results on rx gcc/testsuite * gcc.dg/tree-ssa/ssa-dse-26.c: Update expected output for rx too. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index ff3c36b..f9b54c6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -31,8 +31,8 @@ constraint_equal (struct constraint a, struct constraint b) } /* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } } } */ /* The c6x port generates significantly different gimple which changes the SRA and DSE decisions. Verify we remove all @@ -43,5 +43,5 @@ constraint_equal (struct constraint a, struct constraint b) /* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ /* And more special cases -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } */ -- cgit v1.1 From 0871fe27c24481d3ab5e9b4f40ac2e6629e2dc99 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 May 2021 09:35:30 -0600 Subject: Fix xstormy16 selector gcc/testsuite * gcc.dg/tree-ssa/ssa-dse-26.c: Fix xstormy selector. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index f9b54c6..c39fc8b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -31,8 +31,8 @@ constraint_equal (struct constraint a, struct constraint b) } /* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } } } */ /* The c6x port generates significantly different gimple which changes the SRA and DSE decisions. Verify we remove all @@ -43,5 +43,5 @@ constraint_equal (struct constraint a, struct constraint b) /* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ /* And more special cases -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16-*-*-* or1k*-*-* rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } */ -- cgit v1.1 From 34b51ea7184ebc651b39037dfea14f08722314b1 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 May 2021 11:05:19 -0600 Subject: Fix expected output for lm32 and bfin gcc/testsuite * gcc.dg/tree-ssa/ssa-dse-26.c: Fix expected output for bfin and lm32. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index c39fc8b..a82f311 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -31,8 +31,8 @@ constraint_equal (struct constraint a, struct constraint b) } /* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* lm32*-*-* bfin*-*-* rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* rx*-*-* } } } } } */ /* The c6x port generates significantly different gimple which changes the SRA and DSE decisions. Verify we remove all @@ -43,5 +43,5 @@ constraint_equal (struct constraint a, struct constraint b) /* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ /* And more special cases -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* rx*-*-* } } } */ -- cgit v1.1 From 2c339b2a590a1d096fe7495383cc476d1346c2e7 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 May 2021 12:30:50 -0600 Subject: Fix expected output for nds32le and m32r gcc/testsuite * gcc.dg/tree-ssa/ssa-dse-26.c: Fix expected output for nds32le and m32r. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index a82f311..4011daf 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -31,8 +31,8 @@ constraint_equal (struct constraint a, struct constraint b) } /* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* lm32*-*-* bfin*-*-* rx*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* lm32*-*-* bfin*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } } } */ /* The c6x port generates significantly different gimple which changes the SRA and DSE decisions. Verify we remove all @@ -43,5 +43,5 @@ constraint_equal (struct constraint a, struct constraint b) /* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ /* And more special cases -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* rx*-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } */ -- cgit v1.1 From 2326627eb19d8c21251fd60479f1a190621c475b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 4 May 2021 09:18:11 +0200 Subject: tree-optimization/100398 - avoid DSE of control flow stmt The following makes sure to preserve control altering stmts when removing trivially dead stmts in DSE. 2021-05-04 Richard Biener PR tree-optimization/100398 * tree-ssa-dse.c (pass_dse::execute): Preserve control altering stmts. * gcc.dg/torture/pr100398.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100398.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100398.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100398.c b/gcc/testsuite/gcc.dg/torture/pr100398.c new file mode 100644 index 0000000..41eadde --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100398.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +int +test5_limit (void) +{ + int addr; + + asm goto ("" : "+r" (addr) : : : t_err); + return 0; + + t_err: + return 1; +} -- cgit v1.1 From a310bb73edc9548e08d1fa28e7a56246caf27757 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 4 May 2021 10:07:35 +0200 Subject: tree-optimization/100329 - avoid reassociating asm goto defs This avoids reassociating asm goto defs because we have no idea on which outgoing edge to insert defs. 2021-05-04 Richard Biener PR tree-optimization/100329 * tree-ssa-reassoc.c (can_reassociate_p): Do not reassociate asm goto defs. (insert_stmt_after): Assert we're not running into asm goto. * gcc.dg/torture/pr100329.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100329.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100329.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100329.c b/gcc/testsuite/gcc.dg/torture/pr100329.c new file mode 100644 index 0000000..b90700d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100329.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "--param tree-reassoc-width=2" } */ + +unsigned int a0; + +unsigned int +foo (unsigned int a1, unsigned int a2) +{ + unsigned int x; + + asm goto ("" : "=r" (x) : : : lab); + a0 = x; + + lab: + return x + a1 + a2 + 1; +} -- cgit v1.1 From 1b0f570009825ce53a3967ea9a92b1961b7c122b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 4 May 2021 11:35:24 +0200 Subject: Restrict gcc.dg/tree-ssa/ssa-dse-26.c This restricts the testcase to the target where it exposes the situation fixed with g:e9d297a15d68121ba5bdd5a76ea71c1916180622 which targets BIT_FIELD_REFs created by fold_truth_andor. This avoids strange dejagnu limits with overly long target lists and simplifies the tests. 2021-05-04 Richard Biener * gcc.dg/tree-ssa/ssa-dse-26.c: Skip on !lp64 targets, simplify dump scanning down to one case. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index 4011daf..5eabfb4 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-dse1-details -fno-short-enums -fno-tree-fre" } */ -/* { dg-skip-if "temporary variable for constraint_expr is never used" { msp430-*-* } } */ +/* { dg-skip-if "we want a BIT_FIELD_REF from fold_truth_andor" { ! lp64 } } */ enum constraint_expr_type { @@ -30,18 +30,5 @@ constraint_equal (struct constraint a, struct constraint b) && constraint_expr_equal (a.rhs, b.rhs); } -/* Most targets should be using this test. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* lm32*-*-* bfin*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } } } */ - -/* The c6x port generates significantly different gimple which - changes the SRA and DSE decisions. Verify we remove all - dead stores. Similarly for mmix. */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: \[ax\].. = " 2 "dse1" { target tic6x-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: \[by\].. = " 2 "dse1" { target tic6x-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: x::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */ - -/* And more special cases -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" { target cr16*-*-* xstormy16*-*-* or1k*-*-* bfin*-*-* lm32*-*-* m32r*-*-* nds32le-elf rx*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" } } */ -- cgit v1.1 From 1580fc764423bf89e9b853aaa8c65999e37ccb8b Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 4 May 2021 13:38:03 +0200 Subject: OpenMP: Support complex/float in && and || reduction C/C++ permit logical AND and logical OR also with floating-point or complex arguments by doing an unequal zero comparison; the result is an 'int' with value one or zero. Hence, those are also permitted as reduction variable, even though it is not the most sensible thing to do. gcc/c/ChangeLog: * c-typeck.c (c_finish_omp_clauses): Accept float + complex for || and && reductions. gcc/cp/ChangeLog: * semantics.c (finish_omp_reduction_clause): Accept float + complex for || and && reductions. gcc/ChangeLog: * omp-low.c (lower_rec_input_clauses, lower_reduction_clauses): Handle && and || with floating-point and complex arguments. gcc/testsuite/ChangeLog: * gcc.dg/gomp/clause-1.c: Use 'reduction(&:..)' instead of '...(&&:..)'. libgomp/ChangeLog: * testsuite/libgomp.c-c++-common/reduction-1.c: New test. * testsuite/libgomp.c-c++-common/reduction-2.c: New test. * testsuite/libgomp.c-c++-common/reduction-3.c: New test. --- gcc/testsuite/gcc.dg/gomp/clause-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/clause-1.c b/gcc/testsuite/gcc.dg/gomp/clause-1.c index 9d34b041..8e7cc95 100644 --- a/gcc/testsuite/gcc.dg/gomp/clause-1.c +++ b/gcc/testsuite/gcc.dg/gomp/clause-1.c @@ -56,7 +56,7 @@ foo (int x) ; #pragma omp p reduction (|:d) /* { dg-error "has invalid type for" } */ ; -#pragma omp p reduction (&&:d) /* { dg-error "has invalid type for" } */ +#pragma omp p reduction (&:d) /* { dg-error "has invalid type for" } */ ; #pragma omp p copyin (d) /* { dg-error "must be 'threadprivate'" } */ ; -- cgit v1.1 From 7a3897661151cf8cc77d11f7a98fc64259210748 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 4 May 2021 13:39:14 +0200 Subject: tree-optimization/100414 - compute dominance info in phiopt phiopt now has dominator queries but fails to compute dominance info. 2021-05-04 Richard Biener PR tree-optimization/100414 * tree-ssa-phiopt.c (get_non_trapping): Do not compute dominance info here. (tree_ssa_phiopt_worker): But unconditionally here. * gcc.dg/pr100414.c: New testcase. --- gcc/testsuite/gcc.dg/pr100414.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100414.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100414.c b/gcc/testsuite/gcc.dg/pr100414.c new file mode 100644 index 0000000..7876f6b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100414.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fno-tree-dce -fno-tree-dse -fchecking" } */ + +int i; +void +foo (void) +{ + i &= i && __builtin_bswap16 (i); +} -- cgit v1.1 From 141cce5c2cc16b6846417790dfa01f61389ddbb3 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 4 May 2021 10:21:20 -0600 Subject: Adjust strings in dg-warning directives (PR testsuite/100412). gcc/testsuite/ChangeLog: * gcc.dg/Wvla-parameter-2.c: Use unique strings in directive names. --- gcc/testsuite/gcc.dg/Wvla-parameter-2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-2.c b/gcc/testsuite/gcc.dg/Wvla-parameter-2.c index 01728e7..daa71d8 100644 --- a/gcc/testsuite/gcc.dg/Wvla-parameter-2.c +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-2.c @@ -37,14 +37,14 @@ void f (int[n1][2][n3][4][n5][6][n7][8][n9]); /* Due to a limitation and because [*] is represented the same as [0] only the most significant array bound is rendered as [*]; the others are rendered as [0]. */ -void f (int[n1][2][n3][4][n5][6][n7][8][*]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[\\\*]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-* } } -// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[0]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 } -void f (int[n1][2][n3][4][n5][6][*][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[\\\*]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-* } } -// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[0]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 } -void f (int[n1][2][n3][4][*][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[\\\*]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-*} } -// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[0]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 } -void f (int[n1][2][*][4][n5][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[\\\*]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-* } } -// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[0]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 } +void f (int[n1][2][n3][4][n5][6][n7][8][*]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[\\\*]' declared with 1 unspecified variable bound" "pr100420 (expected)" { xfail *-*-* } } +// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[0]' declared with 1 unspecified variable bound" "pr100420" { target *-*-* } .-1 } +void f (int[n1][2][n3][4][n5][6][*][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[\\\*]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr100420 (expected)" { xfail *-*-* } } +// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[0]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr100420" { target *-*-* } .-1 } +void f (int[n1][2][n3][4][*][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[\\\*]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr100420 (expected)" { xfail *-*-*} } +// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[0]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr100420" { target *-*-* } .-1 } +void f (int[n1][2][*][4][n5][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[\\\*]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr100420 (expected)" { xfail *-*-* } } +// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[0]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr100420" { target *-*-* } .-1 } void f (int[*][2][n3][4][n5][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[\\\*]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" } void f (int[n1][n2][n3][n4][n5][n6][n7][n8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[n2]\\\[n3]\\\[n4]\\\[n5]\\\[n6]\\\[n7]\\\[n8]\\\[n9]' declared with 9 variable bounds" } -- cgit v1.1 From 78624756f7cfa3870c4b8c4c383bca1c9cbb6918 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 4 May 2021 11:10:40 -0600 Subject: Adjust strings in dg-warning directives (PR testsuite/100412). gcc/testsuite/ChangeLog: * gcc.dg/Wvla-parameter-3.c: Use unique strings in directive names. --- gcc/testsuite/gcc.dg/Wvla-parameter-3.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-3.c b/gcc/testsuite/gcc.dg/Wvla-parameter-3.c index 51f0172..f1cf139 100644 --- a/gcc/testsuite/gcc.dg/Wvla-parameter-3.c +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-3.c @@ -25,19 +25,19 @@ void ppax (int (**)[*]); // { dg-message "previously declared as void ppax (int (**)[n]); // { dg-warning "\\\[-Wvla-parameter" } /* A VLA with an unspecified bound is represented the same as [0] so so the pretty printer can't differentiate between the two forms. */ -void ppax (int (**)[1]); // { dg-bogus "\\\[-Warray-parameter" "pr?????" { xfail *-*-* } } - // { dg-warning "\\\[-Wvla-parameter" "pr?????" { xfail *-*-* } .-1 } +void ppax (int (**)[1]); // { dg-bogus "\\\[-Warray-parameter" "pr100420 (expected)" { xfail *-*-* } } + // { dg-warning "\\\[-Wvla-parameter" "pr100420 (expected)" { xfail *-*-* } .-1 } void ppax (int (**)[n + 1]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int *\\\(\\\*\\\*\\\)\\\[n \\\+ 1\\\]'" } void pa1_n (int (*)[1][n]); void pa1_n (int (*)[1][n]); -void pa1_n (int (*)[*][n]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[\\\*]\\\[n]'" "pr?????" { xfail *-*-*} } - // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[0]\\\[n]'" "pr?????" { target *-*-* } .-1 } +void pa1_n (int (*)[*][n]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[\\\*]\\\[n]'" "pr100420 (expected)" { xfail *-*-*} } + // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[0]\\\[n]'" "pr100420" { target *-*-* } .-1 } void pa1_n_2 (int (*)[1][n][2]); -void pa1_n_2 (int (*)[1][n][*]); // { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[\\\*]'" "pr?????" { xfail *-*-* } } - // { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[0]'" "pr?????" { target *-*-* } .-1 } +void pa1_n_2 (int (*)[1][n][*]); // { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[\\\*]'" "pr100420 (expected)" { xfail *-*-* } } + // { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[0]'" "pr100420" { target *-*-* } .-1 } void pa1_n_2_a1_n_2 (int (*)[1][n][2], int (*)[1][n][2]); -- cgit v1.1 From 158cdc7bd97d7ccca5bc8adaaf80fe51eacdc038 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 4 May 2021 13:46:37 -0600 Subject: PR middle-end/100307 - spurious -Wplacement-new with negative pointer offset gcc/ChangeLog: PR middle-end/100307 * builtins.c (compute_objsize_r): Clear base0 for pointers. gcc/testsuite/ChangeLog: PR middle-end/100307 * g++.dg/warn/Wplacement-new-size-9.C: New test. * gcc.dg/tree-ssa/builtin-sprintf-warn-26.c: New test. --- .../gcc.dg/tree-ssa/builtin-sprintf-warn-26.c | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c new file mode 100644 index 0000000..16a551d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c @@ -0,0 +1,38 @@ +/* PR middle-end/100307 - spurious -Wplacement-new with negative pointer + offset + { dg-do compile } + { dg-options "-O0 -Wall" } */ + +extern int sprintf (char*, const char*, ...); + +char a[4]; + +void nowarn_1m1 () +{ + char *p = a + 1; + sprintf (p - 1, "%i", 123); // { dg-bogus "-Wformat-overflow" } +} + +void nowarn_4m3 () +{ + char *p = a + 4; + sprintf (p - 3, "%i", 12); // { dg-bogus "-Wformat-overflow" } +} + +void warn_2m1 () +{ + char *p = a + 2; + sprintf (p - 1, "%i", 123); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } +} + +void warn_3m1 () +{ + char *p = a + 3; + sprintf (p - 1, "%i", 12); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } +} + +void warn_4m1 () +{ + char *p = a + 4; + sprintf (p - 1, "%i", 1); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } +} -- cgit v1.1 From d846f225c25c5885250c303c8d118caa08c447ab Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 4 May 2021 15:51:20 +0200 Subject: tree-optimization/79333 - fold stmts following SSA edges in VN This makes sure to follow SSA edges when folding eliminated stmts. This reaps the same benefit as forwprop folding all stmts, not waiting for one to produce copysign in the new testcase. 2021-05-04 Richard Biener PR tree-optimization/79333 * tree-ssa-sccvn.c (eliminate_dom_walker::eliminate_stmt): Fold stmt following SSA edges. * gcc.dg/tree-ssa/ssa-fre-94.c: New testcase. * gcc.dg/graphite/fuse-1.c: Adjust. * gcc.dg/pr43864-4.c: Likewise. --- gcc/testsuite/gcc.dg/graphite/fuse-1.c | 4 ++-- gcc/testsuite/gcc.dg/pr43864-4.c | 6 +++--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/graphite/fuse-1.c b/gcc/testsuite/gcc.dg/graphite/fuse-1.c index 204d3b2..527b6e5 100644 --- a/gcc/testsuite/gcc.dg/graphite/fuse-1.c +++ b/gcc/testsuite/gcc.dg/graphite/fuse-1.c @@ -1,6 +1,6 @@ /* Check that the two loops are fused and that we manage to fold the two xor operations. */ -/* { dg-options "-O2 -floop-nest-optimize -fdump-tree-forwprop-all -fdump-tree-graphite-all" } */ +/* { dg-options "-O2 -floop-nest-optimize -fdump-tree-forwprop4 -fdump-tree-graphite-all" } */ /* Make sure we fuse the loops like this: AST generated by isl: @@ -12,7 +12,7 @@ for (int c0 = 0; c0 <= 99; c0 += 1) { /* { dg-final { scan-tree-dump-times "AST generated by isl:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*\\}" 1 "graphite" } } */ /* Check that after fusing the loops, the scalar computation is also fused. */ -/* { dg-final { scan-tree-dump-times "gimple_simplified to\[^\\n\]*\\^ 12" 1 "forwprop4" } } */ +/* { dg-final { scan-tree-dump-times " \\^ 12;" 2 "forwprop4" } } */ #define MAX 100 int A[MAX]; diff --git a/gcc/testsuite/gcc.dg/pr43864-4.c b/gcc/testsuite/gcc.dg/pr43864-4.c index 3c6cc50..8a25b0f 100644 --- a/gcc/testsuite/gcc.dg/pr43864-4.c +++ b/gcc/testsuite/gcc.dg/pr43864-4.c @@ -22,7 +22,7 @@ int f(int c, int b, int d) return r - r2; } -/* { dg-final { scan-tree-dump-times "if " 0 "pre"} } */ -/* { dg-final { scan-tree-dump-times "(?n)_.*\\+.*_" 1 "pre"} } */ -/* { dg-final { scan-tree-dump-times "(?n)_.*-.*_" 2 "pre"} } */ +/* During PRE elimination we should simplify this to return b * 2. */ +/* { dg-final { scan-tree-dump-times "if " 0 "pre" } } */ +/* { dg-final { scan-tree-dump "_\[0-9\]+ = b_\[0-9\]+\\(D\\) \\* 2;\[\\r\\n\]\[^\\r\\n\]*return _\[0-9\]+;" "pre" } } */ /* { dg-final { scan-tree-dump-not "Invalid sum" "pre"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c new file mode 100644 index 0000000..92eebf6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/79333 */ +/* { dg-do compile } */ +/* { dg-options "-O -ffinite-math-only -fdump-tree-fre1" } */ + +extern __inline __attribute__ ((__always_inline__,__gnu_inline__)) +double __attribute__ ((__nothrow__ , __leaf__)) +fabs (double __x) { return __builtin_fabs (__x); } + +double f(float f) +{ + double t1 = fabs(f); + double t2 = f / t1; + return t2; +} + +/* { dg-final { scan-tree-dump "copysign" "fre1" } } */ -- cgit v1.1 From 3db6989aba707708f4fca3ff1bc92c4078b5c4cc Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Tue, 27 Apr 2021 17:11:54 +0200 Subject: testsuite: Add s390 to gcc.dg/vect/slp-21.c On s390 we vectorize 4 statements using SLP. Add s390*-*-* to the appropriate dg-finals. gcc/testsuite/ChangeLog: * gcc.dg/vect/slp-21.c: Add s390. --- gcc/testsuite/gcc.dg/vect/slp-21.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/slp-21.c b/gcc/testsuite/gcc.dg/vect/slp-21.c index 8539397..4b83adb 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-21.c +++ b/gcc/testsuite/gcc.dg/vect/slp-21.c @@ -210,7 +210,7 @@ int main (void) Not all vect_perm targets support that, and it's a bit too specific to have its own effective-target selector, so we just test targets directly. */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target powerpc64*-*-* } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! powerpc64*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { powerpc64*-*-* s390*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! { powerpc64*-*-* s390*-*-* } } } } } } */ /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { ! { vect_strided4 } } } } } */ -- cgit v1.1 From f3661f2d63fbc5fd30c24d22137691e16b0a0a17 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 5 May 2021 15:07:25 +0200 Subject: i386: Implement integer vector compares for 64bit vectors [PR98218] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement integer vector compares for 64bit vectors for TARGET_MMX_WITH_SSE. 2021-05-05 Uroš Bizjak gcc/ PR target/98218 * config/i386/i386-expand.c (ix86_expand_int_sse_cmp): Handle V8QI, V4HI and V2SI modes. * config/i386/i386.c (ix86_build_const_vector): Handle V2SImode. (ix86_build_signbit_mask): Ditto. * config/i386/mmx.md (MMXMODE14): New mode iterator. (3): New expander. (*mmx_3): New insn pattern. (3): New expander. (*mmx_3): New insn pattern. (vec_cmp): New expander. (vec_cmpu): Ditto. (vcond): Ditto. (vcondu): Ditto. (vcond_mask_): Ditto. gcc/testsuite/ PR target/98218 * gcc.target/i386/pr98218-1.c: New test. * gcc.target/i386/pr98218-1a.c: Ditto. * gcc.target/i386/pr98218-2.c: Ditto. * gcc.target/i386/pr98218-2a.c: Ditto. * gcc.target/i386/pr98218-3.c: Ditto. * gcc.target/i386/pr98218-3a.c: Ditto. * gcc.dg/vect/vect-bool-cmp.c (dg-final): Scan vect tree dump for "LOOP VECTORIZED", not VECTORIZED. --- gcc/testsuite/gcc.dg/vect/vect-bool-cmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-cmp.c b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp.c index 35d2a3c..c97da52 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bool-cmp.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp.c @@ -253,4 +253,4 @@ main (int argc, char **argv) check (res, ne); } -/* { dg-final { scan-tree-dump-times "VECTORIZED" 18 "vect" { target sse4_runtime } } } */ +/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 18 "vect" { target sse4_runtime } } } */ -- cgit v1.1 From 2254b3233b5bfa690e8c6e6fa923e4626a6a93d3 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 5 May 2021 11:07:39 -0600 Subject: PR middle-end/100325 - missing warning with -O0 on sprintf overflow with pointer plus offset gcc/ChangeLog: * passes.def (pass_warn_printf): Run after SSA. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/builtin-sprintf-warn-26.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c index 16a551d..677b634 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c @@ -22,17 +22,17 @@ void nowarn_4m3 () void warn_2m1 () { char *p = a + 2; - sprintf (p - 1, "%i", 123); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } + sprintf (p - 1, "%i", 123); // { dg-warning "-Wformat-overflow" "pr100325" } } void warn_3m1 () { char *p = a + 3; - sprintf (p - 1, "%i", 12); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } + sprintf (p - 1, "%i", 12); // { dg-warning "-Wformat-overflow" "pr100325" } } void warn_4m1 () { char *p = a + 4; - sprintf (p - 1, "%i", 1); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } + sprintf (p - 1, "%i", 1); // { dg-warning "-Wformat-overflow" "pr100325" } } -- cgit v1.1 From b5254d6b75fe6be669396cd1261f1cba829cc451 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 5 May 2021 10:15:27 +0200 Subject: ipa/100373 - fix emutls lowering compare-debug issue emutls figured that tls uses in debug-insns need lowering but that obviously has effects on code-generation as can be seen in the following IL diff with the new testcase: [local count: 1073741824]: - a = 0; + # DEBUG BEGIN_STMT _4 = __builtin___emutls_get_address (&__emutls_v.b); + # DEBUG D#1 => *_4 + # DEBUG d => (long int) D#1 + # DEBUG BEGIN_STMT + a = 0; + # DEBUG BEGIN_STMT *_4 = 0; return; where it figured the debug use of b in the original [local count: 1073741824]: # DEBUG BEGIN_STMT # DEBUG D#1 => b # DEBUG d => (long int) D#1 # DEBUG BEGIN_STMT a = 0; needs lowering (it maybe does when we want to produce perfect debug but that's just bad luck). The following patch fixes this by avoiding to create a new emutls address when visiting debug stmts and instead resets them. Another option might be to simply not lower debug stmt uses but I have no way to verify actual debug info for this. 2021-05-05 Richard Biener PR ipa/100373 * tree-emutls.c (gen_emutls_addr): Pass in whether we're dealing with a debug use and only query existing addresses if so. (lower_emutls_1): Avoid splitting out addresses for debug stmts, reset the debug stmt when we fail to find existing lowered addresses. (lower_emutls_phi_arg): Set wi.stmt. * gcc.dg/pr100373.c: New testcase. --- gcc/testsuite/gcc.dg/pr100373.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100373.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100373.c b/gcc/testsuite/gcc.dg/pr100373.c new file mode 100644 index 0000000..d4cd52a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100373.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcompare-debug" } */ + +int a; +_Thread_local int b; +void c() +{ + long d = b; + a = 0; + b = 0; +} -- cgit v1.1 From ad96c867e173c1ebcfc201b201adac5095683a08 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 May 2021 10:15:40 +0200 Subject: phiopt: Optimize (x <=> y) cmp z [PR94589] genericize_spaceship genericizes i <=> j to approximately ({ int c; if (i == j) c = 0; else if (i < j) c = -1; else c = 1; c; }) for strong ordering and ({ int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; c; }) for partial ordering. The C++ standard supports then == or != comparisons of that against strong/partial ordering enums, or />= comparisons of <=> result against literal 0. In some cases we already optimize that but in many cases we keep performing all the 2 or 3 comparisons, compute the spaceship value and then compare that. The following patch recognizes those patterns if the <=> operands are integral types or floating point (the latter only for -ffast-math) and optimizes it to the single comparison that is needed (plus adds debug stmts if needed for the spaceship result). There is one thing I'd like to address in a follow-up: the pr94589-2.C testcase should be matching just 12 times each, but runs into operator>=(partial_ordering, unspecified) being defined as (_M_value&1)==_M_value rather than _M_value>=0. When not honoring NaNs, the 2 case should be unreachable and so (_M_value&1)==_M_value is then equivalent to _M_value>=0, but is not a single use but two uses. I'll need to pattern match that case specially. 2021-05-06 Jakub Jelinek PR tree-optimization/94589 * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Call spaceship_replacement. (cond_only_block_p, spaceship_replacement): New functions. * gcc.dg/pr94589-1.c: New test. * gcc.dg/pr94589-2.c: New test. * gcc.dg/pr94589-3.c: New test. * gcc.dg/pr94589-4.c: New test. * g++.dg/opt/pr94589-1.C: New test. * g++.dg/opt/pr94589-2.C: New test. * g++.dg/opt/pr94589-3.C: New test. * g++.dg/opt/pr94589-4.C: New test. --- gcc/testsuite/gcc.dg/pr94589-1.c | 35 +++++++++++++++ gcc/testsuite/gcc.dg/pr94589-2.c | 35 +++++++++++++++ gcc/testsuite/gcc.dg/pr94589-3.c | 97 ++++++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr94589-4.c | 97 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 264 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr94589-1.c create mode 100644 gcc/testsuite/gcc.dg/pr94589-2.c create mode 100644 gcc/testsuite/gcc.dg/pr94589-3.c create mode 100644 gcc/testsuite/gcc.dg/pr94589-4.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr94589-1.c b/gcc/testsuite/gcc.dg/pr94589-1.c new file mode 100644 index 0000000..de404ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94589-1.c @@ -0,0 +1,35 @@ +/* PR tree-optimization/94589 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g0 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[45]" 14 "optimized" } } */ + +#define A __attribute__((noipa)) +A int f1 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == 0; } +A int f2 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != 0; } +A int f3 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c > 0; } +A int f4 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c < 0; } +A int f5 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c >= 0; } +A int f6 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c <= 0; } +A int f7 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == -1; } +A int f8 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != -1; } +A int f9 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c > -1; } +A int f10 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c <= -1; } +A int f11 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == 1; } +A int f12 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != 1; } +A int f13 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c < 1; } +A int f14 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c >= 1; } +A int f15 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == 0; } +A int f16 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != 0; } +A int f17 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c > 0; } +A int f18 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c < 0; } +A int f19 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c >= 0; } +A int f20 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c <= 0; } +A int f21 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == -1; } +A int f22 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != -1; } +A int f23 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c > -1; } +A int f24 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c <= -1; } +A int f25 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == 1; } +A int f26 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != 1; } +A int f27 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c < 1; } +A int f28 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c >= 1; } diff --git a/gcc/testsuite/gcc.dg/pr94589-2.c b/gcc/testsuite/gcc.dg/pr94589-2.c new file mode 100644 index 0000000..9481b76 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94589-2.c @@ -0,0 +1,35 @@ +/* PR tree-optimization/94589 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 5\\.0" 14 "optimized" } } */ + +#define A __attribute__((noipa)) +A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == 0; } +A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != 0; } +A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c > 0; } +A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c < 0; } +A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c >= 0; } +A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c <= 0; } +A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == -1; } +A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != -1; } +A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c > -1; } +A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c <= -1; } +A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == 1; } +A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != 1; } +A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c < 1; } +A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c >= 1; } +A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c == 0; } +A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c != 0; } +A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c > 0; } +A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c < 0; } +A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c >= 0; } +A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c <= 0; } +A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c == -1; } +A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c != -1; } +A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c > -1; } +A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c <= -1; } +A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c == 1; } +A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c != 1; } +A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c < 1; } +A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c >= 1; } diff --git a/gcc/testsuite/gcc.dg/pr94589-3.c b/gcc/testsuite/gcc.dg/pr94589-3.c new file mode 100644 index 0000000..df82fab --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94589-3.c @@ -0,0 +1,97 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -g" } */ + +#include "pr94589-1.c" + +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () + +int +main () +{ + C (f1, 7, 8, 0); + C (f1, 8, 8, 1); + C (f1, 9, 8, 0); + C (f2, 7, 8, 1); + C (f2, 8, 8, 0); + C (f2, 9, 8, 1); + C (f3, 7, 8, 0); + C (f3, 8, 8, 0); + C (f3, 9, 8, 1); + C (f4, 7, 8, 1); + C (f4, 8, 8, 0); + C (f4, 9, 8, 0); + C (f5, 7, 8, 0); + C (f5, 8, 8, 1); + C (f5, 9, 8, 1); + C (f6, 7, 8, 1); + C (f6, 8, 8, 1); + C (f6, 9, 8, 0); + C (f7, 7, 8, 1); + C (f7, 8, 8, 0); + C (f7, 9, 8, 0); + C (f8, 7, 8, 0); + C (f8, 8, 8, 1); + C (f8, 9, 8, 1); + C (f9, 7, 8, 0); + C (f9, 8, 8, 1); + C (f9, 9, 8, 1); + C (f10, 7, 8, 1); + C (f10, 8, 8, 0); + C (f10, 9, 8, 0); + C (f11, 7, 8, 0); + C (f11, 8, 8, 0); + C (f11, 9, 8, 1); + C (f12, 7, 8, 1); + C (f12, 8, 8, 1); + C (f12, 9, 8, 0); + C (f13, 7, 8, 1); + C (f13, 8, 8, 1); + C (f13, 9, 8, 0); + C (f14, 7, 8, 0); + C (f14, 8, 8, 0); + C (f14, 9, 8, 1); + D (f15, 4, 0); + D (f15, 5, 1); + D (f15, 6, 0); + D (f16, 4, 1); + D (f16, 5, 0); + D (f16, 6, 1); + D (f17, 4, 0); + D (f17, 5, 0); + D (f17, 6, 1); + D (f18, 4, 1); + D (f18, 5, 0); + D (f18, 6, 0); + D (f19, 4, 0); + D (f19, 5, 1); + D (f19, 6, 1); + D (f20, 4, 1); + D (f20, 5, 1); + D (f20, 6, 0); + D (f21, 4, 1); + D (f21, 5, 0); + D (f21, 6, 0); + D (f22, 4, 0); + D (f22, 5, 1); + D (f22, 6, 1); + D (f23, 4, 0); + D (f23, 5, 1); + D (f23, 6, 1); + D (f24, 4, 1); + D (f24, 5, 0); + D (f24, 6, 0); + D (f25, 4, 0); + D (f25, 5, 0); + D (f25, 6, 1); + D (f26, 4, 1); + D (f26, 5, 1); + D (f26, 6, 0); + D (f27, 4, 1); + D (f27, 5, 1); + D (f27, 6, 0); + D (f28, 4, 0); + D (f28, 5, 0); + D (f28, 6, 1); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr94589-4.c b/gcc/testsuite/gcc.dg/pr94589-4.c new file mode 100644 index 0000000..b2557fb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94589-4.c @@ -0,0 +1,97 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -g -ffast-math" } */ + +#include "pr94589-2.c" + +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () + +int +main () +{ + C (f1, 7.0, 8.0, 0); + C (f1, 8.0, 8.0, 1); + C (f1, 9.0, 8.0, 0); + C (f2, 7.0, 8.0, 1); + C (f2, 8.0, 8.0, 0); + C (f2, 9.0, 8.0, 1); + C (f3, 7.0, 8.0, 0); + C (f3, 8.0, 8.0, 0); + C (f3, 9.0, 8.0, 1); + C (f4, 7.0, 8.0, 1); + C (f4, 8.0, 8.0, 0); + C (f4, 9.0, 8.0, 0); + C (f5, 7.0, 8.0, 0); + C (f5, 8.0, 8.0, 1); + C (f5, 9.0, 8.0, 1); + C (f6, 7.0, 8.0, 1); + C (f6, 8.0, 8.0, 1); + C (f6, 9.0, 8.0, 0); + C (f7, 7.0, 8.0, 1); + C (f7, 8.0, 8.0, 0); + C (f7, 9.0, 8.0, 0); + C (f8, 7.0, 8.0, 0); + C (f8, 8.0, 8.0, 1); + C (f8, 9.0, 8.0, 1); + C (f9, 7.0, 8.0, 0); + C (f9, 8.0, 8.0, 1); + C (f9, 9.0, 8.0, 1); + C (f10, 7.0, 8.0, 1); + C (f10, 8.0, 8.0, 0); + C (f10, 9.0, 8.0, 0); + C (f11, 7.0, 8.0, 0); + C (f11, 8.0, 8.0, 0); + C (f11, 9.0, 8.0, 1); + C (f12, 7.0, 8.0, 1); + C (f12, 8.0, 8.0, 1); + C (f12, 9.0, 8.0, 0); + C (f13, 7.0, 8.0, 1); + C (f13, 8.0, 8.0, 1); + C (f13, 9.0, 8.0, 0); + C (f14, 7.0, 8.0, 0); + C (f14, 8.0, 8.0, 0); + C (f14, 9.0, 8.0, 1); + D (f15, 4.0, 0); + D (f15, 5.0, 1); + D (f15, 6.0, 0); + D (f16, 4.0, 1); + D (f16, 5.0, 0); + D (f16, 6.0, 1); + D (f17, 4.0, 0); + D (f17, 5.0, 0); + D (f17, 6.0, 1); + D (f18, 4.0, 1); + D (f18, 5.0, 0); + D (f18, 6.0, 0); + D (f19, 4.0, 0); + D (f19, 5.0, 1); + D (f19, 6.0, 1); + D (f20, 4.0, 1); + D (f20, 5.0, 1); + D (f20, 6.0, 0); + D (f21, 4.0, 1); + D (f21, 5.0, 0); + D (f21, 6.0, 0); + D (f22, 4.0, 0); + D (f22, 5.0, 1); + D (f22, 6.0, 1); + D (f23, 4.0, 0); + D (f23, 5.0, 1); + D (f23, 6.0, 1); + D (f24, 4.0, 1); + D (f24, 5.0, 0); + D (f24, 6.0, 0); + D (f25, 4.0, 0); + D (f25, 5.0, 0); + D (f25, 6.0, 1); + D (f26, 4.0, 1); + D (f26, 5.0, 1); + D (f26, 6.0, 0); + D (f27, 4.0, 1); + D (f27, 5.0, 1); + D (f27, 6.0, 0); + D (f28, 4.0, 0); + D (f28, 5.0, 0); + D (f28, 6.0, 1); + return 0; +} -- cgit v1.1 From 1e27ffde96b3967a3abfb4218a20e8ce75b04003 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Thu, 6 May 2021 15:52:48 +0200 Subject: testsuite: Add vect_floatint_cvt to gcc.dg/vect/pr56541.c pr56541.c converts a float vector to an int (bool) vector. Add vect_floatint_cvt in order to select the right targets. gcc/testsuite/ChangeLog: * gcc.dg/vect/pr56541.c: Add vect_floatint_cvt. --- gcc/testsuite/gcc.dg/vect/pr56541.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr56541.c b/gcc/testsuite/gcc.dg/vect/pr56541.c index d5def68..e1cee6d 100644 --- a/gcc/testsuite/gcc.dg/vect/pr56541.c +++ b/gcc/testsuite/gcc.dg/vect/pr56541.c @@ -24,4 +24,4 @@ void foo() } } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { ! vect_cond_mixed } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect_floatint_cvt } xfail { ! vect_cond_mixed } } } } */ -- cgit v1.1 From 717d278af93a4ab04ff30267888fc14fe0221799 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Wed, 5 May 2021 10:41:41 +0200 Subject: ipa-sra: Do not bail out when callers cannot be cloned IPA-SRA fails to produce (very simple) edge summaries when a caller cannot be cloned or its signature cannot be changed which makes it less powerful for no good reason. This patch fixes that problem. gcc/ChangeLog: 2021-04-12 Martin Jambor * ipa-sra.c (ipa_sra_dump_all_summaries): Dump edge summaries even when there is no function summary. (ipa_sra_summarize_function): produce edge summaries even when bailing out early. gcc/testsuite/ChangeLog: 2021-04-12 Martin Jambor * gcc.dg/ipa/ipa-sra-1.c (main): Revert change done by 05193687dde, make the argv again pointer to an array. --- gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c index df7e356..4a22e39 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c @@ -24,7 +24,7 @@ ox (struct bovid cow) } int -main (int argc, char **argv) +main (int argc, char *argv[]) { struct bovid cow; -- cgit v1.1 From 601191b2a48cb8f4657bb2fa2270a7fde9d52e9c Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Fri, 7 May 2021 15:52:35 +0000 Subject: tree-optimization/79333 - fold stmts following SSA edges in VN copysign is only available with c99_runtime, skip ssa-fre-94.c otherwise. 2021-05-07 Christophe Lyon PR tree-optimization/79333 gcc/testsuite/ * gcc.dg/tree-ssa/ssa-fre-94.c: Require c99_runtime. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c index 92eebf6..99c7375 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-94.c @@ -1,5 +1,6 @@ /* PR tree-optimization/79333 */ /* { dg-do compile } */ +/* { dg-require-effective-target c99_runtime } */ /* { dg-options "-O -ffinite-math-only -fdump-tree-fre1" } */ extern __inline __attribute__ ((__always_inline__,__gnu_inline__)) -- cgit v1.1 From e2bc5b6c04df820017c497a2578bd3c4c7b6c89b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 7 May 2021 20:44:36 +0200 Subject: Do not apply scalar storage order to pointer fields Pointer fields (and vector fields originally) were not really considered when the scalar_storage_order attribute, so they are swapped as well. As pointed out, this is problematic to describe in DWARF and probably not very useful in any case, so this pulls them out. gcc/ * doc/extend.texi (scalar_storage_order): Mention effect on pointer and vector fields. * tree.h (reverse_storage_order_for_component_p): Return false if the type is a pointer. gcc/c/ * c-typeck.c (build_unary_op) : Do not issue an error on the address of a pointer field in a record with reverse SSO. gcc/testsuite/ * gcc.dg/sso-12.c: New test. --- gcc/testsuite/gcc.dg/sso-12.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sso-12.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-12.c b/gcc/testsuite/gcc.dg/sso-12.c new file mode 100644 index 0000000..3bed280 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-12.c @@ -0,0 +1,27 @@ +/* Test scalar_storage_order attribute and pointer fields */ + +/* { dg-do run } */ +/* { dg-options "-Wno-pedantic" } */ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +struct __attribute__((scalar_storage_order("big-endian"))) Rec +{ + int *p; +}; +#else +struct __attribute__((scalar_storage_order("little-endian"))) Rec +{ + int *p; +}; +#endif + +int main (int argc) +{ + struct Rec r = { &argc }; + int *p = &argc; + + if (__builtin_memcmp (&r.p, &p, sizeof (int *)) != 0) + __builtin_abort (); + + return 0; +} -- cgit v1.1 From dddc07b4932a3b6e720cf32f0ff2ec2be356a8be Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sat, 8 May 2021 09:49:38 +0200 Subject: Remove obsolete gcc.dg/sso-9.c gcc/testsuite/ * gcc.dg/sso-9.c: Delete. --- gcc/testsuite/gcc.dg/sso-9.c | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/sso-9.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-9.c b/gcc/testsuite/gcc.dg/sso-9.c deleted file mode 100644 index 765f16a..0000000 --- a/gcc/testsuite/gcc.dg/sso-9.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Test support of scalar_storage_order attribute */ - -/* { dg-do compile } */ - -#include - -int x; - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -struct __attribute__((scalar_storage_order("big-endian"))) Rec -{ - va_list v; -}; -#else -struct __attribute__((scalar_storage_order("little-endian"))) Rec -{ - va_list v; -}; -#endif - -void foo (int i, ...) -{ - struct Rec a; - va_start (a.v, i); - a.v = 0, x = va_arg (a.v, int); /* { dg-error "type|reverse storage order" } */ - va_end (a.v); -} -- cgit v1.1 From a564da506f52be66ade298b562417641e87b549f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 5 May 2021 16:15:12 +0200 Subject: tree-optimization/100434 - DSE aggregate call LHS This makes DSE consider aggregate LHS of calls as dead, for pure or const calls the whole stmt and for others by removing the LHS. 2021-05-05 Richard Biener PR tree-optimization/100434 * tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle call LHS. (dse_optimize_stmt): Handle call LHS by dropping the LHS or the whole call if it doesn't have other side-effects. (pass_dse::execute): Adjust. * gcc.dg/tree-ssa/ssa-dse-43.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-43.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-43.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-43.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-43.c new file mode 100644 index 0000000..f8785e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-43.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-dse1-details" } */ + +struct X { int x; }; +struct X x; + +extern struct X foo (void); +void bar() +{ + x = foo(); + x = (struct X){}; +} + +extern struct X __attribute__((const)) foo2 (int); +void bar2() +{ + x = foo2 (1); + x = foo2 (2); +} + +/* { dg-final { scan-tree-dump-times "Deleted dead store in call LHS: x = foo " 1 "dse1" } } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: x = foo2 " 1 "dse1" } } */ -- cgit v1.1 From a076632e274abe344ca7648b7c7f299273d4cbe0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 7 May 2021 09:51:18 +0200 Subject: middle-end/100464 - avoid spurious TREE_ADDRESSABLE in folding debug stmts canonicalize_constructor_val was setting TREE_ADDRESSABLE on bases of ADDR_EXPRs but that's futile when we're dealing with CTOR values in debug stmts. This rips out the code which was added for Java and should have been an assertion when we didn't have debug stmts. To not regress g++.dg/tree-ssa/array-temp1.C we have to adjust the testcase to not look for a no longer applied invalid optimization. 2021-05-10 Richard Biener PR middle-end/100464 PR c++/100468 gcc/ * gimple-fold.c (canonicalize_constructor_val): Do not set TREE_ADDRESSABLE. gcc/cp/ * call.c (set_up_extended_ref_temp): Mark the temporary addressable if the TARGET_EXPR was. gcc/testsuite/ * gcc.dg/pr100464.c: New testcase. * g++.dg/tree-ssa/array-temp1.C: Adjust. --- gcc/testsuite/gcc.dg/pr100464.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100464.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100464.c b/gcc/testsuite/gcc.dg/pr100464.c new file mode 100644 index 0000000..46cc37df --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100464.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fcompare-debug" } */ + +int *a; +static int b, c, d, e, g, h; +int f; +void i() { + int *j[] = {&e, &b, &b, &d, &b, &b, &g, &e, &g, &b, &b, + &b, &b, &g, &e, &e, &b, &b, &d, &b, &b, &e, + &e, &g, &b, &b, &b, &b, &g, &e, &g, &c, &e}; + int **k = &j[5]; + for (; f;) + b |= *a; + *k = &h; +} +int main() {} -- cgit v1.1 From 60af2db18013a0339302928ba98fee893ccc1957 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 10 May 2021 11:37:27 +0200 Subject: tree-optimization/100492 - avoid irreducible regions in loop distribution When we distribute away a condition we rely on the ability to change it to either 1 != 0 or 0 != 0 depending on the direction of the exit branch in the respective loop. But when the loop contains an irreducible sub-region then for the conditions inside this this fails and can lead to infinite loops being generated. Avoid distibuting loops with irreducible sub-regions. 2021-05-10 Richard Biener PR tree-optimization/100492 * tree-loop-distribution.c (find_seed_stmts_for_distribution): Find nothing when the loop contains an irreducible region. * gcc.dg/torture/pr100492.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100492.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100492.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100492.c b/gcc/testsuite/gcc.dg/torture/pr100492.c new file mode 100644 index 0000000..75229c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100492.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-loop-distribution" } */ + +extern void abort (void); + +signed char a, c; +int b, d, *e = &d, g; +signed static char f; +int main() { + int h = 0; + int a_ = a; + for (; a_ < 1; a = ++a_) { + int *i[5], **j = &i[4], ***k[3][2] = {{&j}}, ****l = &k[2][1], *****m = &l; + char *n = &c; + f = *e = g = 0; + for (; g < 2; g++) { + for (b = 0; b < 3; b++) + h = (h && (*n = 0)) == 0; + if (g) + break; + } + } + if (f != 0) + abort (); + return 0; +} -- cgit v1.1 From 1f94ed3b4c308c9da7baf59ecbc0f953e994f9c4 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sat, 8 May 2021 07:23:25 -0700 Subject: Add a test for PR tree-optimization/42587 PR tree-optimization/42587 * gcc.dg/optimize-bswapsi-6.c: New test. --- gcc/testsuite/gcc.dg/optimize-bswapsi-6.c | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/optimize-bswapsi-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-6.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-6.c new file mode 100644 index 0000000..3c089b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-6.c @@ -0,0 +1,38 @@ +/* PR tree-optimization/42587 */ +/* { dg-do compile } */ +/* { dg-require-effective-target bswap } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ +/* { dg-additional-options "-march=z900" { target s390-*-* } } */ + +typedef unsigned char u8; +typedef unsigned int u32; +union __anonunion_out_195 +{ + u32 value; + u8 bytes[4]; +}; +union __anonunion_in_196 +{ + u32 value; + u8 bytes[4]; +}; +extern void acpi_ut_track_stack_ptr (void); +u32 acpi_ut_dword_byte_swap (u32 value); +u32 +acpi_ut_dword_byte_swap (u32 value) +{ + union __anonunion_out_195 out; + union __anonunion_in_196 in; + + { + acpi_ut_track_stack_ptr (); + in.value = value; + out.bytes[0] = in.bytes[3]; + out.bytes[1] = in.bytes[2]; + out.bytes[2] = in.bytes[1]; + out.bytes[3] = in.bytes[0]; + return (out.value); + } +} + +/* { dg-final { scan-tree-dump "32 bit bswap implementation found at" "store-merging" } } */ -- cgit v1.1 From f974b54b8a0c330e9dd2b43ebc940100d601df0f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 10 May 2021 14:00:04 -0600 Subject: Avoid -Walloca-larger-than and -Wvla-larger-than false postives and negatives. Resolves: PR middle-end/100425 - missing -Walloca-larger-than with -O0 PR middle-end/100510 - bogus -Wvla-large-than with -Walloca gcc/ChangeLog: PR middle-end/100425 PR middle-end/100510 * gimple-ssa-warn-alloca.c (pass_walloca::firast_time_p): Rename... (pass_walloca::xlimit_certain_p): ...to this. (pass_walloca::gate): Execute for any kind of handled warning. (pass_walloca::execute): Avoid issuing "maybe" and "unbounded" warnings when xlimit_certain_p is set. gcc/testsuite/ChangeLog: PR middle-end/100425 PR middle-end/100510 * c-c++-common/Walloca-larger-than.C: New test. * gcc.dg/Walloca-larger-than-4.c: New test. * gcc.dg/Wvla-larger-than-5.c: New test. * gcc.dg/pr79972.c: Remove unexpected warning directive. --- gcc/testsuite/gcc.dg/Walloca-larger-than-4.c | 18 +++++++++++++ gcc/testsuite/gcc.dg/Wvla-larger-than-5.c | 38 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr79972.c | 3 ++- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/Walloca-larger-than-4.c create mode 100644 gcc/testsuite/gcc.dg/Wvla-larger-than-5.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Walloca-larger-than-4.c b/gcc/testsuite/gcc.dg/Walloca-larger-than-4.c new file mode 100644 index 0000000..9d4c4e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Walloca-larger-than-4.c @@ -0,0 +1,18 @@ +/* PR middle-end/100425 - missing -Walloca-larger-than with -O0 + { dg-do compile } + { dg-options "-O0 -Wall -Walloca-larger-than=128" } */ + +typedef __SIZE_TYPE__ size_t; + +void* alloca (size_t); + +void sink (void*); + +void warn_alloca_too_large (void) +{ + sink (alloca (1)); + sink (alloca (128)); + sink (alloca (129)); // { dg-warning "\\\[-Walloca-larger-than" } + sink (alloca (128 + 2)); // { dg-warning "\\\[-Walloca-larger-than" } + sink (alloca (1024)); // { dg-warning "\\\[-Walloca-larger-than" } +} diff --git a/gcc/testsuite/gcc.dg/Wvla-larger-than-5.c b/gcc/testsuite/gcc.dg/Wvla-larger-than-5.c new file mode 100644 index 0000000..c131f83 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-larger-than-5.c @@ -0,0 +1,38 @@ +/* PR middle-end/100510 - bogus -Wvla-large-than with -Walloca + { dg-do compile } + { dg-options "-O0 -Walloca -Wvla-larger-than=1000" } */ + +void f (void*); + +#pragma GCC optimize ("0") + +void nowarn_O0 (__SIZE_TYPE__ n) +{ + if (n > 32) + return; + + char a[n]; // { dg-bogus "\\\[-Wvla-larger-than=" } + f (a); +} + +#pragma GCC optimize ("1") + +void nowarn_O1 (__SIZE_TYPE__ n) +{ + if (n > 33) + return; + + char a[n]; // { dg-bogus "\\\[-Wvla-larger-than=" } + f (a); +} + +#pragma GCC optimize ("2") + +void nowarn_O2 (__SIZE_TYPE__ n) +{ + if (n > 34) + return; + + char a[n]; // { dg-bogus "\\\[-Wvla-larger-than=" } + f (a); +} diff --git a/gcc/testsuite/gcc.dg/pr79972.c b/gcc/testsuite/gcc.dg/pr79972.c index 1d2b8be..4d3064f 100644 --- a/gcc/testsuite/gcc.dg/pr79972.c +++ b/gcc/testsuite/gcc.dg/pr79972.c @@ -6,7 +6,8 @@ int f (int dim, int *b, int *c) { - int newcentroid[3][dim]; /* { dg-warning "unbounded use of variable-length array" } */ + /* -Wvla-larger-than is only issued with optimization (see PR 100510). */ + int newcentroid[3][dim]; int *a = newcentroid[2]; int i, dist = 0; __builtin_memcpy (newcentroid, c, sizeof (newcentroid)); -- cgit v1.1 From ca8e8301180fa71de1a76769fc038df2ab85dfeb Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 11 May 2021 10:58:35 +0200 Subject: middle-end/100509 - avoid folding constant to aggregate type When folding a constant initializer looking through aliases to incompatible types can lead to us trying to fold a constant to an aggregate type which can't work. Simply avoid trying to constant fold non-register typed symbols. 2021-05-11 Richard Biener PR middle-end/100509 * gimple-fold.c (fold_gimple_assign): Only call get_symbol_constant_value on register type symbols. * gcc.dg/pr100509.c: New testcase. --- gcc/testsuite/gcc.dg/pr100509.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100509.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100509.c b/gcc/testsuite/gcc.dg/pr100509.c new file mode 100644 index 0000000..9405e2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100509.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +struct X { + int a; +}; +const int a = 0; +static struct X A __attribute__((alias("a"))); +void foo() { struct X b = A; } -- cgit v1.1 From 5ea40269a77a3754dd0f610f7c09b1a372e3c7f7 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 11 May 2021 14:25:55 +0000 Subject: preprocessor: Enable digit separators for C2X C2X adds digit separators, as in C++. Enable them accordingly in libcpp and c-lex.c. Some basic tests are added that digit separators behave as expected for C2X and are properly disabled for C11; further test coverage is included in the existing g++.dg/cpp1y/digit-sep*.C tests. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c-family/ * c-lex.c (interpret_float): Handle digit separators for C2X. libcpp/ * init.c (lang_defaults): Enable digit separators for GNUC2X and STDC2X. gcc/testsuite/ * gcc.dg/c11-digit-separators-1.c, gcc.dg/c2x-digit-separators-1.c, gcc.dg/c2x-digit-separators-2.c: New tests. --- gcc/testsuite/gcc.dg/c11-digit-separators-1.c | 7 +++++ gcc/testsuite/gcc.dg/c2x-digit-separators-1.c | 39 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-digit-separators-2.c | 25 +++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/c11-digit-separators-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-digit-separators-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-digit-separators-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/c11-digit-separators-1.c b/gcc/testsuite/gcc.dg/c11-digit-separators-1.c new file mode 100644 index 0000000..fc83226 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-digit-separators-1.c @@ -0,0 +1,7 @@ +/* Test C2x digit separators not in C11. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#define m(x) 0 + +_Static_assert (m(1'2)+(3'4) == 0, "digit separators"); diff --git a/gcc/testsuite/gcc.dg/c2x-digit-separators-1.c b/gcc/testsuite/gcc.dg/c2x-digit-separators-1.c new file mode 100644 index 0000000..6eadf2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-digit-separators-1.c @@ -0,0 +1,39 @@ +/* Test C2x digit separators. Valid usages. */ +/* { dg-do run } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +_Static_assert (123'45'6 == 123456); +_Static_assert (0'123 == 0123); +_Static_assert (0x1'23 == 0x123); + +#define m(x) 0 + +_Static_assert (m(1'2)+(3'4) == 34); + +_Static_assert (0x0'e-0xe == 0); + +#define a0 '.' - +#define acat(x) a ## x +_Static_assert (acat (0'.') == 0); + +#define c0(x) 0 +#define b0 c0 ( +#define bcat(x) b ## x +_Static_assert (bcat (0'\u00c0')) == 0); + +extern void exit (int); +extern void abort (void); + +int +main (void) +{ + if (314'159e-0'5f != 3.14159f) + abort (); + exit (0); +} + +#line 0'123 +_Static_assert (__LINE__ == 123); + +#line 4'56'7'8'9 +_Static_assert (__LINE__ == 456789); diff --git a/gcc/testsuite/gcc.dg/c2x-digit-separators-2.c b/gcc/testsuite/gcc.dg/c2x-digit-separators-2.c new file mode 100644 index 0000000..d72f8ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-digit-separators-2.c @@ -0,0 +1,25 @@ +/* Test C2x digit separators. Invalid usages. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +void +tf (void) +{ + int i; + i = 1''2; /* { dg-error "adjacent digit separators" } */ + i = 0x'0; /* { dg-error "digit separator after base indicator" } */ + i = 0X'1; /* { dg-error "digit separator after base indicator" } */ + i = 0b'0; /* { dg-error "digit separator after base indicator" } */ + i = 0B'1; /* { dg-error "digit separator after base indicator" } */ + i = 1'u; /* { dg-error "digit separator outside digit sequence" } */ + float f = 1.2e-3'f; /* { dg-error "digit separator outside digit sequence" } */ + i = 1'2'3'; /* { dg-error "12:missing terminating" } */ + ; + double d; + d = 1'.2'3e-4; /* { dg-warning "multi-character" } */ + /* { dg-error "expected" "parse error" { target *-*-* } .-1 } */ + d = 1.2''3; /* { dg-error "adjacent digit separators" } */ + d = 1.23e-4''5; /* { dg-error "adjacent digit separators" } */ + d = 1.2'3e-4'5'; /* { dg-error "17:missing terminating" } */ + /* { dg-error "expected" "parse error" { target *-*-* } .-1 } */ +} -- cgit v1.1 From 21dfb22920ce32fcf336eac4513fa44de28819e0 Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus Date: Tue, 11 May 2021 19:33:37 +0200 Subject: testsuite: Fix input operands of gcc.dg/guality/pr43077-1.c The type of the output operands *p and *q of the extended asm statement of function foo is unsigned long whereas the type of the corresponding input operands is int. This results, e.g. on IBM Z, in the case that the immediates 2 and 3 are written into registers in SI mode and read in DI mode resulting in wrong values. Fixed by lifting the input operands to type long. gcc/testsuite/ChangeLog: * gcc.dg/guality/pr43077-1.c: Align types of output and input operands by lifting immediates to type long. --- gcc/testsuite/gcc.dg/guality/pr43077-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/guality/pr43077-1.c b/gcc/testsuite/gcc.dg/guality/pr43077-1.c index 39bd26a..2d93762 100644 --- a/gcc/testsuite/gcc.dg/guality/pr43077-1.c +++ b/gcc/testsuite/gcc.dg/guality/pr43077-1.c @@ -24,7 +24,7 @@ int __attribute__((noinline)) foo (unsigned long *p, unsigned long *q) { int ret; - asm volatile ("" : "=r" (ret), "=r" (*p), "=r" (*q) : "0" (1), "1" (2), "2" (3)); + asm volatile ("" : "=r" (ret), "=r" (*p), "=r" (*q) : "0" (1), "1" (2l), "2" (3l)); return ret; } -- cgit v1.1 From 3e3fdf3d5217e5a2d075ca399b557b2e886dcd18 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 11 May 2021 18:54:32 +0000 Subject: preprocessor: Fix cpp_avoid_paste for digit separators The libcpp function cpp_avoid_paste is used to insert whitespace in preprocessed output where needed to avoid two consecutive preprocessing tokens, that logically (e.g. when stringized) do not have whitespace between them, from being incorrectly lexed as one when the preprocessed input is reread by a compiler. This fails to allow for digit separators, so meaning that invalid code, that has a CPP_NUMBER (from a macro expansion) followed by a character literal, can result in preprocessed output with a valid use of digit separators, so that required syntax errors do not occur when compiling with -save-temps. Fix this by handling that case in cpp_avoid_paste (as with other cases in cpp_avoid_paste, this doesn't try to check whether the language version in use supports digit separators; it's always OK to have unnecessary whitespace in preprocessed output). Note: there are other cases, with various kinds of wide character or string literal following a CPP_NUMBER, where spurious pasting of preprocessing tokens can occur but the sequence of tokens remains invalid both before and after that pasting. Maybe cpp_avoid_paste should also handle those cases (and similar cases after a CPP_NAME), to ensure the sequence of preprocessing tokens in preprocessed output is exactly right, whether or not it affects whether syntax errors occur. This patch only addresses the case with digit separators where invalid code can fail to be diagnosed without the space inserted. Bootstrapped with no regressions for x86_64-pc-linux-gnu. libcpp/ * lex.c (cpp_avoid_paste): Do not allow pasting CPP_NUMBER with CPP_CHAR. gcc/testsuite/ * g++.dg/cpp1y/digit-sep-paste.C, gcc.dg/c2x-digit-separators-3.c: New tests. --- gcc/testsuite/gcc.dg/c2x-digit-separators-3.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/c2x-digit-separators-3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/c2x-digit-separators-3.c b/gcc/testsuite/gcc.dg/c2x-digit-separators-3.c new file mode 100644 index 0000000..cddb88f --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-digit-separators-3.c @@ -0,0 +1,12 @@ +/* Test C2x digit separators. Test token pasting avoided for preprocessed + output. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -save-temps" } */ + +#define ZERO 0 + +int +f (void) +{ + return ZERO'0'0; /* { dg-error "expected" } */ +} -- cgit v1.1 From 71d38ec80008afdbb9a059253407d80598b765c0 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 11 May 2021 23:54:01 +0000 Subject: preprocessor: Support C2X #elifdef, #elifndef C2X adds #elifdef and #elifndef preprocessor directives; these have also been proposed for C++. Implement these directives in libcpp accordingly. In this implementation, #elifdef and #elifndef are treated as non-directives for any language version other than c2x and gnu2x (if the feature is accepted for C++, it can trivially be enabled for relevant C++ versions). In strict conformance modes for prior language versions, this is required, as illustrated by the c11-elifdef-1.c test added. Bootstrapped with no regressions for x86_64-pc-linux-gnu. libcpp/ * include/cpplib.h (struct cpp_options): Add elifdef. * init.c (struct lang_flags): Add elifdef. (lang_defaults): Update to include elifdef initializers. (cpp_set_lang): Set elifdef for pfile based on language. * directives.c (STDC2X, ELIFDEF): New macros. (EXTENSION): Increase value to 3. (DIRECTIVE_TABLE): Add #elifdef and #elifndef. (_cpp_handle_directive): Do not treat ELIFDEF directives as directives for language versions without the #elifdef feature. (do_elif): Handle #elifdef and #elifndef. (do_elifdef, do_elifndef): New functions. gcc/testsuite/ * gcc.dg/cpp/c11-elifdef-1.c, gcc.dg/cpp/c2x-elifdef-1.c, gcc.dg/cpp/c2x-elifdef-2.c: New tests. --- gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c | 16 ++++++++ gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c | 57 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c | 63 ++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c b/gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c new file mode 100644 index 0000000..2d5809a --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c11-elifdef-1.c @@ -0,0 +1,16 @@ +/* Test #elifdef and #elifndef not in C11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#define A +#undef B + +#if 0 +#elifdef A +#error "#elifdef A applied" +#endif + +#if 0 +#elifndef B +#error "#elifndef B applied" +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c new file mode 100644 index 0000000..b23e311 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-1.c @@ -0,0 +1,57 @@ +/* Test #elifdef and #elifndef in C2x. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#define A +#undef B + +#if 0 +#elifdef A +#define M1 1 +#endif + +#if M1 != 1 +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifdef B +#error "#elifdef B applied" +#endif + +#if 0 +#elifndef A +#error "#elifndef A applied" +#endif + +#if 0 +#elifndef B +#define M2 2 +#endif + +#if M2 != 2 +#error "#elifndef B did not apply" +#endif + +#if 0 +#elifdef A +#else +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifndef B +#else +#error "#elifndef B did not apply" +#endif + +/* As with #elif, the syntax of the new directives is relaxed after a + non-skipped group. */ + +#if 1 +#elifdef x * y +#endif + +#if 1 +#elifndef ! +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c new file mode 100644 index 0000000..9132832 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c2x-elifdef-2.c @@ -0,0 +1,63 @@ +/* Test #elifdef and #elifndef in C2x: erroneous usages. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#define A +#undef B + +#elifdef A /* { dg-error "#elifdef without #if" } */ +#elifdef B /* { dg-error "#elifdef without #if" } */ +#elifndef A /* { dg-error "#elifndef without #if" } */ +#elifndef B /* { dg-error "#elifndef without #if" } */ + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifdef A /* { dg-error "#elifdef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifdef B /* { dg-error "#elifdef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifndef A /* { dg-error "#elifndef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifndef B /* { dg-error "#elifndef after #else" } */ +#endif + +#if 0 +#elifdef A = /* { dg-error "extra tokens at end of #elifdef directive" } */ +#endif + +#if 0 +#elifdef B = /* { dg-error "extra tokens at end of #elifdef directive" } */ +#endif + +#if 0 +#elifndef A = /* { dg-error "extra tokens at end of #elifndef directive" } */ +#endif + +#if 0 +#elifndef B = /* { dg-error "extra tokens at end of #elifndef directive" } */ +#endif + +#if 0 +#elifdef /* { dg-error "no macro name given in #elifdef directive" } */ +#endif + +#if 0 +#elifndef /* { dg-error "no macro name given in #elifndef directive" } */ +#endif + +#if 0 +#elifdef , /* { dg-error "macro names must be identifiers" } */ +#endif + +#if 0 +#elifndef , /* { dg-error "macro names must be identifiers" } */ +#endif -- cgit v1.1 From f5f1838435400b837c8677c53a611e2dc6d56442 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 May 2021 09:46:03 +0200 Subject: match.pd: Optimize (x & y) == x into (x & ~y) == 0 [PR94589] > Somewhere in RTL (_M_value&1)==_M_value is turned into (_M_value&-2)==0, > that could be worth doing already in GIMPLE. Apparently it is /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or constant folding if x/y is a constant. */ if ((code == EQ || code == NE) && (op0code == AND || op0code == IOR) && !side_effects_p (op1) && op1 != CONST0_RTX (cmp_mode)) { /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to (eq/ne (and (not y) x) 0). */ ... /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to (eq/ne (and (not x) y) 0). */ Yes, doing that on GIMPLE for the case where the not argument is constant would simplify the phiopt follow-up (it would be single imm use then). On Thu, May 06, 2021 at 09:42:41PM +0200, Marc Glisse wrote: > We can probably do it in 2 steps, first something like > > (for cmp (eq ne) > (simplify > (cmp (bit_and:c @0 @1) @0) > (cmp (@0 (bit_not! @1)) { build_zero_cst (TREE_TYPE (@0)); }))) > > to get rid of the double use, and then simplify X&C==0 to X<=~C if C is a > mask 111...000 (I thought we already had a function to detect such masks, or > the 000...111, but I can't find them anymore). Ok, here is the first step then. 2021-05-12 Jakub Jelinek Marc Glisse PR tree-optimization/94589 * match.pd ((X & Y) == X -> (X & ~Y) == 0, (X | Y) == Y -> (X & ~Y) == 0): New GIMPLE simplifications. * gcc.dg/tree-ssa/pr94589-1.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c new file mode 100644 index 0000000..7e1aaaa --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94589-1.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/94589 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int x) +{ + return (x & 23) == x; +/* { dg-final { scan-tree-dump " & -24;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " & 23;" "optimized" } } */ +/* { dg-final { scan-tree-dump " == 0" "optimized" } } */ +} + +int +bar (int x) +{ + return (x | 137) != 137; +/* { dg-final { scan-tree-dump " & -138;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\| 137;" "optimized" } } */ +/* { dg-final { scan-tree-dump " != 0" "optimized" } } */ +} -- cgit v1.1 From 19040050aa2c8ee890fc58dda48639fc91bf0af0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 May 2021 10:38:35 +0200 Subject: expand: Don't reuse DEBUG_EXPRs with vector type if they have different modes [PR100508] The inliner doesn't remap DEBUG_EXPR_DECLs, so the same decls can appear in multiple functions. Furthermore, expansion reuses corresponding DEBUG_EXPRs too, so they again can be reused in multiple functions. Neither of that is a major problem, DEBUG_EXPRs are just magic value holders and what value they stand for is independent in each function and driven by what debug stmts or DEBUG_INSNs they are bound to. Except for DEBUG_EXPR*s with vector types, TYPE_MODE can be either BLKmode or some vector mode depending on whether current function's enabled ISAs support that vector mode or not. On the following testcase, we expand it first in foo function without AVX2 enabled and so the DEBUG_EXPR is BLKmode, but later the same DEBUG_EXPR_DECL is used in a simd clone with AVX2 enabled and expansion ICEs because of a mode mismatch. The following patch fixes that by forcing recreation of a DEBUG_EXPR if there is a mode mismatch for vector typed DEBUG_EXPR_DECL, DEBUG_EXPRs will be still reused in between functions otherwise and within the same function the mode should be always the same. 2021-05-12 Jakub Jelinek PR middle-end/100508 * cfgexpand.c (expand_debug_expr): For DEBUG_EXPR_DECL with vector type, don't reuse DECL_RTL if it has different mode, instead force creation of a new DEBUG_EXPR. * gcc.dg/gomp/pr100508.c: New test. --- gcc/testsuite/gcc.dg/gomp/pr100508.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gomp/pr100508.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/pr100508.c b/gcc/testsuite/gcc.dg/gomp/pr100508.c new file mode 100644 index 0000000..c3fa2fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr100508.c @@ -0,0 +1,14 @@ +/* PR middle-end/100508 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -fopenmp-simd" } */ + +typedef int __attribute__((__vector_size__(32))) V; +V j; + +#pragma omp declare simd +int +foo (void) +{ + V m = j; + return 0; +} -- cgit v1.1 From 1ecd1e6c894fbdbc10fdcfee419922b24e1115ee Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 11 May 2021 17:55:18 +0200 Subject: Fix ICE in output_rnglists, at dwarf2out.c:12294 In this testcase the compile unit consists of a single text section with a single embedded DECL_IGNORED_P function. So we have a kind of multi-range text section here. To avoid an ICE in output_rnglists we need to make sure that have_multiple_function_sections is set to true. This is a regression from e69ac020372 ("Add line debug info for virtual thunks") 2021-05-12 Bernd Edlinger PR debug/100515 * dwarf2out.c (dwarf2out_finish): Set have_multiple_function_sections with multi-range text_section. * gcc.dg/debug/dwarf2/pr100515.c: New testcase. --- gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c new file mode 100644 index 0000000..7c72fcd --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c @@ -0,0 +1,19 @@ +/* PR debug/100515 */ +/* { dg-do compile } */ +/* { dg-options "-g -O2 -fopenmp" } */ + +void +foo (int x) +{ +#pragma omp taskloop + for (int i = 0; i < x; i++) + ; +} + +void +bar (int x) +{ +#pragma omp taskloop + for (int i = 0; i < x; i++) + ; +} -- cgit v1.1 From cd36bbb2281ada10b5e1df143ecf64b88cdb8119 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 11 May 2021 14:59:59 +0200 Subject: tree-optimization/100519 - avoid reassociating asm goto defs This splits can_associate_p into checks for SSA defs and checks for the type so it can be called from is_reassociable_op to catch cases not catched by the earlier fix. 2021-05-11 Richard Biener PR tree-optimization/100519 * tree-ssa-reassoc.c (can_associate_p): Split into... (can_associate_op_p): ... this (can_associate_type_p): ... and this. (is_reassociable_op): Call can_associate_op_p. (break_up_subtract_bb): Call the appropriate predicates. (reassociate_bb): Likewise. * gcc.dg/torture/pr100519.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100519.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100519.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100519.c b/gcc/testsuite/gcc.dg/torture/pr100519.c new file mode 100644 index 0000000..faf6e24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100519.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "--param tree-reassoc-width=2" } */ + +unsigned int foo_a1, foo_a2; + +unsigned int foo() +{ + unsigned int v0, x; + asm goto("" : "=r"(x) : : : lab); +lab: + v0 += x + x; + return v0 + x + foo_a1 + foo_a2; +} -- cgit v1.1 From c6b664e2c4c127025e076d8b584abe0976694629 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 May 2021 15:14:35 +0200 Subject: libcpp: Fix up -fdirectives-only preprocessing of includes not ending with newline [PR100392] If a header doesn't end with a new-line, with -fdirectives-only we right now preprocess it as int i = 1;# 2 "pr100392.c" 2 i.e. the line directive isn't on the next line, which means we fail to parse it when compiling. GCC 10 and earlier libcpp/directives-only.c had for this: if (!pfile->state.skipping && cur != base) { /* If the file was not newline terminated, add rlimit, which is guaranteed to point to a newline, to the end of our range. */ if (cur[-1] != '\n') { cur++; CPP_INCREMENT_LINE (pfile, 0); lines++; } cb->print_lines (lines, base, cur - base); } and we have the assertion /* Files always end in a newline or carriage return. We rely on this for character peeking safety. */ gcc_assert (buffer->rlimit[0] == '\n' || buffer->rlimit[0] == '\r'); So, this patch just does readd the more less same thing, so that we emit a newline after the inline even when it wasn't there before. 2021-05-12 Jakub Jelinek PR preprocessor/100392 * lex.c (cpp_directive_only_process): If buffer doesn't end with '\n', add buffer->rlimit[0] character to the printed range and CPP_INCREMENT_LINE and increment line_count. * gcc.dg/cpp/pr100392.c: New test. * gcc.dg/cpp/pr100392.h: New file. --- gcc/testsuite/gcc.dg/cpp/pr100392.c | 5 +++++ gcc/testsuite/gcc.dg/cpp/pr100392.h | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/cpp/pr100392.c create mode 100644 gcc/testsuite/gcc.dg/cpp/pr100392.h (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/cpp/pr100392.c b/gcc/testsuite/gcc.dg/cpp/pr100392.c new file mode 100644 index 0000000..670ad2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100392.c @@ -0,0 +1,5 @@ +/* PR preprocessor/100392 */ +/* { dg-do compile } */ +/* { dg-options "-save-temps -fdirectives-only" } */ + +#include "pr100392.h" diff --git a/gcc/testsuite/gcc.dg/cpp/pr100392.h b/gcc/testsuite/gcc.dg/cpp/pr100392.h new file mode 100644 index 0000000..340bc92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100392.h @@ -0,0 +1,4 @@ +/* PR preprocessor/100392 */ + +/* No newline after ; below. */ +int i = 1; \ No newline at end of file -- cgit v1.1 From 097fde5e7514e909f2e8472be2e008d0cab2260d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 12 May 2021 15:39:52 +0200 Subject: tree-optimization/100566 - fix another predication issue in VN This amends the fix for PR100053 where I failed to amend all edge tests in dominated_by_p_w_unex. 2021-05-12 Richard Biener PR tree-optimization/100566 * tree-ssa-sccvn.c (dominated_by_p_w_unex): Properly handle allow_back for all edge queries. * gcc.dg/torture/pr100566.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100566.c | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100566.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100566.c b/gcc/testsuite/gcc.dg/torture/pr100566.c new file mode 100644 index 0000000..ed85691 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100566.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ + +volatile int s, c; + +__attribute__((noipa)) void +foo (void) +{ + if (c++ > 1) + __builtin_abort (); +} + +__attribute__((noipa)) int +bar (void) +{ + int i = 0, j = s; + if (j == 0) + goto lab; + for (i = 0; i < j; i++) + { + lab: + foo (); + if (!j) + goto lab; + } + return 0; +} + +int +main () +{ + s = 1; + bar (); + if (c != 1) + __builtin_abort (); + return 0; +} -- cgit v1.1 From d902a1b57606536982a1001670f998de685eaf7c Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 12 May 2021 15:22:15 -0400 Subject: Skip out on processing __builtin_clz when varying. The previous changes to irange::constant_p return TRUE for VARYING, since VARYING has numerical end points like any other constant range. The problem is that some users of constant_p depended on constant_p excluding the full domain. The range handler for __builtin_clz, that is shared between ranger and vr_values, is one such user. This patch excludes varying_p(), to match the original behavior for clz. gcc/ChangeLog: PR c/100521 * gimple-range.cc (range_of_builtin_call): Skip out on processing __builtin_clz when varying. --- gcc/testsuite/gcc.dg/pr100521.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100521.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100521.c b/gcc/testsuite/gcc.dg/pr100521.c new file mode 100644 index 0000000..fd9f0db --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100521.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +__builtin_clz (int a) +{ + return __builtin_clz(a); +} -- cgit v1.1 From db514f98a383b2ebdcfe74feb80f98f406cec174 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 12 May 2021 15:57:34 -0600 Subject: Add test for PR middle-end/100571. gcc/testsuite: PR middle-end/100571 * gcc.dg/Wstringop-overflow-67.c: New test. --- gcc/testsuite/gcc.dg/Wstringop-overflow-67.c | 92 ++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-67.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c new file mode 100644 index 0000000..7b8f3f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c @@ -0,0 +1,92 @@ +/* PR middle-end/100571 - bogus -Wstringop-overflow with VLA of elements + larger than byte + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +__attribute__ ((access (read_only, 1, 2))) void fro (int *, int); +__attribute__ ((access (write_only, 1, 2))) void fwo (int *, int); +__attribute__ ((access (read_write, 1, 2))) void frw (int *, int); + +extern __SIZE_TYPE__ n; + +void alloca_ro (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + a[0] = 0; + fro (a, n); +} + +void alloca_wo (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + fwo (a, n); +} + +void alloca_rw (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void calloc_ro (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + fro (a, n); +} + +void calloc_wo (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + fwo (a, n); +} + +void calloc_rw (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void malloc_ro (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + a[0] = 0; + fro (a, n); +} + +void malloc_wo (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + fwo (a, n); +} + +void malloc_rw (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void vla_ro (void) +{ + int a[n]; + a[0] = 0; + fro (a, n); +} + +void vla_wo (void) +{ + int a[n]; + fwo (a, n); +} + +void vla_rw (void) +{ + int a[n]; + a[0] = 0; + frw (a, n); +} -- cgit v1.1 From 810afb0b5fbb9da1e0e51ee9607f275f14c17459 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 13 May 2021 09:23:30 +0200 Subject: testsuite: prune new LTO warning libgomp/ChangeLog: PR testsuite/100569 * testsuite/libgomp.c/omp-nested-3.c: Prune new LTO warning. * testsuite/libgomp.c/pr46032-2.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/data-clauses-kernels-ipa-pta.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/data-clauses-parallel-ipa-pta.c: Likewise. gcc/testsuite/ChangeLog: PR testsuite/100569 * gcc.dg/atomic/c11-atomic-exec-2.c: Prune new LTO warning. * gcc.dg/torture/pr94947-1.c: Likewise. --- gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c | 1 + gcc/testsuite/gcc.dg/torture/pr94947-1.c | 1 + 2 files changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c index 9ee56b6..3e75096 100644 --- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c +++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-2.c @@ -2,6 +2,7 @@ assignment. */ /* { dg-do run } */ /* { dg-options "-std=c11 -pedantic-errors" } */ +/* { dg-prune-output "warning: using serial compilation" } */ extern void abort (void); extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/torture/pr94947-1.c b/gcc/testsuite/gcc.dg/torture/pr94947-1.c index ab8b488..832e40d 100644 --- a/gcc/testsuite/gcc.dg/torture/pr94947-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr94947-1.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-additional-sources "pr94947-2.c" } */ /* { dg-additional-options "-fipa-pta -flto-partition=1to1" } */ +/* { dg-prune-output "warning: using serial compilation" } */ extern void abort (); extern void baz (); -- cgit v1.1 From 829c4bea06600ea4201462f91ce6d76ca21fdb35 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 13 May 2021 12:14:14 +0200 Subject: ix86: Support V{2, 4}DImode arithmetic right shifts for SSE2+ [PR98856] As mentioned in the PR, we don't support arithmetic right V2DImode or V4DImode on x86 without -mavx512vl or -mxop. The ISAs indeed don't have {,v}psraq instructions until AVX512VL, but we actually can emulate it quite easily. One case is arithmetic >> 63, we can just emit {,v}pxor; {,v}pcmpgt for that for SSE4.2+, or for SSE2 psrad $31; pshufd $0xf5. Then arithmetic >> by constant > 32, that can be done with {,v}psrad $31 and {,v}psrad $(cst-32) and two operand permutation, arithmetic >> 32 can be done as {,v}psrad $31 and permutation of that and the original operand. Arithmetic >> by constant < 32 can be done as {,v}psrad $cst and {,v}psrlq $cst and two operand permutation. And arithmetic >> by variable scalar amount can be done as arithmetic >> 63, logical >> by the amount, << by (64 - amount of the >> 63 result; note that the vector << 64 result in 0) and oring together. I had to improve the permutation generation so that it actually handles the needed permutations (or handles them better). 2021-05-13 Jakub Jelinek PR tree-optimization/98856 * config/i386/i386.c (ix86_shift_rotate_cost): Add CODE argument. Expect V2DI and V4DI arithmetic right shifts to be emulated. (ix86_rtx_costs, ix86_add_stmt_cost): Adjust ix86_shift_rotate_cost caller. * config/i386/i386-expand.c (expand_vec_perm_2perm_interleave, expand_vec_perm_2perm_pblendv): New functions. (ix86_expand_vec_perm_const_1): Use them. * config/i386/sse.md (ashr3): Rename to ... (ashr3): ... this. (ashr3): New define_expand with VI248_AVX512BW iterator. (ashrv4di3): New define_expand. (ashrv2di3): Change condition to TARGET_SSE2, handle !TARGET_XOP and !TARGET_AVX512VL expansion. * gcc.target/i386/sse2-psraq-1.c: New test. * gcc.target/i386/sse4_2-psraq-1.c: New test. * gcc.target/i386/avx-psraq-1.c: New test. * gcc.target/i386/avx2-psraq-1.c: New test. * gcc.target/i386/avx-pr82370.c: Adjust expected number of vpsrad instructions. * gcc.target/i386/avx2-pr82370.c: Likewise. * gcc.target/i386/avx512f-pr82370.c: Likewise. * gcc.target/i386/avx512bw-pr82370.c: Likewise. * gcc.dg/torture/vshuf-4.inc: Add two further permutations. * gcc.dg/torture/vshuf-8.inc: Likewise. --- gcc/testsuite/gcc.dg/torture/vshuf-4.inc | 4 +++- gcc/testsuite/gcc.dg/torture/vshuf-8.inc | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/vshuf-4.inc b/gcc/testsuite/gcc.dg/torture/vshuf-4.inc index d041b33..fb35df8 100644 --- a/gcc/testsuite/gcc.dg/torture/vshuf-4.inc +++ b/gcc/testsuite/gcc.dg/torture/vshuf-4.inc @@ -25,7 +25,9 @@ T (21, 2, 6, 3, 7) \ T (22, 1, 2, 3, 0) \ T (23, 2, 1, 0, 3) \ T (24, 2, 5, 6, 3) \ -T (25, 0, 1, 4, 5) +T (25, 0, 1, 4, 5) \ +T (26, 1, 5, 3, 7) \ +T (27, 0, 5, 2, 7) #define EXPTESTS \ T (116, 1, 2, 4, 3) \ T (117, 7, 3, 3, 0) \ diff --git a/gcc/testsuite/gcc.dg/torture/vshuf-8.inc b/gcc/testsuite/gcc.dg/torture/vshuf-8.inc index de358f3..d628039 100644 --- a/gcc/testsuite/gcc.dg/torture/vshuf-8.inc +++ b/gcc/testsuite/gcc.dg/torture/vshuf-8.inc @@ -27,7 +27,9 @@ T (23, 6, 5, 4, 3, 2, 1, 0, 7) \ T (24, 0, 1, 2, 3, 8, 9, 10, 11) \ T (25, 0, 1, 2, 3, 12, 13, 14, 15) \ T (26, 0, 1, 8, 9, 10, 11, 12, 13) \ -T (27, 0, 8, 9, 10, 11, 12, 13, 14) +T (27, 0, 8, 9, 10, 11, 12, 13, 14) \ +T (28, 1, 9, 3, 11, 5, 13, 7, 15) \ +T (29, 0, 9, 2, 11, 4, 13, 6, 15) #define EXPTESTS \ T (116, 9, 3, 9, 4, 7, 0, 0, 6) \ T (117, 4, 14, 12, 8, 9, 6, 0, 10) \ -- cgit v1.1 From a451598b2c02e1ca3c62fea272d73a9f31922252 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Thu, 13 May 2021 11:42:58 +0100 Subject: arm: correctly handle inequality comparisons against max constants [PR100563] Normally we expect the gimple optimizers to fold away comparisons that are always true, but at some lower optimization levels this is not always the case, so the back-end has to be able to generate correct code in these cases. In this example, we have a comparison of the form (unsigned long long) op <= ~0ULL which, of course is always true. Normally, in the arm back-end we handle these expansions where the immediate cannot be handled directly by adding 1 to the constant and then adjusting the comparison operator: (unsigned long long) op < CONST + 1 but we cannot do that when the constant is already the largest value. Fortunately, we observe that the comparisons we need to handle this way are either always true or always false, so instead of forming a comparison against the maximum value, we can replace it with a comparison against the minimum value (which just happens to also be a constant we can handle. So op1 <= ~0ULL -> op1 >= 0U op1 > ~0ULL -> op1 < 0U op1 <= LONG_LONG_INT_MAX -> op1 >= (-LONG_LONG_INT_MAX - 1) op1 > LONG_LONG_INT_MAX -> op1 < (-LONG_LONG_INT_MAX - 1) gcc: PR target/100563 * config/arm/arm.c (arm_canonicalize_comparison): Correctly canonicalize DImode inequality comparisons against the maximum integral value. gcc/testsuite: * gcc.dg/pr100563.c: New test. --- gcc/testsuite/gcc.dg/pr100563.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100563.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100563.c b/gcc/testsuite/gcc.dg/pr100563.c new file mode 100644 index 0000000..812eb9e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100563.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Og" } */ +unsigned long long e(void); +void f(int); +void a() { + short b = -1, c = (int)&b; + unsigned long long d = e(); + f(b >= d); +} -- cgit v1.1 From efd471a980662f113dad8de0c0ef8593d0d38419 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Thu, 13 May 2021 14:52:05 +0100 Subject: testsuite: suppress cast warnings in pr100563.c [PR100563] Fix a warning when building on machines that don't have 32-bit pointers gcc/testsuite: PR target/100563 * gcc.dg/pr100563.c (dg-options): Add -wno-pointer-to-int-cast. --- gcc/testsuite/gcc.dg/pr100563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100563.c b/gcc/testsuite/gcc.dg/pr100563.c index 812eb9e..f6a5fcd 100644 --- a/gcc/testsuite/gcc.dg/pr100563.c +++ b/gcc/testsuite/gcc.dg/pr100563.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Og" } */ +/* { dg-options "-Og -Wno-pointer-to-int-cast" } */ unsigned long long e(void); void f(int); void a() { -- cgit v1.1 From 957c437363f139313b2c0b2c93ca985df1d98ad2 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 13 May 2021 10:38:09 -0600 Subject: PR c/100550 - ICE: in fold_convert_loc with function call VLA argument gcc/c/ChangeLog: PR c/100550 * c-decl.c (get_parm_array_spec): Avoid erroneous VLA bounds. gcc/testsuite/ChangeLog: PR c/100550 * gcc.dg/Wvla-parameter-9.c: New test. --- gcc/testsuite/gcc.dg/Wvla-parameter-9.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wvla-parameter-9.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-9.c b/gcc/testsuite/gcc.dg/Wvla-parameter-9.c new file mode 100644 index 0000000..6c8987a --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-9.c @@ -0,0 +1,30 @@ +/* PR c/100550 - ICE: in fold_convert_loc with function call VLA argument + { dg-do compile } + { dg-options "-Wall" } */ + +struct S { int i; }; + +extern void v; +extern void *pv; +extern struct S s; +void vf (void); + +/* Verify that a function redeclaration with an invalid VLA doesn't ICE. */ + +void f0 (int[]); +void f0 (int[undeclared]); // { dg-error "undeclared" } + +void f1 (int[]); +void f1 (int[-1]); // { dg-error "size" } + +void f2 (int[]); +void f2 (int[v]); // { dg-error "size" } + +void f3 (int[]); +void f3 (int b[s]); // { dg-error "size" } + +void f4 (int[]); +void f4 (int c[pv]); // { dg-error "size" } + +void f5 (int[]); +void f5 (int d[vf ()]); // { dg-error "size" } -- cgit v1.1 From ca9bb74a5f856ccdceb4797f18b0a4ac8f49d069 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Thu, 13 May 2021 23:26:32 +0200 Subject: tree-sra: Avoid refreshing into const base decls (PR 100453) When SRA transforms an assignment where the RHS is an aggregate decl that it creates replacements for, the (least efficient) fallback method of dealing with them is to store all the replacements back into the original decl and then let the original assignment takes itc sourse. That of course should not need to be done for TREE_READONLY bases which cannot change contents. The SRA code handled this situation in one of two necessary places but only for DECL_IN_CONSTANT_POOL const decls, this patch modifies both to check TREE_READONLY. gcc/ChangeLog: 2021-05-12 Martin Jambor PR tree-optimization/100453 * tree-sra.c (sra_modify_assign): All const base accesses do not need refreshing, not just those from decl_pool. (sra_modify_assign): Do not refresh into a const base decl. gcc/testsuite/ChangeLog: 2021-05-12 Martin Jambor PR tree-optimization/100453 * gcc.dg/tree-ssa/pr100453.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr100453.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr100453.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c new file mode 100644 index 0000000..0cf0ad2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +struct a { + int b : 4; +} d; +static int c, e; +static const struct a f; +static void g(const struct a h) { + for (; c < 1; c++) + d = h; + e = h.b; + c = h.b; +} +int main() { + g(f); + return 0; +} -- cgit v1.1 From 2efe245bb88bf4574e322ef7e6d2df83d9e13237 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 13 May 2021 16:05:50 -0600 Subject: Avoid -Wuninitialized false negatives with sanitization and VLAs. Resolves: PR tree-optimization/93100 - gcc -fsanitize=address inhibits -Wuninitialized PR middle-end/98583 - missing -Wuninitialized reading from a second VLA in its own block gcc/ChangeLog: PR tree-optimization/93100 PR middle-end/98583 * tree-ssa-uninit.c (check_defs): Exclude intrinsic functions that don't modify referenced objects. gcc/testsuite/ChangeLog: PR tree-optimization/93100 PR middle-end/98583 * g++.dg/warn/uninit-pr93100.C: New test. * gcc.dg/uninit-pr93100.c: New test. * gcc.dg/uninit-pr98583.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr93100.c | 74 +++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/uninit-pr98583.c | 31 +++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr93100.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pr98583.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr93100.c b/gcc/testsuite/gcc.dg/uninit-pr93100.c new file mode 100644 index 0000000..61b7e43 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr93100.c @@ -0,0 +1,74 @@ +/* PR tree-optimization/93100 - gcc -fsanitize=address inhibits -Wuninitialized + { dg-do compile } + { dg-options "-Wall -fsanitize=address" } */ + +struct A +{ + _Bool b; + int i; +}; + +void warn_A_b_O0 (void) +{ + struct A a; + + if (a.b) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +void warn_A_i_O0 (void) +{ + struct A a; + + if (a.i) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +#pragma GCC optimize ("1") + +void warn_A_b_O1 (void) +{ + struct A a; + + if (a.b) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +void warn_A_i_O1 (void) +{ + struct A a; + + if (a.i) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + + +#pragma GCC optimize ("2") + +void warn_A_b_O2 (void) +{ + struct A a; + + if (a.b) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} + +void warn_A_i_O2 (void) +{ + struct A a; + + if (a.i) // { dg-warning "\\\[-Wuninitialized" } + { + (void)&a; + } +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr98583.c b/gcc/testsuite/gcc.dg/uninit-pr98583.c new file mode 100644 index 0000000..638b029 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr98583.c @@ -0,0 +1,31 @@ +/* PR middle-end/98583 - missing -Wuninitialized reading from a second VLA + in its own block + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void f (int*); +void g (int); + +void h1 (int n) +{ + int a[n]; + f (a); + + int b[n]; + g (b[1]); // { dg-warning "\\\[-Wuninitialized" } +} + +void h2 (int n, int i, int j) +{ + if (i) + { + int a[n]; + f (a); + } + + if (j) + { + int b[n]; + g (b[1]); // { dg-warning "\\\[-Wmaybe-uninitialized" } + } +} -- cgit v1.1 From af42043e6618e69187b47f37dac870763c01e20f Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Sat, 15 May 2021 10:11:12 +0200 Subject: Revert "tree-sra: Avoid refreshing into const base decls (PR 100453)" This reverts commit ca9bb74a5f856ccdceb4797f18b0a4ac8f49d069. ...because of Ada issues I did not catch with original testing. gcc/ChangeLog: 2021-05-12 Martin Jambor Revert: PR tree-optimization/100453 * tree-sra.c (sra_modify_assign): All const base accesses do not need refreshing, not just those from decl_pool. (sra_modify_assign): Do not refresh into a const base decl. gcc/testsuite/ChangeLog: 2021-05-12 Martin Jambor Revert: PR tree-optimization/100453 * gcc.dg/tree-ssa/pr100453.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr100453.c | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr100453.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c deleted file mode 100644 index 0cf0ad2..0000000 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c +++ /dev/null @@ -1,18 +0,0 @@ -/* { dg-do run } */ -/* { dg-options "-O1" } */ - -struct a { - int b : 4; -} d; -static int c, e; -static const struct a f; -static void g(const struct a h) { - for (; c < 1; c++) - d = h; - e = h.b; - c = h.b; -} -int main() { - g(f); - return 0; -} -- cgit v1.1 From b050cf6a4d9c305daff4a96e5a2489ece69dc287 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Mon, 17 May 2021 09:25:43 +0000 Subject: testsuite: Require openmp effective-target for PR100515 The related test uses -fopenmp, which is not supported by newlib-based targets such as arm-eabi or aarch64-elf. Requiring the openmp effective-target makes the test unsupported rather than failed. 2021-05-17 Christophe Lyon PR debug/100515 gcc/testsuite * gcc.dg/debug/dwarf2/pr100515.c: Require openmp effective-target. --- gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c index 7c72fcd..17f6463 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr100515.c @@ -1,5 +1,6 @@ /* PR debug/100515 */ /* { dg-do compile } */ +/* { dg-require-effective-target fopenmp } */ /* { dg-options "-g -O2 -fopenmp" } */ void -- cgit v1.1 From 086882b1c8faa8f99f98a9219ccec42d89db50c2 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 17 May 2021 14:47:08 +0200 Subject: c/100625 - avoid building invalid labels in the GIMPLE FE When duplicate labes are diagnosed, avoid building a GIMPLE_LABEL. 2021-05-17 Richard Biener PR c/100625 gcc/c/ * gimple-parser.c (c_parser_gimple_label): Avoid building a GIMPLE label with NULL label decl. gcc/testsuite/ * gcc.dg/gimplefe-error-9.c: New testcase. --- gcc/testsuite/gcc.dg/gimplefe-error-9.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-error-9.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-9.c b/gcc/testsuite/gcc.dg/gimplefe-error-9.c new file mode 100644 index 0000000..87014c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-9.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +void __GIMPLE +foo() +{ +bb1: +bb1:; /* { dg-error "duplicate" } */ +} -- cgit v1.1 From ce81282261c6c77883b17d0ebfbbe337bed76457 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 13 May 2021 16:09:58 -0400 Subject: Bail in bounds_of_var_in_loop if scev returns NULL. Both initial_condition_in_loop_num and evolution_part_in_loop_num can return NULL. This patch exits if either one is NULL. Presumably this didn't happen before, because adjust_range_with_scev was called far less frequently than in ranger, which can call it for every PHI. gcc/ChangeLog: PR tree-optimization/100349 * vr-values.c (bounds_of_var_in_loop): Bail if scev returns NULL. gcc/testsuite/ChangeLog: * gcc.dg/pr100349.c: New test. --- gcc/testsuite/gcc.dg/pr100349.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100349.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100349.c b/gcc/testsuite/gcc.dg/pr100349.c new file mode 100644 index 0000000..dd7977a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100349.c @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "-O2 -w" } + +#include +uint8_t a; +b(int8_t c) { + int d; +e: + uint32_t f; + for (;;) + for (c = 10; c; c++) + if (0 > (a = c) ?: d) { + f = a; + goto e; + } +} -- cgit v1.1 From 3f476de7fd274f619a0b04c2e2f7077ee8ab17a5 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 17 May 2021 15:53:39 -0400 Subject: Once a range becomes constant, make it invariant. Once a range is forced to a constant globally, simply make it invariant. Unify this with the code which makes non-zero pointer ranges invariant. gcc/ PR tree-optimization/100512 * gimple-range-cache.cc (ranger_cache::set_global_range): Mark const and non-zero pointer ranges as invariant. * gimple-range.cc (gimple_ranger::range_of_stmt): Remove pointer processing from here. gcc/testsuite/ PR tree-optimization/100512 * gcc.dg/pr100512.c: New. --- gcc/testsuite/gcc.dg/pr100512.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100512.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100512.c b/gcc/testsuite/gcc.dg/pr100512.c new file mode 100644 index 0000000..70b90e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100512.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -w" } */ + +#include +int a; +void b() { + int16_t *c; + uint16_t d = 2; + if (0 == d) { + uint64_t e; + uint64_t *f = &e; + for (;;) { + if (e += 0 >= 0) + for (;;) + ; + g: + for (; a;) { + int16_t i = &d; + *c = i && *f; + } + } + } + goto g; +} + -- cgit v1.1 From 4054472b3fa15e11ccd48190f5e3ecfc89d65af9 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 12 May 2021 09:20:17 +0200 Subject: c/100547 - reject overly large vector_size attributes This rejects a number of vector components that does not fit an 'int' which is an internal limitation of RTVEC. This requires adjusting gcc.dg/attr-vector_size.c which checks for much larger supported vectors. Note that the RTVEC limitation is a host specific limitation (unless we change this 'int' to int32_t), but should be 32bits in practice everywhere. 2021-05-12 Richard Biener PR c/100547 gcc/c-family/ * c-attribs.c (type_valid_for_vector_size): Reject too large nunits. Reword existing nunit diagnostic. gcc/testsuite/ * gcc.dg/pr100547.c: New testcase. * gcc.dg/attr-vector_size.c: Adjust. --- gcc/testsuite/gcc.dg/attr-vector_size.c | 16 --------------- gcc/testsuite/gcc.dg/pr100547.c | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr100547.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/attr-vector_size.c b/gcc/testsuite/gcc.dg/attr-vector_size.c index 00be26a..3f2ce88 100644 --- a/gcc/testsuite/gcc.dg/attr-vector_size.c +++ b/gcc/testsuite/gcc.dg/attr-vector_size.c @@ -22,14 +22,6 @@ DEFVEC (extern, 30); #if __SIZEOF_SIZE_T__ > 4 -DEFVEC (extern, 31); -DEFVEC (extern, 32); -DEFVEC (extern, 33); -DEFVEC (extern, 34); -DEFVEC (extern, 60); -DEFVEC (extern, 61); -DEFVEC (extern, 62); - VEC (POW2 (63)) char v63; /* { dg-error "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */ #else @@ -49,14 +41,6 @@ void test_local_scope (void) #if __SIZEOF_SIZE_T__ > 4 - DEFVEC (auto, 31); - DEFVEC (auto, 32); - DEFVEC (auto, 33); - DEFVEC (auto, 34); - DEFVEC (auto, 60); - DEFVEC (auto, 61); - DEFVEC (auto, 62); - VEC (POW2 (63)) char v63; /* { dg-error "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */ #else diff --git a/gcc/testsuite/gcc.dg/pr100547.c b/gcc/testsuite/gcc.dg/pr100547.c new file mode 100644 index 0000000..2d3da4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100547.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O -g" } */ + +typedef int __attribute__((vector_size( + ((((((((((((((((((((((((((((((8 * sizeof(short)) * sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)))) V; /* { dg-error "number of vector components" } */ +void k() { V w = { 0 }; } -- cgit v1.1 From 414fe08a352eac69168f4fb3671246c84a1ac5aa Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 18 May 2021 08:41:43 +0200 Subject: c/100522 - avoid invalid GIMPLE in GIMPLE parsing This plugs a few easy holes avoiding ICEs down the route. 2021-05-18 Richard Biener PR c/100522 gcc/c/ * gimple-parser.c (c_parser_gimple_postfix_expression_after_primary): Diagnose calls to non-functions. (c_parser_gimple_statement): Diagnose unexpected assignment RHS. gcc/testsuite/ * gcc.dg/gimplefe-error-10.c: New testcase. --- gcc/testsuite/gcc.dg/gimplefe-error-10.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-error-10.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-10.c b/gcc/testsuite/gcc.dg/gimplefe-error-10.c new file mode 100644 index 0000000..13d86ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-10.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +__GIMPLE +void foo() { + int t1; + t1_1 = t1_1(); /* { dg-error "invalid call" } */ +} -- cgit v1.1 From c81704b359283bb54696755ead881ab04136da94 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 18 May 2021 10:26:45 +0200 Subject: regcprop: Avoid DCE of asm goto [PR100590] The following testcase ICEs, because copyprop_hardreg_forward_1 decides to DCE asm goto with REG_UNUSED notes (because the output is unused and asm isn't volatile). But that DCE just removes the asm goto, leaving a bb with two successors and no insn at the end that would allow that. The following patch makes sure we drop that way only INSNs and not JUMP_INSNs or CALL_INSNs. 2021-05-18 Jakub Jelinek PR rtl-optimization/100590 * regcprop.c (copyprop_hardreg_forward_1): Only DCE dead sets if they are NONJUMP_INSN_P. * gcc.dg/pr100590.c: New test. --- gcc/testsuite/gcc.dg/pr100590.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100590.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100590.c b/gcc/testsuite/gcc.dg/pr100590.c new file mode 100644 index 0000000..5cd3687 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100590.c @@ -0,0 +1,13 @@ +/* PR rtl-optimization/100590 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-dce -w" } */ + +int +foo (void) +{ + int x; + asm goto ("" : "+r" (x) : : : lab); + return 0; + lab: + return 1; +} -- cgit v1.1 From 03eb779141a29f96600cd46904b88a33c4b49a66 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Thu, 6 May 2021 11:59:42 +0200 Subject: Add 'dg-note', 'dg-lto-note' That's 'dg-message "note: [...]"' with a twist: inhibit default notes pruning, such that "if 'dg-note' is used at least once in a testcase, [notes] are not pruned and instead must *all* be handled explicitly". The rationale is that either you're not interested in notes at all (default behavior of pruning all notes), but often, when you're interested in one note, you're in fact interested in all notes, and especially interested if *additional* notes appear over time, as GCC evolves. gcc/testsuite/ * lib/gcc-dg.exp: Implement 'dg-note'. * lib/prune.exp: Likewise. * gcc.dg/vect/nodump-vect-opt-info-2.c: Use 'dg-note', and 'dg-prune-output "note: ". * gfortran.dg/goacc/routine-external-level-of-parallelism-2.f: Use 'dg-note', match up additional notes, one class of them with XFAILed 'dg-bogus'. * lib/lto.exp: Implement 'dg-lto-note'. * g++.dg/lto/odr-1_0.C: Use 'dg-lto-note', match up additional notes. * g++.dg/lto/odr-1_1.C: Likewise. * g++.dg/lto/odr-2_1.C: Likewise. libstdc++-v3/ * testsuite/lib/prune.exp: Add note about 'dg-note'. gcc/ * doc/sourcebuild.texi: Document 'dg-note'. --- gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c index 23a3b39..bcdf7f0 100644 --- a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c +++ b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c @@ -3,7 +3,9 @@ extern void accumulate (int x, int *a); -int test_missing_function_defn (int *arr, int n) /* { dg-message "vectorized 0 loops in function" } */ +int test_missing_function_defn (int *arr, int n) /* { dg-note "5: vectorized 0 loops in function" } */ +/* { dg-prune-output "note: " } as we're not interested in matching any further + notes. */ { int sum = 0; for (int i = 0; i < n; ++i) /* { dg-missed "21: couldn't vectorize loop" } */ -- cgit v1.1 From cd323d97d0592135ca4345701ef051659d8d4507 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 18 May 2021 12:29:58 -0400 Subject: analyzer: fix missing leak after call to strsep [PR100615] PR analyzer/100615 reports a missing leak diagnostic. The issue is that the code calls strsep which the analyzer doesn't have special knowledge of, and so conservatively assumes that it could free the pointer, so drops malloc state for it. Properly "teaching" the analyzer about strsep would require it to support bifurcating state at a call, which is currently fiddly to do, so for now this patch notes that strsep doesn't affect the malloc state machine, allowing the analyzer to correctly detect the leak. gcc/analyzer/ChangeLog: PR analyzer/100615 * sm-malloc.cc: Include "analyzer/function-set.h". (malloc_state_machine::on_stmt): Call unaffected_by_call_p and bail on the functions it recognizes. (malloc_state_machine::unaffected_by_call_p): New. gcc/testsuite/ChangeLog: PR analyzer/100615 * gcc.dg/analyzer/pr100615.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr100615.c | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr100615.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr100615.c b/gcc/testsuite/gcc.dg/analyzer/pr100615.c new file mode 100644 index 0000000..7a06f98 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr100615.c @@ -0,0 +1,53 @@ +/* Adapted from + https://github.com/stackpath/rxtxcpu/blob/816d86c5d49c4db2ea5649f6b87e96da5af660f1/cpu.c + which is MIT-licensed. */ + +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *)0) + +extern size_t strlen (const char *__s) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__pure__)) + __attribute__ ((__nonnull__ (1))); +extern char *strdup (const char *__s) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__nonnull__ (1))); +extern char *strsep (char **__restrict __stringp, + const char *__restrict __delim) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__nonnull__ (1, 2))); +extern long int strtol (const char *__restrict __nptr, + char **__restrict __endptr, int __base) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__nonnull__ (1))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +#define CPU_LIST_BASE 10 + +int parse_cpu_list(char *cpu_list) { + if (strlen(cpu_list) == 0) { + return 0; + } + + char *endptr; + char *tofree, *string, *range; + + tofree = string = strdup(cpu_list); /* { dg-message "allocated here" } */ + + while ((range = strsep(&string, ",")) != NULL) { + int first = strtol(range, &endptr, CPU_LIST_BASE); + if (!*endptr) { + continue; + } + char *save = endptr; + endptr++; + int last = strtol(endptr, &endptr, CPU_LIST_BASE); + if (save[0] != '-' || *endptr || last < first) { + return -1; /* { dg-warning "leak of 'tofree'" } */ + } + } + free(tofree); + return 0; +} -- cgit v1.1 From de56f95afaaa22c67cbeec780921d63e8b34514e Mon Sep 17 00:00:00 2001 From: Xionghu Luo Date: Tue, 18 May 2021 21:34:18 -0500 Subject: Run pass_sink_code once more before store_merging Gimple sink code pass runs quite early, there may be some new oppertunities exposed by later gimple optmization passes, this patch runs the sink code pass once more before store_merging. For detailed discussion, please refer to: https://gcc.gnu.org/pipermail/gcc-patches/2020-December/562352.html Tested the SPEC2017 performance on P8LE, 544.nab_r is improved by 2.43%, but no big changes to other cases, GEOMEAN is improved quite small with 0.25%. gcc/ChangeLog: 2021-05-18 Xionghu Luo * passes.def: Add sink_code pass before store_merging. * tree-ssa-sink.c (pass_sink_code:clone): New. gcc/testsuite/ChangeLog: 2021-05-18 Xionghu Luo * gcc.dg/tree-ssa/ssa-sink-1.c: Adjust. * gcc.dg/tree-ssa/ssa-sink-2.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-3.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-4.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-5.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-6.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-7.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-8.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-9.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-10.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-13.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-14.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-16.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-17.c: Ditto. * gcc.dg/tree-ssa/ssa-sink-18.c: New. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-14.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-17.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c | 212 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c | 15 -- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-5.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-6.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-7.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-8.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-9.c | 2 +- 15 files changed, 227 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-1.c index 411585a..57b5016 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-1.c @@ -7,4 +7,4 @@ foo (int a, int b, int c) return c ? x : a; } /* We should sink the x = a * b calculation into the branch that returns x. */ -/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c index 37e4d2f..535cb32 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c @@ -16,4 +16,4 @@ void foo (void) } } -/* { dg-final { scan-tree-dump-times "Sinking # VUSE" 4 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sinking # VUSE" 4 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c index a65ba35..584fd91 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c @@ -21,5 +21,5 @@ void test () /* We should sink/merge all stores and end up with a single BB. */ -/* { dg-final { scan-tree-dump-times "MEM\[^\n\r\]* = 0;" 3 "sink" } } */ -/* { dg-final { scan-tree-dump-times " + +#define HLOG 16 +#define MAX_LIT (1 << 5) +typedef const uint8_t *LZF_HSLOT; +typedef LZF_HSLOT LZF_STATE[1 << (HLOG)]; + +int +compute_on_bytes (uint8_t *in_data, int in_len, uint8_t *out_data, int out_len) +{ + LZF_STATE htab; + + uint8_t *ip = in_data; + uint8_t *op = out_data; + uint8_t *in_end = ip + in_len; + uint8_t *out_end = op + out_len; + uint8_t *ref; + + unsigned long off; + unsigned int hval; + int lit; + + if (!in_len || !out_len) + return 0; + + lit = 0; + op++; + hval = (((ip[0]) << 8) | ip[1]); + + while (ip < in_end - 2) + { + uint8_t *hslot; + + hval = (((hval) << 8) | ip[2]); + hslot = (uint8_t*)(htab + (((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))); + + ref = *hslot + in_data; + *hslot = ip - in_data; + + if (1 && (off = ip - ref - 1) < (1 << 13) && ref > in_data + && ref[2] == ip[2] + && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])) + { + unsigned int len = 2; + unsigned int maxlen = in_end - ip - len; + maxlen + = maxlen > ((1 << 8) + (1 << 3)) ? ((1 << 8) + (1 << 3)) : maxlen; + + if ((op + 3 + 1 >= out_end) != 0) + if (op - !lit + 3 + 1 >= out_end) + return 0; + + op[-lit - 1] = lit - 1; + op -= !lit; + + for (;;) + { + if (maxlen > 16) + { + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + len++; + if (ref[len] != ip[len]) + break; + } + + do + { + len++; + } + while (len < maxlen && ip[len] == ref[len]); + + break; + } + + len -= 2; + ip++; + + if (len < 7) + { + *op++ = (off >> 8) + (len << 5); + } + else + { + *op++ = (off >> 8) + (7 << 5); + *op++ = len - 7; + } + *op++ = off; + lit = 0; + op++; + ip += len + 1; + + if (ip >= in_end - 2) + break; + + --ip; + --ip; + + hval = (((ip[0]) << 8) | ip[1]); + hval = (((hval) << 8) | ip[2]); + htab[(((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))] + = (LZF_HSLOT)(ip - in_data); + ip++; + + hval = (((hval) << 8) | ip[2]); + htab[(((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))] + = (LZF_HSLOT)(ip - in_data); + ip++; + } + else + { + if (op >= out_end) + return 0; + + lit++; + *op++ = *ip++; + + if (lit == (1 << 5)) + { + op[-lit - 1] = lit - 1; + lit = 0; + op++; + } + } + } + if (op + 3 > out_end) /* at most 3 bytes can be missing here */ + return 0; + + while (ip < in_end) + { + lit++; + *op++ = *ip++; + if (lit == MAX_LIT) + { + op[-lit - 1] = lit - 1; /* stop run */ + lit = 0; + op++; /* start run */ + } + } + + op[-lit - 1] = lit - 1; /* end run */ + op -= !lit; /* undo run if length is zero */ + + return op - out_data; + } + + /* For this case, pass sink2 sinks statements from hot loop header to loop + exits after gimple loop optimizations, which generates instructions executed + each iteration in loop, but the results are used outside of loop: + With -m64, + "Sinking _367 = (uint8_t *) _320; + from bb 31 to bb 90 + Sinking _320 = _321 + ivtmp.25_326; + from bb 31 to bb 90 + Sinking _321 = (unsigned long) ip_229; + from bb 31 to bb 90 + Sinking len_158 = _322 + 4294967295; + from bb 31 to bb 33" + When -m32, Power and X86 will sink 3 instructions, but arm ilp32 couldn't + sink due to ivopts chooses two IV candidates instead of one, which is + expected, so this case is restricted to lp64 only so far. */ + + /* { dg-final { scan-tree-dump-times "Sunk statements: 4" 1 "sink2" { target lp64 } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-2.c index 6aa5a18..a0b4734 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-2.c @@ -9,4 +9,4 @@ bar (int a, int b, int c) return y; } /* We should sink the x = a * b calculation into the else branch */ -/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c index 599997e..e69de29 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c @@ -1,15 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-sink-stats" } */ -extern void foo(int a); -int -main (int argc) -{ - int a; - a = argc + 1; - if (argc + 3) - { - foo (a); - } -} -/* We should sink the a = argc + 1 calculation into the if branch */ -/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-4.c index 784edd2..1e3cfa9 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-4.c @@ -17,4 +17,4 @@ main (int argc) foo2 (a); } /* We should sink the first a = b + c calculation into the else branch */ -/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-5.c index dbdde39..f04da5d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-5.c @@ -44,4 +44,4 @@ void foo(int16_t runs[], uint8_t alpha[], int x, int count) } /* We should not sink the next_runs = runs + x calculation after the loop. */ -/* { dg-final { scan-tree-dump-times "Sunk statements:" 0 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sunk statements:" 0 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-6.c index 1abae9f..31f5af3 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-6.c @@ -14,4 +14,4 @@ int foo(int *a, int r) /* *a = 1 should be sunk to the else block. */ -/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-7.c index ec3288f..bd74844 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-7.c @@ -15,4 +15,4 @@ int foo(int *a, int r, short *b) /* *a = 1 should be sunk to the else block. */ -/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-8.c index 48af421..4b23b56 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-8.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-8.c @@ -24,4 +24,4 @@ int foo(int *a, int r, short *b) /* *a = 1 should be sunk into the default case. */ -/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-9.c index 509a763..32bfc81 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-9.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-9.c @@ -15,4 +15,4 @@ int foo(int *a, int r, int *b) /* *a = 1 should be sunk to the else block. */ -/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink" } } */ +/* { dg-final { scan-tree-dump-times "Sinking" 1 "sink1" } } */ -- cgit v1.1 From 51cfa55431c38f3c29c7b72833337ad8a2da5c06 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 19 May 2021 09:51:44 +0200 Subject: Fix commit mistake in testcase gcc.dg/tree-ssa/ssa-sink-3.c the test case was accidenally changed to empty file. 2021-05-19 Bernd Edlinger * gcc.dg/tree-ssa/ssa-sink-3.c: Fix test case. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c index e69de29..ad88ccc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-sink-stats" } */ +extern void foo(int a); +int +main (int argc) +{ + int a; + a = argc + 1; + if (argc + 3) + { + foo (a); + } +} +/* We should sink the a = argc + 1 calculation into the if branch */ +/* { dg-final { scan-tree-dump-times "Sunk statements: 1" 1 "sink1" } } */ -- cgit v1.1 From 32bd0353db37af2cb023e575ed4ce8c944fd9dba Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 19 May 2021 15:25:36 +0200 Subject: Fix typos. PR testsuite/100658 gcc/cp/ChangeLog: * mangle.c (write_encoding): Fix typos. gcc/jit/ChangeLog: * libgccjit.c (gcc_jit_context_new_function): Fix typos. gcc/testsuite/ChangeLog: * gcc.dg/local1.c: Fix typos. * gcc.dg/ucnid-5-utf8.c: Likewise. * gcc.dg/ucnid-5.c: Likewise. --- gcc/testsuite/gcc.dg/local1.c | 2 +- gcc/testsuite/gcc.dg/ucnid-5-utf8.c | 2 +- gcc/testsuite/gcc.dg/ucnid-5.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/local1.c b/gcc/testsuite/gcc.dg/local1.c index e9f653b..448c71b 100644 --- a/gcc/testsuite/gcc.dg/local1.c +++ b/gcc/testsuite/gcc.dg/local1.c @@ -10,7 +10,7 @@ the later daclaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the - identifer has external linkage. + identifier has external linkage. This is PR 14366. */ diff --git a/gcc/testsuite/gcc.dg/ucnid-5-utf8.c b/gcc/testsuite/gcc.dg/ucnid-5-utf8.c index 8e10467..43310b6 100644 --- a/gcc/testsuite/gcc.dg/ucnid-5-utf8.c +++ b/gcc/testsuite/gcc.dg/ucnid-5-utf8.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-skip-if "No dollar in identfiers" { avr-*-* powerpc-ibm-aix* } } */ +/* { dg-skip-if "No dollar in identifiers" { avr-*-* powerpc-ibm-aix* } } */ /* { dg-skip-if "" { ! ucn } } */ /* { dg-options "-std=c99 -fdollars-in-identifiers -g" } */ void abort (void); diff --git a/gcc/testsuite/gcc.dg/ucnid-5.c b/gcc/testsuite/gcc.dg/ucnid-5.c index dc282a7..6f0f475 100644 --- a/gcc/testsuite/gcc.dg/ucnid-5.c +++ b/gcc/testsuite/gcc.dg/ucnid-5.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-skip-if "No dollar in identfiers" { avr-*-* powerpc-ibm-aix* } } */ +/* { dg-skip-if "No dollar in identifiers" { avr-*-* powerpc-ibm-aix* } } */ /* { dg-options "-std=c99 -fdollars-in-identifiers -g" } */ void abort (void); -- cgit v1.1 From 8d51039cb7c807ed84ff7df5416a1e3ba07a5e63 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 19 May 2021 13:35:07 +0200 Subject: middle-end/100672 - fix bogus right shift folding This fixes the bogus use of TYPE_PRECISION on vector types from optimizing -((int)x >> 31) into (unsigned)x >> 31. 2021-05-19 Richard Biener PR middle-end/100672 * fold-const.c (fold_negate_expr_1): Use element_precision. (negate_expr_p): Likewise. * gcc.dg/torture/pr100672.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100672.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100672.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100672.c b/gcc/testsuite/gcc.dg/torture/pr100672.c new file mode 100644 index 0000000..cc62e71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100672.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-additional-options "-w -Wno-psabi" } */ + +typedef long long __attribute__((__vector_size__ (4 * sizeof (long long)))) V; + +V +foo (V v) +{ + return -(v >> 1); +} + +int +main (void) +{ + V v = foo ((V) { -2, -4, -6, -8 }); + if (v[0] != 1 || v[1] != 2 || v[2] != 3 || v[3] != 4) + __builtin_abort (); + return 0; +} -- cgit v1.1 From eb2a917fa0779b689f09ac8d8c41b0456facbe62 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 19 May 2021 16:13:13 -0600 Subject: PR c/100619 - ICE on a VLA parameter with too many dimensions gcc/c-family/ChangeLog: PR c/100619 * c-attribs.c (build_attr_access_from_parms): Handle arbitrarily many bounds. gcc/testsuite/ChangeLog: PR c/100619 * gcc.dg/pr100619.c: New test. --- gcc/testsuite/gcc.dg/pr100619.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100619.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100619.c b/gcc/testsuite/gcc.dg/pr100619.c new file mode 100644 index 0000000..5df02bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100619.c @@ -0,0 +1,24 @@ +/* PR c/100619 - ICE on a VLA parameter with too many dimensions + { dg-do compile } + { dg-options "-Wall" } */ + +extern int n; + +#define A10 [n][n][n][n][n][n][n][n][n][n] +#define A100 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A1000 A100 A100 A100 A100 A100 A100 A100 A100 A100 A100 A100 + +void f10 (int A10); +void f10 (int A10); + +void f100 (int A100); +void f100 (int A100); + +void f1000 (int A1000); +void f1000 (int A1000); + +void fx_1000 (int [ ]A1000); +void fx_1000 (int [1]A1000); // { dg-warning "-Warray-parameter" } + +void fn_1000 (int [n ]A1000); +void fn_1000 (int [n + 1]A1000); // { dg-warning "-Wvla-parameter" } -- cgit v1.1 From d15a2d261b24adcbfe5e663b15dde3df5d2b3486 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 20 May 2021 09:09:07 +0200 Subject: libcpp: Fix up -fdirectives-only handling of // comments on last line not terminated with newline [PR100646] As can be seen on the testcases, before the -fdirectives-only preprocessing rewrite the preprocessor would assume // comments are terminated by the end of file even when newline wasn't there, but now we error out. The following patch restores the previous behavior. 2021-05-20 Jakub Jelinek PR preprocessor/100646 * lex.c (cpp_directive_only_process): Treat end of file as termination for !is_block comments. * gcc.dg/cpp/pr100646-1.c: New test. * gcc.dg/cpp/pr100646-2.c: New test. --- gcc/testsuite/gcc.dg/cpp/pr100646-1.c | 5 +++++ gcc/testsuite/gcc.dg/cpp/pr100646-2.c | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/cpp/pr100646-1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/pr100646-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/cpp/pr100646-1.c b/gcc/testsuite/gcc.dg/cpp/pr100646-1.c new file mode 100644 index 0000000..8f2caf4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100646-1.c @@ -0,0 +1,5 @@ +/* PR preprocessor/100646 */ +/* { dg-do compile } */ +/* { dg-options "-fdirectives-only -save-temps -std=c17" } */ +int main () { return 0; } +// Not newline terminated \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/cpp/pr100646-2.c b/gcc/testsuite/gcc.dg/cpp/pr100646-2.c new file mode 100644 index 0000000..a1deba1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100646-2.c @@ -0,0 +1,6 @@ +/* PR preprocessor/100646 */ +/* { dg-do compile } */ +/* { dg-options "-fdirectives-only -save-temps -std=c17" } */ +int main () { return 0; } +/* { dg-warning "backslash-newline at end of file" "" { target *-*-* } .+1 } */ +// Not newline terminated\ \ No newline at end of file -- cgit v1.1 From 459d84e9b6e925922246b6aff76a5202b1d4d4ba Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Fri, 30 Apr 2021 07:52:40 -0700 Subject: opts: change write_symbols to support bitmasks To support multiple debug formats, we need to move away from explicit enumeration of each individual combination of debug formats. gcc/c-family/ChangeLog: * c-opts.c (c_common_post_options): Adjust access to debug_type_names. * c-pch.c (struct c_pch_validity): Use type uint32_t. (pch_init): Renamed member. (c_common_valid_pch): Adjust access to debug_type_names. gcc/ChangeLog: * common.opt: Change type to support bitmasks. * flag-types.h (enum debug_info_type): Rename enumerator constants. (NO_DEBUG): New bitmask. (DBX_DEBUG): Likewise. (DWARF2_DEBUG): Likewise. (XCOFF_DEBUG): Likewise. (VMS_DEBUG): Likewise. (VMS_AND_DWARF2_DEBUG): Likewise. * flags.h (debug_set_to_format): New function declaration. (debug_set_count): Likewise. (debug_set_names): Likewise. * opts.c (debug_type_masks): Array of bitmasks for debug formats. (debug_set_to_format): New function definition. (debug_set_count): Likewise. (debug_set_names): Likewise. (set_debug_level): Update access to debug_type_names. * toplev.c: Likewise. gcc/objc/ChangeLog: * objc-act.c (synth_module_prologue): Use uint32_t instead of enum debug_info_type. gcc/testsuite/ChangeLog: * gcc.dg/pch/valid-1.c: Adjust diagnostic message in testcase. * lib/dg-pch.exp: Adjust diagnostic message. --- gcc/testsuite/gcc.dg/pch/valid-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pch/valid-1.c b/gcc/testsuite/gcc.dg/pch/valid-1.c index d445c47..6e9abda 100644 --- a/gcc/testsuite/gcc.dg/pch/valid-1.c +++ b/gcc/testsuite/gcc.dg/pch/valid-1.c @@ -1,7 +1,7 @@ /* { dg-require-effective-target pch_supported_debug } */ /* { dg-options "-I. -Winvalid-pch -g" } */ -#include "valid-1.h"/* { dg-warning "created with -gnone, but used with -g" } */ +#include "valid-1.h"/* { dg-warning "created with .none. debug info, but used with" } */ /* { dg-error "No such file" "no such file" { target *-*-* } 0 } */ /* { dg-error "they were invalid" "invalid files" { target *-*-* } 0 } */ /* { dg-message "terminated" "" { target *-*-* } 0 } */ -- cgit v1.1 From 99b76adb94d9363d0ca31a7d34ce850e2ca9ffc5 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sun, 16 May 2021 10:40:16 -0700 Subject: Don't simplify (A & C) != 0 ? D : 0 for pointer types. While rewriting part of PHI-OPT to use match-and-simplify, I ran into a bug where this pattern in match.pd would hit and would produce invalid gimple; a shift of a pointer type. This just disables this simplification for pointer types similarly to what is already done in PHI-OPT for the generic A ? D : 0 case. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Thanks, Andrew Pinski 2021-5-23 Andrew Pinski gcc/ * match.pd ((A & C) != 0 ? D : 0): Limit to non pointer types. gcc/testsuite/ * gcc.dg/gimplefe-45.c: New test. --- gcc/testsuite/gcc.dg/gimplefe-45.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-45.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gimplefe-45.c b/gcc/testsuite/gcc.dg/gimplefe-45.c new file mode 100644 index 0000000..b1d3cbb --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-45.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fgimple" } */ + +/* This used to ICE when simplifying (A & C) != 0 ? D : 0 + for pointer types. */ + +int *__GIMPLE () +p (int n) +{ + int *_2; + int *_t; + int *_t1; + _t = (int*)8; + _t1 = 0; + n = n & 2; + _2 = n != 0 ? _t : _t1; + return _2; +} + -- cgit v1.1 From 1040a44aa23f7b106e1c96e6a247ea6fd4021258 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sun, 23 May 2021 17:35:40 +0000 Subject: Fix two testcases for ssa names which are more than 1 digit phi-opt-10.c and phi-opt-7.c both depend on currently that some ssa name versions are one digit long which is not always correct. This fixes the problem by detecting digits rather than just using '.'. Committed as obvious after a bootstrap/test. Thanks, Andrew Pinski gcc/testsuite/ChangeLog * gcc.dg/tree-ssa/phi-opt-10.c: Use "\[0-9\]*" instead of '.' when matching ssa name version. * gcc.dg/tree-ssa/phi-opt-7.c: Likewise. --- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c index 4c190e6..3681fa7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c @@ -7,4 +7,4 @@ int eqm1_phi (unsigned long a) { return a ? 0 : -1; } int spaceship1 (long a) { return a > 0 ? 1 : a < 0 ? -1 : 0; } int spaceship2 (long a) { return a > 0 ? 1 : a == 0 ? 0 : -1; } -/* { dg-final { scan-tree-dump-times " = -\[^\r\n\]*_.;" 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times " = -\[^\r\n\]*_\[0-9\]*;" 4 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c index 18ecbd5..51e1f6d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c @@ -18,5 +18,5 @@ int f(int t, int c) /* There should be one ifs as one of them should be changed into a conditional and the other should be there still. */ /* { dg-final { scan-tree-dump-times "if" 1 "optimized" } }*/ -/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_. = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ -- cgit v1.1 From cec4d4a6782c9bd8d071839c50a239c49caca689 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 20 May 2021 09:32:29 +0200 Subject: Add no_sanitize_coverage attribute. gcc/ChangeLog: * asan.h (sanitize_coverage_p): New function. * doc/extend.texi: Document it. * fold-const.c (fold_range_test): Use sanitize_flags_p instead of flag_sanitize_coverage. (fold_truth_andor): Likewise. * sancov.c: Likewise. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * ipa-inline.c (sanitize_attrs_match_for_inline_p): Handle -fsanitize-coverage when inlining. gcc/c-family/ChangeLog: * c-attribs.c (handle_no_sanitize_coverage_attribute): New. gcc/testsuite/ChangeLog: * gcc.dg/sancov/attribute.c: New test. --- gcc/testsuite/gcc.dg/sancov/attribute.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c new file mode 100644 index 0000000..7cfa913 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ + +void foo(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +bar(void) +{ +} + +static void inline +__attribute__((always_inline)) +inline_fn(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +baz(void) +{ + inline_fn(); +} + +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ -- cgit v1.1 From 1fd76b24306ed4df4cf9e797d900699ed59ce7f7 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 22 May 2021 19:49:50 +0000 Subject: Optimize x < 0 ? ~y : y to (x >> 31) ^ y in match.pd This copies the optimization that is done in phiopt for "x < 0 ? ~y : y to (x >> 31) ^ y" into match.pd. The code for phiopt is kept around until phiopt uses match.pd (which I am working towards). Note the original testcase is now optimized early on and I added a new testcase to optimize during phiopt. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Thanks, Andrew Pinski Differences from v1: V2: Add check for integeral type to make sure vector types are not done. gcc: * match.pd (x < 0 ? ~y : y): New patterns. gcc/testsuite: * gcc.dg/tree-ssa/pr96928.c: Update test for slightly different IR. * gcc.dg/tree-ssa/pr96928-1.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c | 48 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr96928.c | 7 +++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c new file mode 100644 index 0000000..a2770e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c @@ -0,0 +1,48 @@ +/* PR tree-optimization/96928 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ + +int +foo (int a) +{ + if (a < 0) + return ~a; + return a; +} + +int +bar (int a, int b) +{ + if (a < 0) + return ~b; + return b; +} + +unsigned +baz (int a, unsigned int b) +{ + if (a < 0) + return ~b; + return b; +} + +unsigned +qux (int a, unsigned int c) +{ + if (a >= 0) + return ~c; + return c; +} + +int +corge (int a, int b) +{ + if (a >= 0) + return b; + return ~b; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c index 2091357..e8fd82f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c @@ -1,8 +1,11 @@ /* PR tree-optimization/96928 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */ /* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ -/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ +/* The following check is done at optimized because a ^ (~b) is rewritten as ~(a^b) + and in the case of match.pd optimizing these ?:, the ~ is moved out already + by the time we get to phiopt2. */ +/* { dg-final { scan-tree-dump-times "\\\^ c_\[0-9]*\\\(D\\\);" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ /* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ -- cgit v1.1 From 401bd4adcfda9965363b1ac3ba7e1580f15d6883 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 26 May 2021 19:12:05 +0200 Subject: Warn on type punning that toggles scalar storage order As documented in the manual, we do not support type punning that toggles the scalar storage order, so this adds a warning for the case of unions. gcc/c/ PR c/100653 * c-decl.c (finish_struct): Warn for a union containing an aggregate field with a differing scalar storage order. gcc/testsuite/ * gcc.dg/sso-13.c: New test. --- gcc/testsuite/gcc.dg/sso-13.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sso-13.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-13.c b/gcc/testsuite/gcc.dg/sso-13.c new file mode 100644 index 0000000..ddfde00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-13.c @@ -0,0 +1,24 @@ +/* Test support of scalar_storage_order attribute */ + +/* { dg-do compile } */ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) +#else +#define REV_ENDIANNESS __attribute__((scalar_storage_order("little-endian"))) +#endif + +typedef struct tIp6Addr +{ + unsigned int s6_addr32[4]; +} tIp6Addr; + +struct _tBeTimNetAddr +{ + unsigned char isIPv4; + union + { + unsigned int addr; + tIp6Addr addr6; /* { dg-warning "type punning toggles" } */ + } REV_ENDIANNESS u; +} REV_ENDIANNESS; -- cgit v1.1 From 28484d00c45b7bf094a22a4fddf9ffdc7482c7e1 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 26 May 2021 20:44:49 +0200 Subject: i386: Autovectorize 4-byte vectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2021-05-26 Uroš Bizjak gcc/ * config/i386/i386.c (ix86_autovectorize_vector_modes): Add V4QImode and V16QImode for TARGET_SSE2. * doc/sourcebuild.texi (Vector-specific attributes): Add vect64 and vect32 description. gcc/testsuite/ * lib/target-supports.exp (check_effective_target_vect32): New. (available_vector_sizes): Append 32 for x86 targets. * gcc.dg/vect/pr71264.c (dg-final): Xfail scan dump for vect32 targets. * gcc.dg/vect/slp-28.c (dg-final): Adjust dumps for vect32 targets. * gcc.dg/vect/slp-3.c (dg-final): Ditto. * gcc.target/i386/pr100637-3b.c: New test. * gcc.target/i386/pr100637-3w.c: Ditto. * gcc.target/i386/pr100637-4b.c: Ditto. * gcc.target/i386/pr100637-4w.c: Ditto. --- gcc/testsuite/gcc.dg/vect/pr71264.c | 3 +-- gcc/testsuite/gcc.dg/vect/slp-28.c | 5 +++-- gcc/testsuite/gcc.dg/vect/slp-3.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr71264.c b/gcc/testsuite/gcc.dg/vect/pr71264.c index dc849bf..1381e0e 100644 --- a/gcc/testsuite/gcc.dg/vect/pr71264.c +++ b/gcc/testsuite/gcc.dg/vect/pr71264.c @@ -19,5 +19,4 @@ void test(uint8_t *ptr, uint8_t *mask) } } -/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail s390*-*-* sparc*-*-* } } } */ - +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail { { s390*-*-* sparc*-*-* } || vect32 } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-28.c b/gcc/testsuite/gcc.dg/vect/slp-28.c index 7778bad..0bb5f0eb 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-28.c +++ b/gcc/testsuite/gcc.dg/vect/slp-28.c @@ -88,6 +88,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect32 } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { ! vect32 } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-3.c b/gcc/testsuite/gcc.dg/vect/slp-3.c index 46ab584..80ded18 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-3.c +++ b/gcc/testsuite/gcc.dg/vect/slp-3.c @@ -141,8 +141,8 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! vect_partial_vectors } } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_partial_vectors } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! vect_partial_vectors } } } }*/ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target vect_partial_vectors } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! { vect_partial_vectors || vect32 } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target { vect_partial_vectors || vect32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! { vect_partial_vectors || vect32 } } } } }*/ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_partial_vectors || vect32 } } } } */ -- cgit v1.1 From fe9a499cb8775cfbcea356ab0cae5c365971cf86 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 19 May 2021 18:27:47 +0200 Subject: Convert Walloca pass to get_range_query. This patch converts the Walloca pass to use an on-demand ranger accesible with get_range_query instead of having to create a ranger and pass it around. gcc/ChangeLog: * gimple-ssa-warn-alloca.c (alloca_call_type): Use get_range_query instead of query argument. (pass_walloca::execute): Enable and disable global ranger. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-55.c: Adapt for range query changes. * gcc.dg/pr80776-1.c: Same. --- gcc/testsuite/gcc.dg/Wstringop-overflow-55.c | 8 ++++---- gcc/testsuite/gcc.dg/pr80776-1.c | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index 25f5b82..8df5cb6 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -66,7 +66,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -74,7 +74,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } @@ -83,7 +83,7 @@ void warn_int_anti_range (int i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -91,7 +91,7 @@ void warn_int_anti_range (int i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index af41c0c..f3a120b 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,7 +17,5 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - /* The correctness bits for [E]VRP cannot handle chained conditionals - when deciding to ignore a unreachable branch for setting SSA range info. */ - sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ } -- cgit v1.1 From 95bef94c6c6c6cb7bf640068aea77c209bca7c65 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 27 May 2021 09:32:42 +0200 Subject: Tweak Wstringop-overflow-55.c test. On x86-32 warn_ptrdiff_anti_range_add() and warn_int_anti_range() degrade to the same function so ICF is folding the latter into a call into the former. This is causing no warnings to be emitted for warn_int_anti_range. Fixed by passing -fno-ipa-icf. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-55.c: Pass -fno-ipa-icf. --- gcc/testsuite/gcc.dg/Wstringop-overflow-55.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index 8df5cb6..c3c2dbe 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -1,6 +1,6 @@ /* Verify that offsets in "anti-ranges" are handled correctly. { dg-do compile } - { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Wall -ftrack-macro-expansion=0 -fno-ipa-icf" } */ typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t; -- cgit v1.1 From 5b43f6ace51c08dc2bae3c91a2a11300356c573d Mon Sep 17 00:00:00 2001 From: Joern Rennecke Date: Fri, 28 May 2021 09:34:07 +0100 Subject: Recognize popcount also when a double width operation is needed. 2021-05-28 Joern Rennecke gcc/ * match.pd : When generating popcount directly fails, try doing it in two halves. gcc/testsuite/ * gcc.dg/tree-ssa/popcount4ll.c: Remove lp64 condition. Adjust scanning pattern for !lp64. * gcc.dg/tree-ssa/popcount5ll.c: Likewise. * gcc.dg/tree-ssa/popcount4l.c: Adjust scanning pattern for ! int32plus. Co-Authored-By: Richard Biener --- gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c | 3 ++- gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c | 5 +++-- gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c index 69fb2d1..269e56e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c @@ -25,6 +25,7 @@ int popcount64c(unsigned long x) return (x * h01) >> shift; } -/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target int32plus } } } */ +/* { dg-final { scan-tree-dump "\.POPCOUNT" "optimized" { target { ! int32plus } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c index c1588be..7abadf6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target { lp64 } } } */ +/* { dg-do compile } */ /* { dg-require-effective-target popcountll } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ @@ -16,4 +16,5 @@ int popcount64c(unsigned long long x) return (x * h01) >> shift; } -/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target { lp64 } } } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 2 "optimized" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c index edb191b..2afe081 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c @@ -1,5 +1,5 @@ /* PR tree-optimization/94800 */ -/* { dg-do compile { target { lp64 } } } */ +/* { dg-do compile } */ /* { dg-require-effective-target popcountll } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ @@ -19,4 +19,5 @@ int popcount64c(unsigned long long x) return x >> shift; } -/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target { lp64 } } } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 2 "optimized" { target { ! lp64 } } } } */ -- cgit v1.1 From 8b2b32ab2d8cff4eb0dad0ef4e72e33257574cb6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 28 May 2021 13:05:39 +0200 Subject: c/100803 - diagnose invalid GIMPLE condition another easy fix for GIMPLE FE parser robustness. 2021-05-28 Richard Biener PR c/100803 gcc/c/ * gimple-parser.c (c_parser_gimple_paren_condition): Diagnose invalid if conditions. gcc/testsuite/ * gcc.dg/gimplefe-error-11.c: New testcase. --- gcc/testsuite/gcc.dg/gimplefe-error-11.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-error-11.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-11.c b/gcc/testsuite/gcc.dg/gimplefe-error-11.c new file mode 100644 index 0000000..9c29717 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-11.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +int bar(); +__GIMPLE +int foo() +{ + if (bar()) /* { dg-error "comparison required" } */ + goto bb1; + else + goto bb2; +} -- cgit v1.1 From 359c0a86e2974a9f3036bc05b6e6c661f2c463cf Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 28 May 2021 13:31:35 +0200 Subject: ipa/100791 - copy fntype when processing __builtin_va_arg_pack This missing copying exposed a type mismatch in the IL. 2021-05-28 Richard Biener PR ipa/100791 * tree-inline.c (copy_bb): When processing __builtin_va_arg_pack copy fntype from original call. * gcc.dg/pr100791.c: New testcase. --- gcc/testsuite/gcc.dg/pr100791.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100791.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100791.c b/gcc/testsuite/gcc.dg/pr100791.c new file mode 100644 index 0000000..96cf34f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100791.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +static inline int __attribute__((__always_inline__)) +foo () +{ + return log_bad_request(0, __builtin_va_arg_pack()); /* { dg-warning "implicit" } */ +} +void log_bad_request() { foo (0); } /* { dg-warning "conflicting types" } */ -- cgit v1.1 From f7a07f5a5d8065e7f11133dd1f4ad3510ab2195b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 28 May 2021 14:26:06 +0200 Subject: tree-optimization/100778 - avoid cross-BB vectorization of trapping op This avoids vectorizing a possibly trapping operation when lanes are handled in different BBs. I spotted this when working on the originally reported issue in PR100778. 2021-05-28 Richard Biener PR tree-optimization/100778 * tree-vect-slp.c (vect_build_slp_tree_1): Prevent possibly trapping ops in different BBs. * gcc.dg/vect/bb-slp-pr100778-1.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c new file mode 100644 index 0000000..9f8b7ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr100778-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ + +double foo (int x, double *p) +{ + double res = p[0] + p[1]; + double tem = p[0] / x; + if (x) + { + p[0] = tem; + p[1] /= x; + } + return res + tem; +} + +/* We may not SLP vectorize the FP division because it can trap and it + is distributed between two basic-blocks. */ +/* { dg-final { scan-tree-dump "Build SLP failed: different BB for PHI or possibly trapping operation in _\[0-9\]+ = _\[0-9\]+ / _\[0-9\]+;" "slp2" } } */ -- cgit v1.1 From 2364b584552208ce715fa4fd44c510b7e5210d1e Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 28 May 2021 22:17:51 +0200 Subject: Fix i686 bootstrap by temporarily disabling exporting of global ranges. The patch converting evrp to the get_range_query(fun) API broke i686 bootstrap (commit 57bf37515). The problem seems to be in a subsequent pass that has more up-to-date global ranges. I won't be able to look at this until next week, so I am reverting the problematic bit of the patch-- the exporting of global ranges once evrp finishes. The use of the new API remains. Reverting the behavior shouldn't be a problem as we never used to export global ranges from ranger. This was new behavior in the patchset. Tested on x86-64 Linux with a bootstrap and regtest, and on x86-32 with only a bootstrap and the configure flags from the PR: --enable-clocale=gnu --with-system-zlib --with-demangler-in-ld --with-fpmath=sse --enable-languages=c,c++ --enable-cet i686-linux --enable-bootstrap --with-fpmath=sse --disable-libcc1 --disable-libcilkrts --disable-libsanitizer gcc/ChangeLog: PR tree-optimization/100787 * gimple-ssa-evrp.c: Disable exporting of global ranges. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-55.c: * gcc.dg/pr80776-1.c: --- gcc/testsuite/gcc.dg/Wstringop-overflow-55.c | 8 ++++---- gcc/testsuite/gcc.dg/pr80776-1.c | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index c3c2dbe..5f83af7 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -66,7 +66,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -74,7 +74,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } sink (p0, p1, p2, p3, p4, p5); } @@ -83,7 +83,7 @@ void warn_int_anti_range (int i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -91,7 +91,7 @@ void warn_int_anti_range (int i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } sink (p0, p1, p2, p3, p4, p5); } diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index f3a120b..af41c0c 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,5 +17,7 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ + /* The correctness bits for [E]VRP cannot handle chained conditionals + when deciding to ignore a unreachable branch for setting SSA range info. */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ } -- cgit v1.1 From ade5ac7c7966c8e88a25f448fa737457364935a4 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 28 May 2021 14:26:02 +0200 Subject: diagnostics: Fix sporadic test failure it turns out to be reproducible this way: COLUMNS=80 make check-gcc-c RUNTESTFLAGS="plugin.exp=diagnostic*" Running /home/ed/gnu/gcc-trunk/gcc/testsuite/gcc.dg/plugin/plugin.exp ... FAIL: gcc.dg/plugin/diagnostic-test-expressions-1.c -fplugin=./diagnostic_plugin_test_tree_expression_range.so 1 blank line(s) in output FAIL: gcc.dg/plugin/diagnostic-test-expressions-1.c -fplugin=./diagnostic_plugin_test_tree_expression_range.so expected multiline pattern lines 550-551 not found: " __builtin_types_compatible_p \(long, int\) \+ f \(i\)\);.*\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\^~~~~~~\n" FAIL: gcc.dg/plugin/diagnostic-test-expressions-1.c -fplugin=./diagnostic_plugin_test_tree_expression_range.so (test for excess errors) a lot more errors happen with COLUMNS=20. 2021-05-29 Bernd Edlinger * gcc.dg/plugin/diagnostic_plugin_show_trees.c (plugin_init): Fix caret_max_with. * gcc.dg/plugin/diagnostic_plugin_test_inlining.c (plugin_init): Likewise. * gcc.dg/plugin/diagnostic_plugin_test_paths.c (plugin_init): Likewise. * gcc.dg/plugin/diagnostic_plugin_test_string_literals.c (plugin_init): Likewise. * gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c (plugin_init): Likewise. --- gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c | 2 ++ gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c | 2 ++ gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c | 2 ++ gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c | 2 ++ .../gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c | 2 ++ 5 files changed, 10 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c index 71e6740..ac72503 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c @@ -115,6 +115,8 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; + global_dc->caret_max_width = 80; + register_callback (plugin_name, PLUGIN_PRE_GENERICIZE, callback, diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c index 49b78cc..02c4629 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c @@ -169,6 +169,8 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; + global_dc->caret_max_width = 80; + pass_info.pass = new pass_test_inlining (g); pass_info.reference_pass_name = "*warn_function_noreturn"; pass_info.ref_pass_instance_number = 1; diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c index 7672875..5c2da02 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c @@ -450,6 +450,8 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; + global_dc->caret_max_width = 80; + pass_info.pass = make_pass_test_show_path (g); pass_info.reference_pass_name = "whole-program"; pass_info.ref_pass_instance_number = 1; diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c index cf99697..aa73dca 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c @@ -208,6 +208,8 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; + global_dc->caret_max_width = 80; + pass_info.pass = new pass_test_string_literals (g); pass_info.reference_pass_name = "ssa"; pass_info.ref_pass_instance_number = 1; diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c index 89cc95a..4a89d84 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c @@ -89,6 +89,8 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; + global_dc->caret_max_width = 130; + register_callback (plugin_name, PLUGIN_PRE_GENERICIZE, callback, -- cgit v1.1 From 715914d3f9e4e40af58d22103c7650cdd720ef92 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 31 May 2021 12:13:50 -0400 Subject: Do not calculate new values when evaluating a debug statement. Add a flag to enable/disable immediately improving poor values found during cache propagation. Then disable it when processing debug statements. gcc/ PR tree-optimization/100781 * gimple-range-cache.cc (ranger_cache::ranger_cache): Enable new value calculation by default. (ranger_cache::enable_new_values): New. (ranger_cache::disable_new_values): New. (ranger_cache::push_poor_value): Check if new values are allowed. * gimple-range-cache.h (class ranger_cache): New member/methods. * gimple-range.cc (gimple_ranger::range_of_expr): Check for debug statement, and disable/renable new value calculation. gcc/testsuite/ PR tree-optimization/100781 * gcc.dg/pr100781.c: New. --- gcc/testsuite/gcc.dg/pr100781.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100781.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100781.c b/gcc/testsuite/gcc.dg/pr100781.c new file mode 100644 index 0000000..c0e008a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100781.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --param=evrp-mode=ranger -fcompare-debug " } */ + +struct a { + int b; +}; +long c(short d, long e, struct a f) { +g:; + int h = f.b <= e, i = d, n = h >= d; + if (!n) + goto j; + goto k; +j:; + long l = 5; + if (l) + goto m; + d = 0; +m: + if (d) + return f.b; +k: + goto g; +} +int main() { } + -- cgit v1.1 From 18b88412069f51433e1b4f440d3c035bfc7b5cca Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 1 Jun 2021 05:26:02 -0400 Subject: Revert patch that disabled exporting of global ranges. Andrew's last set of changes fixes the bootstrap problem on i686 when global ranges are exported from evrp. The specific patch that fixes the problem is 715914d3: Author: Andrew MacLeod Date: Mon May 31 12:13:50 2021 -0400 Do not calculate new values when evaluating a debug statement. Add a flag to enable/disable immediately improving poor values found during cache propagation. Then disable it when processing debug statements. This patch reverts commit 2364b58 now that exporting of global ranges works. Tested on x86-64 Linux with default flags, and on i686 with the flags in the PR: --enable-clocale=gnu --with-system-zlib --with-demangler-in-ld --with-fpmath=sse --enable-languages=c,c++ --enable-cet i686-linux --enable-bootstrap --with-fpmath=sse --disable-libcc1 --disable-libcilkrts --disable-libsanitizer gcc/ChangeLog: * gimple-ssa-evrp.c: Enable exporting of global ranges. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-55.c: Adjust for global ranges changes. * gcc.dg/pr80776-1.c: Same. --- gcc/testsuite/gcc.dg/Wstringop-overflow-55.c | 8 ++++---- gcc/testsuite/gcc.dg/pr80776-1.c | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index 5f83af7..c3c2dbe 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -66,7 +66,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -74,7 +74,7 @@ void warn_ptrdiff_anti_range_add (ptrdiff_t i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } @@ -83,7 +83,7 @@ void warn_int_anti_range (int i) { i |= 1; - char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } } + char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" } char *p0 = ca5; // offset char *p1 = p0 + i; // 1-5 char *p2 = p1 + i; // 2-5 @@ -91,7 +91,7 @@ void warn_int_anti_range (int i) char *p4 = p3 + i; // 4-5 char *p5 = p4 + i; // 5 - memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } } + memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size" "pr?????" } sink (p0, p1, p2, p3, p4, p5); } diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index af41c0c..f3a120b 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,7 +17,5 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - /* The correctness bits for [E]VRP cannot handle chained conditionals - when deciding to ignore a unreachable branch for setting SSA range info. */ - sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ } -- cgit v1.1 From ea418485c700494c3efdc282854c5f5a08702416 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Mon, 31 May 2021 00:17:22 +0000 Subject: Fix PR 95481: tail call fails with empty struct types The problem here is we don't have an assignment type any more for empty structs as they were removed during gimplifcation. This adds a special case where the assignment var does not exist and the return decl is empty typed. OK? Tested on aarch64-linux-gnu with no regressions. Thanks, Andrew Pinski changes since v1: v2: Use is_empty_type instead of zero-sized type. gcc/ChangeLog: PR tree-optimization/95481 * tree-tailcall.c (find_tail_calls): Handle empty typed return decls. gcc/testsuite/ChangeLog: PR tree-optimization/95481 * gcc.dg/tree-ssa/tailcall-10.c: New test. * gcc.dg/tree-ssa/tailcall-11.c: New test. * gcc.dg/tree-ssa/tailcall-12.c: New test. * gcc.dg/tree-ssa/tailcall-13.c: New test. * gcc.dg/tree-ssa/tailrecursion-8.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c | 12 ++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c | 12 ++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c | 12 ++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c | 11 +++++++++++ 5 files changed, 62 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c new file mode 100644 index 0000000..484dcc1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc-details" } */ + +struct A {}; + +struct A goo(void); +struct A foo(void) +{ + return goo(); +} + +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c new file mode 100644 index 0000000..36e4417 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc-details" } */ + +struct A {}; + +void goo(void); +struct A foo(void) +{ + goo(); +} + +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c new file mode 100644 index 0000000..0eeb3ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc-details" } */ + +struct A {}; + +struct A goo(void); +void foo(void) +{ + goo(); +} + +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c new file mode 100644 index 0000000..855b3312 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc-details" } */ + +struct A {}; +struct B{}; + +struct B goo(void); +struct A foo(void) +{ + struct A a; + goo(); + return a; +} + +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c new file mode 100644 index 0000000..ecde499 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -foptimize-sibling-calls -fdump-tree-tailr1-details" } */ + +struct A {}; + +struct A foo() +{ + return foo(); +} + +/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr1"} } */ -- cgit v1.1 From c1681f22b4b44096f7bd8a2cf42f54762305c3ae Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 20 May 2021 10:57:49 +0200 Subject: Simplify option handling for -fsanitize-coverage gcc/ChangeLog: * common.opt: Use proper Enum values. * opts.c (COVERAGE_SANITIZER_OPT): Remove. (parse_sanitizer_options): Handle only sanitizer_opts. (common_handle_option): Just assign value. gcc/testsuite/ChangeLog: * gcc.dg/spellcheck-options-23.c: New test. --- gcc/testsuite/gcc.dg/spellcheck-options-23.c | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-23.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-23.c b/gcc/testsuite/gcc.dg/spellcheck-options-23.c new file mode 100644 index 0000000..575a28d --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-23.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=tracecmp" } */ + +/* { dg-error "unrecognized argument in option '-fsanitize-coverage=tracecmp'" "" { target *-*-* } 0 } */ +/* { dg-message "valid arguments to '-fsanitize-coverage=' are: trace-cmp trace-pc; did you mean 'trace-cmp'?" "" { target *-*-* } 0 } */ -- cgit v1.1 From 160fe6034bd2ca0073a722b6774518bb9ea5ac02 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 1 Jun 2021 17:48:30 +0200 Subject: Use known global ranges in export_global_ranges This patch modifies export_global_ranges to take into account current global ranges. It also handles enhances said function to export pointer global ranges as well. gcc/ChangeLog: * gimple-range.cc (gimple_ranger::export_global_ranges): Call update_global_range. * value-query.cc (update_global_range): New. * value-query.h (update_global_range): New. gcc/testsuite/ChangeLog: * gcc.dg/pr80776-1.c: XFAIL and document the reason why. --- gcc/testsuite/gcc.dg/pr80776-1.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index f3a120b..eca5e80 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,5 +17,15 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ + + /* Legacy evrp sets the range of i to [0, MAX] *before* the first conditional, + and to [0,999999] *before* the second conditional. This is because both + evrp and VRP use trickery to set global ranges when this particular use of + a __builtin_unreachable is in play (see uses of + assert_unreachable_fallthru_edge_p). + + Setting these ranges at the definition site, causes VRP to remove the + unreachable code altogether, leaving the following sprintf unguarded. This + causes the bogus warning below. */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ } -- cgit v1.1 From 8d7dae0eb366a88a1baba1857ecc54c09e4a520e Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Fri, 4 Jun 2021 17:37:15 +0200 Subject: i386: Add init pattern for V2HI vectors [PR100637] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2021-06-03 Uroš Bizjak gcc/ PR target/100637 * config/i386/i386-expand.c (ix86_expand_vector_init_duplicate): Handle V2HI mode. (ix86_expand_vector_init_general): Ditto. Use SImode instead of word_mode for logic operations when GET_MODE_SIZE (mode) < UNITS_PER_WORD. (expand_vec_perm_even_odd_1): Assert that V2HI mode should be implemented by expand_vec_perm_1. (expand_vec_perm_broadcast_1): Assert that V2HI and V4HI modes should be implemented using standard shuffle patterns. (ix86_vectorize_vec_perm_const): Handle V2HImode. Add V4HI and V2HI modes to modes, implementable with shuffle for one operand. * config/i386/mmx.md (*punpckwd): New insn_and_split pattern. (*pshufw_1): New insn pattern. (*vec_dupv2hi): Ditto. (vec_initv2hihi): New expander. gcc/testsuite/ PR target/100637 * gcc.dg/vect/slp-perm-9.c (dg-final): Adjust dumps for vect32 targets. --- gcc/testsuite/gcc.dg/vect/slp-perm-9.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c index ab75f44..873eddf 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c @@ -57,13 +57,13 @@ int main (int argc, const char* argv[]) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" { target { ! { vect_perm_short || vect_load_lanes } } } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm_short || vect_load_lanes } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" { target { ! { { vect_perm_short || vect32 } || vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { { vect_perm_short || vect32 } || vect_load_lanes } } } } */ /* We don't try permutes with a group size of 3 for variable-length vectors. */ /* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target { vect_perm_short && { { ! vect_perm3_short } && { ! vect_partial_vectors_usage_1 } } } xfail vect_variable_length } } } */ /* Try to vectorize the epilogue using partial vectors. */ /* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 2 "vect" { target { vect_perm_short && { { ! vect_perm3_short } && vect_partial_vectors_usage_1 } } xfail vect_variable_length } } } */ /* { dg-final { scan-tree-dump-not "permutation requires at least three vectors" "vect" { target vect_perm3_short } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { { ! vect_perm3_short } || vect_load_lanes } } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_short && { ! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { { ! { vect_perm3_short || vect32 } } || vect_load_lanes } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { { vect_perm3_short || vect32 } && { ! vect_load_lanes } } } } } */ -- cgit v1.1 From c6503fa93b5565c922f76611a55b0a53cd940a5f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 4 Jun 2021 10:35:27 -0600 Subject: PR c/100719 - missing -Wvla-parameter on a mismatch in second parameter gcc/ChangeLog: * attribs.c (init_attr_rdwr_indices): Use VLA bounds in the expected order. (attr_access::vla_bounds): Also handle VLA bounds. gcc/c-family/ChangeLog: * c-warn.c (warn_parm_array_mismatch): Check TREE_PURPOSE to test for element presence. gcc/testsuite/ChangeLog: * gcc.dg/Wvla-parameter-10.c: New test. * gcc.dg/Wvla-parameter-11.c: New test. --- gcc/testsuite/gcc.dg/Wvla-parameter-10.c | 68 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/Wvla-parameter-11.c | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wvla-parameter-10.c create mode 100644 gcc/testsuite/gcc.dg/Wvla-parameter-11.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-10.c b/gcc/testsuite/gcc.dg/Wvla-parameter-10.c new file mode 100644 index 0000000..68db3ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-10.c @@ -0,0 +1,68 @@ +/* PR c/100719 - missing -Wvla-parameter on a mismatch in second parameter + { dg-do compile } + { dg-options "-Wall" } */ + +typedef struct A1 { int i; } A1; +typedef struct A2 { int i; } A2; +typedef struct A3 { int i; } A3; + +void f2 (int n, A1[n], A2[n]); +void f2 (int n, A1[n], A2[n]); + +void f2_x1 (int n, A1[n], A2[n]); // { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" } +void f2_x1 (int n, A1[n + 1], A2[n]); // { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" } + +void f2_x2 (int n, A1[n], A2[n]); // { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" } +void f2_x2 (int n, A1[n], A2[n + 2]); // { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" } + + +void f3 (int n, A1[n], A2[n], A3[n]); +void f3 (int n, A1[n], A2[n], A3[n]); + +void f3_x1 (int n, A1[n], A2[n], A3[n]); +// { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void f3_x1 (int n, A1[n + 1], A2[n], A3[n]); +// { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" "" { target *-*-* } .-1 } + +void f3_x2 (int n, A1[n], A2[n], A3[n]); +// { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void f3_x2 (int n, A1[n], A2[n + 2], A3[n]); +// { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" "" { target *-*-* } .-1 } + +void f3_x3 (int n, A1[n], A2[n], A3[n]); +// { dg-note "previously declared as 'A3\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void f3_x3 (int n, A1[n], A2[n], A3[n + 3]); +// { dg-warning "argument 4 of type 'A3\\\[n \\+ 3]' declared with mismatched bound 'n \\+ 3'" "" { target *-*-* } .-1 } + + +void g3_x1 (int n, A1[n], A2[*], A3[n]); +// { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void g3_x1 (int n, A1[n + 1], A2[*], A3[n]); +// { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" "" { target *-*-* } .-1 } + +void g3_x2 (int n, A1[*], A2[n], A3[n]); +// { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void g3_x2 (int n, A1[*], A2[n + 2], A3[n]); +// { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" "" { target *-*-* } .-1 } + +void g3_x3 (int n, A1[*], A2[*], A3[n]); +// { dg-note "previously declared as 'A3\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void g3_x3 (int n, A1[*], A2[*], A3[n + 3]); +// { dg-warning "argument 4 of type 'A3\\\[n \\+ 3]' declared with mismatched bound 'n \\+ 3'" "" { target *-*-* } .-1 } + + +void h3_x1 (int n, A1[n], A2[ ], A3[n]); +// { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void h3_x1 (int n, A1[n + 1], A2[ ], A3[n]); +// { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" "" { target *-*-* } .-1 } + +void h3_x2 (int n, A1[ ], A2[n], A3[n]); +// { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void h3_x2 (int n, A1[ ], A2[n + 2], A3[n]); +// { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" "" { target *-*-* } .-1 } + +void h3_x3 (int n, A1[ ], A2[ ], A3[n]); +// { dg-note "previously declared as 'A3\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 } +void h3_x3 (int n, A1[ ], A2[ ], A3[n + 3]); +// { dg-warning "argument 4 of type 'A3\\\[n \\+ 3]' declared with mismatched bound 'n \\+ 3'" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-11.c b/gcc/testsuite/gcc.dg/Wvla-parameter-11.c new file mode 100644 index 0000000..39886a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-11.c @@ -0,0 +1,70 @@ +/* PR c/100719 - missing -Wvla-parameter on a mismatch in second parameter + { dg-do compile } + { dg-options "-Wall" } */ + +typedef struct A1 { int i; } A1; +typedef struct A2 { int i; } A2; +typedef struct A3 { int i; } A3; + +extern int n, n1, n2, n3; + +void f2 (int, A1[n], A2[n]); +void f2 (int, A1[n], A2[n]); + +void f2_x1 (int, A1[n], A2[n]); // { dg-note "previously declared as 'A1\\\[n]'" } +void f2_x1 (int, A1[n1], A2[n]); // { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" } + +void f2_x2 (int, A1[n], A2[n]); // { dg-note "previously declared as 'A2\\\[n]'" } +void f2_x2 (int, A1[n], A2[n2]); // { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" } + + +void f3 (int, A1[n], A2[n], A3[n]); +void f3 (int, A1[n], A2[n], A3[n]); + +void f3_x1 (int, A1[n], A2[n], A3[n]); +// { dg-note "previously declared as 'A1\\\[n]'" "note" { target *-*-* } .-1 } +void f3_x1 (int, A1[n1], A2[n], A3[n]); +// { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 } + +void f3_x2 (int, A1[n], A2[n], A3[n]); +// { dg-note "previously declared as 'A2\\\[n]'" "note" { target *-*-* } .-1 } +void f3_x2 (int, A1[n], A2[n2], A3[n]); +// { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" "" { target *-*-* } .-1 } + +void f3_x3 (int, A1[n], A2[n], A3[n]); +// { dg-note "previously declared as 'A3\\\[n]'" "note" { target *-*-* } .-1 } +void f3_x3 (int, A1[n], A2[n], A3[n3]); +// { dg-warning "argument 4 of type 'A3\\\[n3]' declared with mismatched bound 'n3'" "" { target *-*-* } .-1 } + + +void g3_x1 (int, A1[n], A2[*], A3[n]); +// { dg-note "previously declared as 'A1\\\[n]'" "note" { target *-*-* } .-1 } +void g3_x1 (int, A1[n1], A2[*], A3[n]); +// { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 } + +void g3_x2 (int, A1[*], A2[n], A3[n]); +// { dg-note "previously declared as 'A2\\\[n]'" "note" { target *-*-* } .-1 } +void g3_x2 (int, A1[*], A2[n2], A3[n]); +// { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" "" { target *-*-* } .-1 } + +void g3_x3 (int, A1[*], A2[*], A3[n]); +// { dg-note "previously declared as 'A3\\\[n]'" "note" { target *-*-* } .-1 } +void g3_x3 (int, A1[*], A2[*], A3[n3]); +// { dg-warning "argument 4 of type 'A3\\\[n3]' declared with mismatched bound 'n3'" "" { target *-*-* } .-1 } + + +void h3_x1 (int, A1[n], A2[ ], A3[n]); +// { dg-note "previously declared as 'A1\\\[n]'" "note" { target *-*-* } .-1 } +void h3_x1 (int, A1[n1], A2[ ], A3[n]); +// { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 } + +void h3_x2 (int, A1[ ], A2[n], A3[n]); +// { dg-note "previously declared as 'A2\\\[n]'" "note" { target *-*-* } .-1 } +void h3_x2 (int, A1[ ], A2[n2], A3[n]); +// { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" "" { target *-*-* } .-1 } + +void h3_x3 (int, A1[ ], A2[ ], A3[n]); +// { dg-note "previously declared as 'A3\\\[n]'" "note" { target *-*-* } .-1 } +void h3_x3 (int, A1[ ], A2[ ], A3[n3]); +// { dg-warning "argument 4 of type 'A3\\\[n3]' declared with mismatched bound 'n3'" "" { target *-*-* } .-1 } + -- cgit v1.1 From 9816f509db4966fcb90ed3baab72cc6cd901f06c Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 4 Jun 2021 10:49:06 -0600 Subject: PR middle-end/100732 - ICE on sprintf %s with integer argument gcc/ChangeLog: PR middle-end/100732 * gimple-fold.c (gimple_fold_builtin_sprintf): Avoid folding calls with either source or destination argument of invalid type. * tree-ssa-uninit.c (maybe_warn_pass_by_reference): Avoid checking calls with arguments of invalid type. gcc/testsuite/ChangeLog: PR middle-end/100732 * gcc.dg/tree-ssa/builtin-snprintf-11.c: New test. * gcc.dg/tree-ssa/builtin-snprintf-12.c: New test. * gcc.dg/tree-ssa/builtin-sprintf-28.c: New test. * gcc.dg/tree-ssa/builtin-sprintf-29.c: New test. * gcc.dg/uninit-pr100732.c: New test. --- .../gcc.dg/tree-ssa/builtin-snprintf-11.c | 32 +++++++++++++++++ .../gcc.dg/tree-ssa/builtin-snprintf-12.c | 36 +++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c | 30 ++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c | 40 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/uninit-pr100732.c | 21 ++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pr100732.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c new file mode 100644 index 0000000..73117c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c @@ -0,0 +1,32 @@ +/* PR middle-end/100732 - ICE on sprintf %s with integer argument + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +char d[32]; + +void gb (_Bool b) +{ + __builtin_snprintf (d, 32, "%s", b); // { dg-warning "\\\[-Wformat" } +} + +void gi (int i) +{ + __builtin_snprintf (d, 32, "%s", i); // { dg-warning "\\\[-Wformat" } +} + +void gd (char *d, double x) +{ + __builtin_snprintf (d, 32, "%s", x); // { dg-warning "\\\[-Wformat" } +} + + +struct X { int i; }; + +void gx (char *d, struct X x) +{ + __builtin_snprintf (d, 32, "%s", x); // { dg-warning "\\\[-Wformat" } +} + +/* Also verify that the invalid sprintf call isn't folded to strcpy. + { dg-final { scan-tree-dump-times "snprintf" 4 "optimized" } } + { dg-final { scan-tree-dump-not "strcpy" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c new file mode 100644 index 0000000..9e26356 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c @@ -0,0 +1,36 @@ +/* PR middle-end/100732 - ICE on sprintf %s with integer argument + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +#define snprintf(d, n, f, ...) \ + __builtin___snprintf_chk (d, n, 0, 32, f, __VA_ARGS__) + +int n; + +void gb (char *d, _Bool b) +{ + snprintf (d, n, "%s", b); // { dg-warning "\\\[-Wformat" } +} + +void gi (char *d, int i) +{ + snprintf (d, n, "%s", i); // { dg-warning "\\\[-Wformat" } +} + +void gd (char *d, double x) +{ + snprintf (d, n, "%s", x); // { dg-warning "\\\[-Wformat" } +} + + +struct X { int i; }; + +void gx (char *d, struct X x) +{ + snprintf (d, n, "%s", x); // { dg-warning "\\\[-Wformat" } +} + + +/* Also verify that the invalid sprintf call isn't folded to strcpy. + { dg-final { scan-tree-dump-times "snprintf_chk" 4 "optimized" } } + { dg-final { scan-tree-dump-not "strcpy" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c new file mode 100644 index 0000000..c1d0083 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c @@ -0,0 +1,30 @@ +/* PR middle-end/100732 - ICE on sprintf %s with integer argument + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +void gb (char *d, _Bool b) +{ + __builtin_sprintf (d, "%s", b); // { dg-warning "\\\[-Wformat" } +} + +void gi (char *d, int i) +{ + __builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" } +} + +void gd (char *d, double x) +{ + __builtin_sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" } +} + + +struct X { int i; }; + +void gx (char *d, struct X x) +{ + __builtin_sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" } +} + +/* Also verify that the invalid sprintf call isn't folded to strcpy. + { dg-final { scan-tree-dump-times "sprintf" 4 "optimized" } } + { dg-final { scan-tree-dump-not "strcpy" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c new file mode 100644 index 0000000..d0f7db2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c @@ -0,0 +1,40 @@ +/* PR middle-end/100732 - ICE on sprintf %s with integer argument + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +#define sprintf(d, f, ...) \ + __builtin___sprintf_chk (d, 0, 32, f, __VA_ARGS__) + + +void fi (int i, const char *s) +{ + sprintf (i, "%s", s); // { dg-warning "\\\[-Wint-conversion" } +} + +void gb (char *d, _Bool b) +{ + sprintf (d, "%s", b); // { dg-warning "\\\[-Wformat" } +} + +void gi (char *d, int i) +{ + sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" } +} + +void gd (char *d, double x) +{ + sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" } +} + + +struct X { int i; }; + +void gx (char *d, struct X x) +{ + sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" } +} + + +/* Also verify that the invalid sprintf call isn't folded to strcpy. + { dg-final { scan-tree-dump-times "sprintf_chk" 5 "optimized" } } + { dg-final { scan-tree-dump-not "strcpy" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/uninit-pr100732.c b/gcc/testsuite/gcc.dg/uninit-pr100732.c new file mode 100644 index 0000000..9c847ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr100732.c @@ -0,0 +1,21 @@ +/* PR middle-end/100732 - ICE on sprintf %s with integer argument + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +void nowarn_s_i (char *d, int i) +{ + __builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" } +} + +void warn_s_i (char *d) +{ + int i; + __builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" } + // { dg-warning "\\\[-Wuninitialized" "" { target *-*-* } .-1 } +} + +void warn_i_i (char *d) +{ + int i; + __builtin_sprintf (d, "%i", i); // { dg-warning "\\\[-Wuninitialized" } +} -- cgit v1.1 From 5328cad24f7460a39b2def12bb9b62be36c92a54 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 4 Jun 2021 11:21:51 -0600 Subject: PR c/100783 - ICE on -Wnonnull and erroneous type gcc/c-family/ChangeLog: PR c/100783 * c-attribs.c (positional_argument): Bail on erroneous types. gcc/c/ChangeLog: PR c/100783 * c-objc-common.c (print_type): Handle erroneous types. gcc/testsuite/ChangeLog: PR c/100783 * gcc.dg/nonnull-6.c: New test. --- gcc/testsuite/gcc.dg/nonnull-6.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/nonnull-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/nonnull-6.c b/gcc/testsuite/gcc.dg/nonnull-6.c new file mode 100644 index 0000000..8f36870 --- /dev/null +++ b/gcc/testsuite/gcc.dg/nonnull-6.c @@ -0,0 +1,15 @@ +/* PR c/100783 - ICE on -Wnonnull and erroneous type + { dg-do compile } + { dg-options "-Wall" } */ + +__attribute__((nonnull (1))) void +f1 (char[][n]); // { dg-error "undeclared" } + +__attribute__((nonnull (2))) void +f2 (int n, char[n][m]); // { dg-error "undeclared" } + +__attribute__((nonnull (1))) void +f3 (char[*][n]); // { dg-error "undeclared" } + +__attribute__((nonnull (1))) void +f4 (char[f1]); // { dg-error "size" } -- cgit v1.1 From a589877a0036fc2f66b7a957859940c53efdc7c9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 6 Jun 2021 11:37:45 +0200 Subject: Fix thinko in new warning on type punning for storage order purposes In C, unlike in Ada, the storage order of arrays is that of their component type, so you need to look at it when deciding to warn. And the PR complains about a bogus warning on the assignment of a pointer returned by alloca or malloc, so this also fixes that. gcc/c PR c/100920 * c-decl.c (finish_struct): Fix thinko in previous change. * c-typeck.c (convert_for_assignment): Do not warn on pointer assignment and initialization for storage order purposes if the RHS is a call to a DECL_IS_MALLOC function. gcc/testsuite/ * gcc.dg/sso-14.c: New test. --- gcc/testsuite/gcc.dg/sso-14.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sso-14.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-14.c b/gcc/testsuite/gcc.dg/sso-14.c new file mode 100644 index 0000000..af98145 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-14.c @@ -0,0 +1,53 @@ +/* PR c/100920 */ +/* Testcase by George Thopas */ + +/* { dg-do compile } */ + +#include +#include + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) +#else +#define REV_ENDIANNESS __attribute__((scalar_storage_order("little-endian"))) +#endif + +struct s_1 { + int val; +} REV_ENDIANNESS; + +typedef struct s_1 t_1; + +struct s_2 { + char val; +} REV_ENDIANNESS; + +typedef struct s_2 t_2; + +struct s12 { + t_1 a[1]; + t_2 b[1]; +} REV_ENDIANNESS; + +typedef struct s12 t_s12; + +union u12 { + t_1 a[1]; + t_2 b[1]; +} REV_ENDIANNESS; + +typedef union u12 t_u12; + +int main(void) +{ + t_s12 *msg1 = __builtin_alloca(10); + t_u12 *msg2 = __builtin_alloca(10); + + msg1 = malloc (sizeof (t_s12)); + msg2 = malloc (sizeof (t_u12)); + + msg1->a[0].val = 0; + msg2->a[0].val = 0; + + return 0; +} -- cgit v1.1 From cb4b99be48af1c0911ce2a957af20d9cd946f364 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 6 Jun 2021 19:38:41 +0200 Subject: openmp: Add testcase for scan directive with nested functions > In convert_nonlocal_omp_clauses, the following clauses are > missing: OMP_CLAUSE_AFFINITY, OMP_CLAUSE_DEVICE_TYPE, > OMP_CLAUSE_EXCLUSIVE, OMP_CLAUSE_INCLUSIVE. OMP_CLAUSE_{EXCLUSIVE,INCLUSIVE} isn't needed, because we don't walk the clauses at all for GIMPLE_OMP_SCAN. It would be a bug if we used the exclusive/inclusive operands after gimplification, but we apparently don't do that, all we check is whether the OMP_CLAUSE_KIND of the first clause (all should be the same) is OMP_CLAUSE_EXCLUSIVE or OMP_CLAUSE_INCLUSIVE, nothing else. That said, I think we should have a testcase. 2021-06-06 Jakub Jelinek * gcc.dg/gomp/scan-1.c: New test. --- gcc/testsuite/gcc.dg/gomp/scan-1.c | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gomp/scan-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/scan-1.c b/gcc/testsuite/gcc.dg/gomp/scan-1.c new file mode 100644 index 0000000..807071d --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/scan-1.c @@ -0,0 +1,51 @@ +int baz (void); +void qux (int); +int r; + +int +foo (void) +{ + int r = 0, i; + void bar (void) { r++; } + #pragma omp parallel for reduction(inscan, +:r) + for (i = 0; i < 64; i++) + { + r += baz (); + #pragma omp scan inclusive(r) + qux (r); + } + #pragma omp parallel for reduction(inscan, +:r) + for (i = 0; i < 64; i++) + { + qux (r); + #pragma omp scan exclusive(r) + r += baz (); + } + bar (); + return r; +} + +int +corge (void) +{ + int r = 0, i; + void bar (void) + { + #pragma omp parallel for reduction(inscan, +:r) + for (i = 0; i < 64; i++) + { + r += baz (); + #pragma omp scan inclusive(r) + qux (r); + } + #pragma omp parallel for reduction(inscan, +:r) + for (i = 0; i < 64; i++) + { + qux (r); + #pragma omp scan exclusive(r) + r += baz (); + } + } + bar (); + return r; +} -- cgit v1.1 From e1521b170b44be5cd5d36a98b6b760457b68f566 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 7 Jun 2021 09:28:31 +0200 Subject: fold-const: Fix up fold_read_from_vector [PR100887] The callers of fold_read_from_vector expect that the index they pass is an index of an element in the vector and the function does that most of the time. But we allow CONSTRUCTORs with VECTOR_TYPE to have VECTOR_TYPE elements and in that case every CONSTRUCTOR element represents not just one index (with the exception of V1 vectors), but multiple. So returning zero vector if i >= CONSTRUCTOR_NELTS or returning some CONSTRUCTOR_ELT's value might not be what the callers expect. Fixed by punting if the first element has vector type. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? In theory we could instead recurse (and assert that for CONSTRUCTORs of vector elements we have always all elements specified like tree-cfg.c verifies?) after adjusting the index appropriately. 2021-06-07 Jakub Jelinek PR target/100887 * fold-const.c (fold_read_from_vector): Return NULL if trying to read from a CONSTRUCTOR with vector type elements. * gcc.dg/pr100887.c: New test. --- gcc/testsuite/gcc.dg/pr100887.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100887.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100887.c b/gcc/testsuite/gcc.dg/pr100887.c new file mode 100644 index 0000000..de6b3ef --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100887.c @@ -0,0 +1,14 @@ +/* PR target/100887 */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */ + +typedef unsigned long long __attribute__((__vector_size__ (2 * sizeof (long long)))) U; +typedef unsigned long long __attribute__((__vector_size__ (4 * sizeof (long long)))) V; +typedef unsigned long long __attribute__((__vector_size__ (8 * sizeof (long long)))) W; + +U +foo (V v) +{ + return __builtin_shufflevector ((W){}, v, 0, 8); +} -- cgit v1.1 From 97d83259b91fb558f5b09bfb09529900f585c4c9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Jun 2021 18:17:31 +0200 Subject: Fix old thinko in warning on pointer for storage order purposes gcc/c PR c/100920 * c-typeck.c (convert_for_assignment): Test fndecl_built_in_p to spot built-in functions. gcc/testsuite/ * gcc.dg/sso-14.c: Adjust. --- gcc/testsuite/gcc.dg/sso-14.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-14.c b/gcc/testsuite/gcc.dg/sso-14.c index af98145..8941946 100644 --- a/gcc/testsuite/gcc.dg/sso-14.c +++ b/gcc/testsuite/gcc.dg/sso-14.c @@ -5,6 +5,7 @@ #include #include +#include #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) @@ -42,12 +43,14 @@ int main(void) { t_s12 *msg1 = __builtin_alloca(10); t_u12 *msg2 = __builtin_alloca(10); + int same; msg1 = malloc (sizeof (t_s12)); msg2 = malloc (sizeof (t_u12)); - msg1->a[0].val = 0; - msg2->a[0].val = 0; + memset (msg1, 0, sizeof (t_s12)); + memcpy (msg2, &msg1, sizeof (t_s12)); + same = memcmp (msg1, msg2, sizeof (t_s12)); return 0; } -- cgit v1.1 From 4db34072d5336d13b66f7185ec6454aa7d36f3c7 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Mon, 7 Jun 2021 22:10:33 -0500 Subject: predcom: Enabled by loop vect at O2 [PR100794] As PR100794 shows, in the current implementation PRE bypasses some optimization to avoid introducing loop carried dependence which stops loop vectorizer to vectorize the loop. At -O2, there is no downstream pass to re-catch this kind of opportunity if loop vectorizer fails to vectorize that loop. This patch follows Richi's suggestion in the PR, if predcom flag isn't set and loop vectorization will enable predcom without any unrolling implicitly. The Power9 SPEC2017 evaluation showed it can speed up 521.wrf_r 3.30% and 554.roms_r 1.08% at very-cheap cost model, no remarkable impact at cheap cost model, the build time and size impact is fine (see the PR for the details). By the way, I tested another proposal to guard PRE not skip the optimization for cheap and very-cheap vect cost models, the evaluation results showed it's fine with very cheap cost model, but it can degrade some bmks like 521.wrf_r -9.17% and 549.fotonik3d_r -2.07% etc. Bootstrapped/regtested on powerpc64le-linux-gnu P9, x86_64-redhat-linux and aarch64-linux-gnu. gcc/ChangeLog: PR tree-optimization/100794 * tree-predcom.c (tree_predictive_commoning_loop): Add parameter allow_unroll_p and only allow unrolling when it's true. (tree_predictive_commoning): Add parameter allow_unroll_p and adjust for it. (run_tree_predictive_commoning): Likewise. (pass_predcom::gate): Check flag_tree_loop_vectorize and global_options_set.x_flag_predictive_commoning. (pass_predcom::execute): Adjust for allow_unroll_p. gcc/testsuite/ChangeLog: PR tree-optimization/100794 * gcc.dg/tree-ssa/pr100794.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr100794.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr100794.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100794.c b/gcc/testsuite/gcc.dg/tree-ssa/pr100794.c new file mode 100644 index 0000000..6f707ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr100794.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-vectorize -fdump-tree-pcom-details -fdisable-tree-vect" } */ + +extern double arr[100]; +extern double foo (double, double); +extern double sum; + +void +test (int i_0, int i_n) +{ + int i; + for (i = i_0; i < i_n - 1; i++) + { + double a = arr[i]; + double b = arr[i + 1]; + sum += a * b; + } +} + +/* { dg-final { scan-tree-dump "Executing predictive commoning without unrolling" "pcom" } } */ -- cgit v1.1 From 48aa5c60034736a439f2214dac34b165e74a7d20 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 8 Jun 2021 09:42:18 +0200 Subject: Fix "tailing" typo. gcc/fortran/ChangeLog: * intrinsic.texi: Fix typo. * trans-expr.c (gfc_trans_pointer_assignment): Likewise. gcc/ChangeLog: * genautomata.c (create_automata): Fix typo. libgfortran/ChangeLog: * intrinsics/chmod.c (chmod_internal): Fix typo. * io/transfer.c (read_sf): Likewise. libquadmath/ChangeLog: * libquadmath.texi: Fix typo. gcc/testsuite/ChangeLog: * gcc.dg/format/strfmon-1.c: Fix typo. * gfortran.dg/char4-subscript.f90: Likewise. --- gcc/testsuite/gcc.dg/format/strfmon-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/format/strfmon-1.c b/gcc/testsuite/gcc.dg/format/strfmon-1.c index 934242a..a790db5 100644 --- a/gcc/testsuite/gcc.dg/format/strfmon-1.c +++ b/gcc/testsuite/gcc.dg/format/strfmon-1.c @@ -57,7 +57,7 @@ foo (char *s, size_t m, double d, long double ld) strfmon (s, m, "%n%n", d); /* { dg-warning "matching" "too few args" } */ strfmon (s, m, ""); /* { dg-warning "zero-length" "empty" } */ strfmon (s, m, NULL); /* { dg-warning "null" "null format string" } */ - strfmon (s, m, "%"); /* { dg-warning "trailing" "tailing %" } */ + strfmon (s, m, "%"); /* { dg-warning "trailing" "trailing %" } */ strfmon (s, m, "%n\0", d); /* { dg-warning "embedded" "embedded NUL" } */ strfmon (s, m, "%^^n", d); /* { dg-warning "repeated" "repeated flag" } */ } -- cgit v1.1 From ec2174c6957e97bd69c001a782cd52b98e6ba2fb Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 8 Jun 2021 10:06:13 +0200 Subject: testsuite: Add -Wno-psabi -w to pr100887.c test [PR100943] On x86 the test is using -mavx512f and so never reports the various -Wpsabi notes/warnings, but on other targets it can. 2021-06-08 Jakub Jelinek PR target/100887 PR testsuite/100943 * gcc.dg/pr100887.c: Add -Wno-psabi -w to dg-options. --- gcc/testsuite/gcc.dg/pr100887.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100887.c b/gcc/testsuite/gcc.dg/pr100887.c index de6b3ef..027025f 100644 --- a/gcc/testsuite/gcc.dg/pr100887.c +++ b/gcc/testsuite/gcc.dg/pr100887.c @@ -1,6 +1,6 @@ /* PR target/100887 */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-Wno-psabi -w" } */ /* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */ typedef unsigned long long __attribute__((__vector_size__ (2 * sizeof (long long)))) U; -- cgit v1.1 From 7a56d3d3e99cc77ad8a6a674870c814da6225675 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 8 Jun 2021 12:52:12 +0200 Subject: tree-optimization/100923 - fix alias-ref construction wrt availability This PR shows that building an ao_ref from value-numbers is prone to expose bogus contextual alias info to the oracle. The following makes sure to construct ao_refs from SSA names available at the program point only. On the way it modifies the awkward valueize_refs[_1] API. 2021-06-08 Richard Biener PR tree-optimization/100923 * tree-ssa-sccvn.c (valueize_refs_1): Take a pointer to the operand vector to be valueized. (valueize_refs): Likewise. (valueize_shared_reference_ops_from_ref): Adjust. (valueize_shared_reference_ops_from_call): Likewise. (vn_reference_lookup_3): Likewise. (vn_reference_lookup_pieces): Likewise. Re-valueize with honoring availability when we are about to create the ao_ref and valueized before. (vn_reference_lookup): Likewise. (vn_reference_insert_pieces): Adjust. * gcc.dg/torture/pr100923.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100923.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100923.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100923.c b/gcc/testsuite/gcc.dg/torture/pr100923.c new file mode 100644 index 0000000..05a6341 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100923.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +int a = 1, b, c, *d = &a, *e = &a, f; +void g(int h) {} +void k(int *l) +{ + int ***j; + if (c) + { + *j = &l; + ***j; + } + g(*l); + *e = f; + if (*l) + { + int i = b / a; + a = i; + } +} +int main() +{ + k(d); + return 0; +} -- cgit v1.1 From d3b1ef7a83c0c0cd5b20a1dd1714b868f3d2b442 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 8 Jun 2021 14:45:57 -0400 Subject: analyzer: bitfield fixes [PR99212] This patch verifies the previous fix for bitfield sizes by implementing enough support for bitfields in the analyzer to get the test cases to pass. The patch implements support in the analyzer for reading from a BIT_FIELD_REF, and support for folding BIT_AND_EXPR of a mask, to handle the cases generated in tests. The existing bitfields tests in data-model-1.c turned out to rely on undefined behavior, in that they were assigning values to a signed bitfield that were outside of the valid range of values. I believe that that's why we were seeing target-specific differences in the test results (PR analyzer/99212). The patch updates the test to remove the undefined behaviors. gcc/analyzer/ChangeLog: PR analyzer/99212 * region-model-manager.cc (region_model_manager::maybe_fold_binop): Add support for folding BIT_AND_EXPR of compound_svalue and a mask constant. * region-model.cc (region_model::get_rvalue_1): Implement BIT_FIELD_REF in terms of... (region_model::get_rvalue_for_bits): New function. * region-model.h (region_model::get_rvalue_for_bits): New decl. * store.cc (bit_range::from_mask): New function. (selftest::test_bit_range_intersects_p): New selftest. (selftest::assert_bit_range_from_mask_eq): New. (ASSERT_BIT_RANGE_FROM_MASK_EQ): New macro. (selftest::assert_no_bit_range_from_mask_eq): New. (ASSERT_NO_BIT_RANGE_FROM_MASK): New macro. (selftest::test_bit_range_from_mask): New selftest. (selftest::analyzer_store_cc_tests): Call the new selftests. * store.h (bit_range::intersects_p): New. (bit_range::from_mask): New decl. (concrete_binding::get_bit_range): New accessor. (store_manager::get_concrete_binding): New overload taking const bit_range &. gcc/testsuite/ChangeLog: PR analyzer/99212 * gcc.dg/analyzer/bitfields-1.c: New test. * gcc.dg/analyzer/data-model-1.c (struct sbits): Make bitfields explicitly signed. (test_44): Update test values assigned to the bits to ones that fit in the range of the bitfield type. Remove xfails. (test_45): Remove xfails. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/bitfields-1.c | 144 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/data-model-1.c | 30 ++---- 2 files changed, 154 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/bitfields-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/bitfields-1.c b/gcc/testsuite/gcc.dg/analyzer/bitfields-1.c new file mode 100644 index 0000000..8bbe76b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/bitfields-1.c @@ -0,0 +1,144 @@ +#include "analyzer-decls.h" + +typedef unsigned char u8; +typedef unsigned __INT16_TYPE__ u16; +typedef unsigned __INT32_TYPE__ u32; + +struct st1 +{ + u16 nonzero_offset; + unsigned int f0 : 1; + unsigned int f1 : 1; + unsigned int f2 : 1; + unsigned int f3 : 1; + unsigned int f4 : 1; + unsigned int f5 : 1; + unsigned int f6 : 1; + unsigned int f7 : 1; +}; + +void test_1 (void) +{ + struct st1 s; + s.f0 = 0; + __analyzer_eval (s.f0 == 0); /* { dg-warning "TRUE" } */ + s.f0 = 1; + __analyzer_eval (s.f0 == 1); /* { dg-warning "TRUE" } */ + + s.f1 = 0; + __analyzer_eval (s.f1 == 0); /* { dg-warning "TRUE" } */ + s.f1 = 1; + __analyzer_eval (s.f1 == 1); /* { dg-warning "TRUE" } */ + + /* etc */ + + s.f6 = 0; + __analyzer_eval (s.f6 == 0); /* { dg-warning "TRUE" } */ + s.f6 = 1; + __analyzer_eval (s.f6 == 1); /* { dg-warning "TRUE" } */ + + s.f7 = 0; + __analyzer_eval (s.f7 == 0); /* { dg-warning "TRUE" } */ + s.f7 = 1; + __analyzer_eval (s.f7 == 1); /* { dg-warning "TRUE" } */ +}; + +void test_2 (_Bool v0, _Bool v1, _Bool v2, _Bool v3, + _Bool v4, _Bool v5, _Bool v6, _Bool v7) +{ + struct st1 s; + s.f0 = v0; + s.f1 = v1; + s.f2 = v2; + s.f3 = v3; + s.f4 = v4; + s.f5 = v5; + s.f6 = v6; + s.f7 = v7; + + __analyzer_eval (s.f0 == v0); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f1 == v1); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f2 == v2); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f3 == v3); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f4 == v4); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f5 == v5); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f6 == v6); /* { dg-warning "TRUE" } */ + __analyzer_eval (s.f7 == v7); /* { dg-warning "TRUE" } */ +}; + +struct st3 +{ + unsigned int f01 : 2; + unsigned int f23 : 2; + unsigned int f34 : 2; + unsigned int f56 : 2; +}; + +void test_3 (void) +{ + struct st3 s; + s.f01 = 0; + __analyzer_eval (s.f01 == 0); /* { dg-warning "TRUE" } */ + s.f01 = 1; + __analyzer_eval (s.f01 == 1); /* { dg-warning "TRUE" } */ + s.f01 = 2; + __analyzer_eval (s.f01 == 2); /* { dg-warning "TRUE" } */ + s.f01 = 3; + __analyzer_eval (s.f01 == 3); /* { dg-warning "TRUE" } */ + + /* etc */ + + s.f56 = 0; + __analyzer_eval (s.f56 == 0); /* { dg-warning "TRUE" } */ + s.f56 = 1; + __analyzer_eval (s.f56 == 1); /* { dg-warning "TRUE" } */ + s.f56 = 2; + __analyzer_eval (s.f56 == 2); /* { dg-warning "TRUE" } */ + s.f56 = 3; + __analyzer_eval (s.f56 == 3); /* { dg-warning "TRUE" } */ +}; + +/* A signed bitfield. */ + +struct st4 +{ + signed int f012 : 3; + signed int f345 : 3; +}; + +void test_4 (void) +{ + struct st4 s; + s.f345 = -4; + __analyzer_eval (s.f345 == -4); /* { dg-warning "TRUE" } */ + s.f345 = -3; + __analyzer_eval (s.f345 == -3); /* { dg-warning "TRUE" } */ + s.f345 = -2; + __analyzer_eval (s.f345 == -2); /* { dg-warning "TRUE" } */ + s.f345 = -1; + __analyzer_eval (s.f345 == -1); /* { dg-warning "TRUE" } */ + s.f345 = 0; + __analyzer_eval (s.f345 == 0); /* { dg-warning "TRUE" } */ + s.f345 = 1; + __analyzer_eval (s.f345 == 1); /* { dg-warning "TRUE" } */ + s.f345 = 2; + __analyzer_eval (s.f345 == 2); /* { dg-warning "TRUE" } */ + s.f345 = 3; + __analyzer_eval (s.f345 == 3); /* { dg-warning "TRUE" } */ +}; + +/* A zero bitfield to break up padding. */ + +struct st5 +{ + unsigned f0 : 5; + unsigned :0; + unsigned f1 : 16; +}; + +void test_5 (void) +{ + struct st5 s; + s.f1 = 0xcafe; + __analyzer_eval (s.f1 == 0xcafe); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index c0f5463..4a62a0e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -934,24 +934,20 @@ void test_43 (void) struct sbits { - int b0 : 1; - int b123 : 3; - int b456 : 3; - int b7 : 1; + signed int b0 : 1; + signed int b123 : 3; + signed int b456 : 3; + signed int b7 : 1; }; void test_44 (void) { struct sbits bits; - bits.b0 = 1; - __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "FALSE" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): ^^^^ + bits.b0 = -1; + __analyzer_eval (bits.b0 == -1); /* { dg-warning "TRUE" } */ - bits.b456 = 5; - __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "FALSE" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): ^^^^ + bits.b456 = -4; + __analyzer_eval (bits.b456 == -4); /* { dg-warning "TRUE" } */ }; struct ubits @@ -962,20 +958,14 @@ struct ubits unsigned int b7 : 1; }; -/* FIXME: this requires BIT_FIELD_REF to work. */ - void test_45 (void) { struct ubits bits; bits.b0 = 1; - __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" "desired, PR99212" { xfail { ! { cris-*-* } } } } */ - /* { dg-warning "UNKNOWN" "status quo, PR99212" { target { *-*-* } xfail { cris-*-* } } .-1 } */ - // TODO(xfail): ^^^^ + __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" } */ bits.b456 = 5; - __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): ^^^^ + __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" } */ }; extern const char *char_ptr; -- cgit v1.1 From c4574d23cb07340918793a5a98ae7bb2988b3791 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Tue, 1 Jun 2021 06:48:05 +0000 Subject: Improve match_simplify_replacement in phi-opt This improves match_simplify_replace in phi-opt to handle the case where there is one cheap (non-call) preparation statement in the middle basic block similar to xor_replacement and others. This allows to remove xor_replacement which it does too. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Thanks, Andrew Pinski Changes since v1: v3 - Just minor changes to using gimple_assign_lhs instead of gimple_lhs and fixing a comment. v2 - change the check on the preparation statement to allow only assignments and no calls and only assignments that feed into the phi. gcc/ChangeLog: PR tree-optimization/25290 * tree-ssa-phiopt.c (xor_replacement): Delete. (tree_ssa_phiopt_worker): Delete use of xor_replacement. (match_simplify_replacement): Allow one cheap preparation statement that can be moved to before the if. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr96928-1.c: Fix testcase for now that ~ happens on the outside of the bit_xor. --- gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c index a2770e5..2e86620 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c @@ -1,9 +1,9 @@ /* PR tree-optimization/96928 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */ /* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ -/* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ -- cgit v1.1 From ce670e4faafb296d1f1a7828d20f8c8ba4686797 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 18 Nov 2020 14:17:34 +0100 Subject: tree-optimization/97832 - handle associatable chains in SLP discovery This makes SLP discovery handle associatable (including mixed plus/minus) chains better by swapping operands across the whole chain. To work this adds caching of the 'matches' lanes for failed SLP discovery attempts, thereby fixing a failed SLP discovery for the slp-pr98855.cc testcase which results in building an operand from scalars as expected. Unfortunately this makes us trip over the cost threshold so I'm XFAILing the testcase for now. For BB vectorization all this doesn't work because we have no way to distinguish good from bad associations as we eventually build operands from scalars and thus not fail in the classical sense. 2021-05-31 Richard Biener PR tree-optimization/97832 * tree-vectorizer.h (_slp_tree::failed): New. * tree-vect-slp.c (_slp_tree::_slp_tree): Initialize failed member. (_slp_tree::~_slp_tree): Free failed. (vect_build_slp_tree): Retain failed nodes and record matches in them, copying that back out when running into a cached fail. Dump start and end of discovery. (dt_sort_cmp): New. (vect_build_slp_tree_2): Handle associatable chains together doing more aggressive operand swapping. * gcc.dg/vect/pr97832-1.c: New testcase. * gcc.dg/vect/pr97832-2.c: Likewise. * gcc.dg/vect/pr97832-3.c: Likewise. * g++.dg/vect/slp-pr98855.cc: XFAIL. --- gcc/testsuite/gcc.dg/vect/pr97832-1.c | 17 ++++++++++++ gcc/testsuite/gcc.dg/vect/pr97832-2.c | 29 ++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/pr97832-3.c | 50 +++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/slp-50.c | 20 ++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr97832-1.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr97832-2.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr97832-3.c create mode 100644 gcc/testsuite/gcc.dg/vect/slp-50.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr97832-1.c b/gcc/testsuite/gcc.dg/vect/pr97832-1.c new file mode 100644 index 0000000..063fc7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr97832-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast" } */ +/* { dg-require-effective-target vect_double } */ + +double a[1024], b[1024], c[1024]; + +void foo() +{ + for (int i = 0; i < 256; ++i) + { + a[2*i] = a[2*i] + b[2*i] - c[2*i]; + a[2*i+1] = a[2*i+1] - b[2*i+1] - c[2*i+1]; + } +} + +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr97832-2.c b/gcc/testsuite/gcc.dg/vect/pr97832-2.c new file mode 100644 index 0000000..4f05781 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr97832-2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast" } */ +/* { dg-require-effective-target vect_double } */ + +void foo1x1(double* restrict y, const double* restrict x, int clen) +{ + int xi = clen & 2; + double f_re = x[0+xi+0]; + double f_im = x[4+xi+0]; + int clen2 = (clen+xi) * 2; +#pragma GCC unroll 0 + for (int c = 0; c < clen2; c += 8) { + // y[c] = y[c] - x[c]*conj(f); +#pragma GCC unroll 4 + for (int k = 0; k < 4; ++k) { + double x_re = x[c+0+k]; + double x_im = x[c+4+k]; + double y_re = y[c+0+k]; + double y_im = y[c+4+k]; + y_re = y_re - x_re * f_re - x_im * f_im;; + y_im = y_im + x_re * f_im - x_im * f_re; + y[c+0+k] = y_re; + y[c+4+k] = y_im; + } + } +} + +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr97832-3.c b/gcc/testsuite/gcc.dg/vect/pr97832-3.c new file mode 100644 index 0000000..ad1225d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr97832-3.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast" } */ +/* { dg-require-effective-target vect_double } */ + +void foo(double* restrict y, const double* restrict x0, const double* restrict x1, int clen) +{ + int xi = clen & 2; + double f00_re = x0[0+xi+0]; + double f10_re = x1[0+xi+0]; + double f01_re = x0[0+xi+1]; + double f11_re = x1[0+xi+1]; + double f00_im = x0[4+xi+0]; + double f10_im = x1[4+xi+0]; + double f01_im = x0[4+xi+1]; + double f11_im = x1[4+xi+1]; + int clen2 = (clen+xi) * 2; + double* y0 = &y[0]; + double* y1 = &y[clen2]; + #pragma GCC unroll 0 + for (int c = 0; c < clen2; c += 8) { + // y0[c] = y0[c] - x0[c]*conj(f00) - x1[c]*conj(f10); + // y1[c] = y1[c] - x0[c]*conj(f01) - x1[c]*conj(f11); + #pragma GCC unroll 4 + for (int k = 0; k < 4; ++k) { + double x0_re = x0[c+0+k]; + double x0_im = x0[c+4+k]; + double y0_re = y0[c+0+k]; + double y0_im = y0[c+4+k]; + double y1_re = y1[c+0+k]; + double y1_im = y1[c+4+k]; + y0_re = y0_re - x0_re * f00_re - x0_im * f00_im; + y0_im = y0_im + x0_re * f00_im - x0_im * f00_re; + y1_re = y1_re - x0_re * f01_re - x0_im * f01_im; + y1_im = y1_im + x0_re * f01_im - x0_im * f01_re; + double x1_re = x1[c+0+k]; + double x1_im = x1[c+4+k]; + y0_re = y0_re - x1_re * f10_re - x1_im * f10_im; + y0_im = y0_im + x1_re * f10_im - x1_im * f10_re; + y1_re = y1_re - x1_re * f11_re - x1_im * f11_im; + y1_im = y1_im + x1_re * f11_im - x1_im * f11_re; + y0[c+0+k] = y0_re; + y0[c+4+k] = y0_im; + y1[c+0+k] = y1_re; + y1[c+4+k] = y1_im; + } + } +} + +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-50.c b/gcc/testsuite/gcc.dg/vect/slp-50.c new file mode 100644 index 0000000..17509e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-50.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math" } */ + +typedef int Quantum; +typedef struct { + Quantum blue, green; +} PixelPacket; +PixelPacket *EnhanceImage_image_q; +int EnhanceImage_image_x; +float EnhanceImage_image_distance_squared_total_weight; +void EnhanceImage_image_distance_squared() +{ + float zero_1; + for (; EnhanceImage_image_x; EnhanceImage_image_x++) { + EnhanceImage_image_distance_squared_total_weight += 5.0; + EnhanceImage_image_q->green = EnhanceImage_image_q->blue = + zero_1 + EnhanceImage_image_distance_squared_total_weight / 2 - 1; + EnhanceImage_image_q++; + } +} -- cgit v1.1 From 2c17b5f8cca82d1957242055991a2c23184a1af1 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 9 Jun 2021 11:23:41 -0400 Subject: [PATCH] PR middle-end/53267: Constant fold BUILT_IN_FMOD. gcc/ChangeLog PR middle-end/53267 * fold-const-call.c (fold_const_call_sss) [CASE_CFN_FMOD]: Support evaluation of fmod/fmodf/fmodl at compile-time. gcc/testsuite/ChangeLog * gcc.dg/builtins-70.c: New test. --- gcc/testsuite/gcc.dg/builtins-70.c | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/builtins-70.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/builtins-70.c b/gcc/testsuite/gcc.dg/builtins-70.c new file mode 100644 index 0000000..a0c2dc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtins-70.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2021 Free Software Foundation. + + Check that constant folding of built-in fmod functions doesn't + break anything and produces the expected results. + +/* { dg-do link } */ +/* { dg-options "-O2 -ffast-math" } */ + +extern void link_error(void); + +extern double fmod(double,double); +extern float fmodf(float,float); +extern long double fmodl(long double,long double); + +int main() +{ + if (fmod (6.5, 2.3) < 1.8999 || fmod (6.5, 2.3) > 1.9001) + link_error (); + if (fmod (-6.5, 2.3) < -1.9001 || fmod (-6.5, 2.3) > -1.8999) + link_error (); + if (fmod (6.5, -2.3) < 1.8999 || fmod (6.5, -2.3) > 1.9001) + link_error (); + if (fmod (-6.5, -2.3) < -1.9001 || fmod (-6.5, -2.3) > -1.8999) + link_error (); + + if (fmodf (6.5f, 2.3f) < 1.8999f || fmodf (6.5f, 2.3f) > 1.9001f) + link_error (); + if (fmodf (-6.5f, 2.3f) < -1.9001f || fmodf (-6.5f, 2.3f) > -1.8999f) + link_error (); + if (fmodf (6.5f, -2.3f) < 1.8999f || fmodf (6.5f, -2.3f) > 1.9001f) + link_error (); + if (fmodf (-6.5f, -2.3f) < -1.9001f || fmodf (-6.5f, -2.3f) > -1.8999f) + link_error (); + + if (fmodl (6.5l, 2.3l) < 1.8999l || fmod (6.5l, 2.3l) > 1.9001l) + link_error (); + if (fmodl (-6.5l, 2.3l) < -1.9001l || fmod (-6.5l, 2.3l) > -1.8999l) + link_error (); + if (fmodl (6.5l, -2.3l) < 1.8999l || fmod (6.5l, -2.3l) > 1.9001l) + link_error (); + if (fmodl (-6.5l, -2.3l) < -1.9001l || fmod (-6.5l, -2.3l) > -1.8999l) + link_error (); + + return 0; +} + -- cgit v1.1 From cbf6dcaac040b7a572b8287453101489637c626b Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Thu, 10 Jun 2021 12:56:19 +0200 Subject: testsuite: Change gcc.dg/vect/pr56541.c target. My last commit changed the target selector to ! vect_floatint_cvt when it should of course be vect_floatint_cvt. Fix this. gcc/testsuite/ChangeLog: * gcc.dg/vect/pr56541.c: Fix target selector. --- gcc/testsuite/gcc.dg/vect/pr56541.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr56541.c b/gcc/testsuite/gcc.dg/vect/pr56541.c index e1cee6d..fa86142 100644 --- a/gcc/testsuite/gcc.dg/vect/pr56541.c +++ b/gcc/testsuite/gcc.dg/vect/pr56541.c @@ -24,4 +24,4 @@ void foo() } } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect_floatint_cvt } xfail { ! vect_cond_mixed } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_floatint_cvt } xfail { ! vect_cond_mixed } } } } */ -- cgit v1.1 From 336c41dbcb21740f8964021e157bc69ca547059b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 11 Jun 2021 09:33:58 +0200 Subject: middle-end/101009 - fix distance vector recording This fixes recording of distance vectors in case the DDR has just constant equal indexes. In that case we expect distance vectors with zero distances to be recorded which is what was done when any distance was computed for affine indexes. 2021-06-11 Richard Biener PR middle-end/101009 * tree-data-ref.c (build_classic_dist_vector_1): Make sure to set *init_b to true when we encounter a constant equal index pair. (compute_affine_dependence): Also dump the actual DR_REF. * gcc.dg/torture/pr101009.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101009.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101009.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101009.c b/gcc/testsuite/gcc.dg/torture/pr101009.c new file mode 100644 index 0000000..2bbed1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101009.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-tree-sra -fno-tree-pre -ftree-loop-distribution" } */ + +struct a { + unsigned b; + unsigned c; +} e, *f = &e; +int d = 1; +int main() { + for (; d; d--) { + struct a g[] = {{2, 1}, {2, 1}}; + *f = g[1]; + } + if (e.c != 1) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 8bf728aecc4fea46b4490e950b9ae229f90597b0 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 1 Jun 2021 15:13:18 +0200 Subject: Introduce -Wcoverage-invalid-line-number PR gcov-profile/100788 gcc/ChangeLog: * common.opt: Add new option. * coverage.c (coverage_begin_function): Emit warning instead on the internal compiler error. * doc/invoke.texi: Document the option. * toplev.c (process_options): Enable it by default. gcc/testsuite/ChangeLog: * gcc.dg/pr100788.c: New test. --- gcc/testsuite/gcc.dg/pr100788.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100788.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100788.c b/gcc/testsuite/gcc.dg/pr100788.c new file mode 100644 index 0000000..6f510ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100788.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "--coverage -Wno-error=coverage-invalid-line-number" } */ + +void +foo() // { dg-warning "function starts on a higher line number than it ends" } +{ +#line 1 +} + +int main() +{ + foo (); +} -- cgit v1.1 From 4bdcdd8fa8d7659e5a19a930cf2f0332127f8a46 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 11 Jun 2021 12:59:43 +0200 Subject: simplify-rtx: Fix up simplify_logical_relational_operation for vector IOR [PR101008] simplify_relational_operation callees typically return just const0_rtx or const_true_rtx and then simplify_relational_operation attempts to fix that up if the comparison result has vector mode, or floating mode, or punt if it has scalar mode and vector mode operands (it doesn't know how exactly to deal with the scalar masks). But, simplify_logical_relational_operation has a special case, where it attempts to fold (x < y) | (x >= y) etc. and if it determines it is always true, it just returns const_true_rtx, without doing the dances that simplify_relational_operation does. That results in an ICE on the following testcase, where such folding happens during expansion (of debug stmts into DEBUG_INSNs) and we ICE because all of sudden a VOIDmode rtx appears where it expects a vector (V4SImode) rtx. The following patch fixes that by moving the adjustement into a separate helper routine and using it from both simplify_relational_operation and simplify_logical_relational_operation. 2021-06-11 Jakub Jelinek PR rtl-optimization/101008 * simplify-rtx.c (relational_result): New function. (simplify_logical_relational_operation, simplify_relational_operation): Use it. * gcc.dg/pr101008.c: New test. --- gcc/testsuite/gcc.dg/pr101008.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101008.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101008.c b/gcc/testsuite/gcc.dg/pr101008.c new file mode 100644 index 0000000..c06208d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101008.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/101008 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +typedef unsigned __attribute__((__vector_size__(32))) U; +typedef unsigned __attribute__((__vector_size__(16))) V; + +int c, r; + +V v; + +void +foo(void) +{ + U u = __builtin_shufflevector (v, (V)(v != c) | (V)(c == v), + 4, 3, 5, 5, 1, 2, 3, 0); + r = ((union { U a; int b; }) u).b; +} -- cgit v1.1 From b9ec5ebb605936684e95b8dcc12e43ba7d8f2cb4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 11 Jun 2021 13:36:26 +0200 Subject: tree-optimization/101028 - fix endless SLP reassoc discovery This fixes a missing clearing of mismatched lanes from the fatal fail path in SLP reassoc discovery in the most conservative way. 2021-06-11 Richard Biener PR tree-optimization/101028 * tree-vect-slp.c (vect_build_slp_tree_2): When SLP reassoc discovery fails fatally, mark appropriate lanes in matches[] so. * gcc.dg/pr101028.c: New testcase. --- gcc/testsuite/gcc.dg/pr101028.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101028.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101028.c b/gcc/testsuite/gcc.dg/pr101028.c new file mode 100644 index 0000000..501e6af --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101028.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ + +typedef struct { + double x, y; +} PointInfo; + +typedef struct { + PointInfo point; +} PrimitiveInfo; + +int TraceBezier_alpha, TraceBezier_i; +double TraceBezier_weight; +PointInfo *TraceBezier_points; +PrimitiveInfo *TraceBezier_primitive_info; + +void TracePath() { + double *coefficients; + PointInfo point; + long j; + for (; TraceBezier_i; TraceBezier_i++) { + point.x = point.y = TraceBezier_alpha = 1.0; + j = 0; + for (; j < 4; j++) { + point.x += TraceBezier_alpha * coefficients[j] * + TraceBezier_primitive_info->point.x; + point.y += TraceBezier_alpha * TraceBezier_primitive_info->point.y; + TraceBezier_alpha *= TraceBezier_weight; + TraceBezier_primitive_info++; + } + TraceBezier_points[TraceBezier_i] = point; + TraceBezier_weight += 1.0; + } +} -- cgit v1.1 From 9d20ec97475b1102d6ca005ad165056d34615a3d Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 11 Jun 2021 09:30:33 -0400 Subject: analyzer: tweak priority of callstrings in worklist::key_t::cmp While debugging another issue I noticed that the analyzer could fail to merge nodes for control flow in which one path had called a function and another path hadn't: BB / \ / \ fn call no fn call \ / \ / join BB The root cause was that the worklist sort function wasn't prioritizing call strings, and thus it was fully exploring the "no function called" path to the exit BB, and only then exploring the "within the function call" parts of the "funcion called" path. This patch prioritizes call strings when sorting the worklist so that the nodes with deeper call strings are processed before those with shallower call strings, thus allowing such nodes to be merged at the joinpoint. gcc/analyzer/ChangeLog: * engine.cc (worklist::key_t::cmp): Move sort by call_string to before SCC. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c: Update expected number of enodes after the loop. * gcc.dg/analyzer/paths-8.c: New test. Signed-off-by: David Malcolm --- .../gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c | 3 +-- gcc/testsuite/gcc.dg/analyzer/paths-8.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/paths-8.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c index 2b03527..0172c9b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c +++ b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c @@ -69,6 +69,5 @@ void test(int n) free (it); - __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ - // TODO: why 2 enodes here, rather than 1 + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-8.c b/gcc/testsuite/gcc.dg/analyzer/paths-8.c new file mode 100644 index 0000000..b350d4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/paths-8.c @@ -0,0 +1,17 @@ +#include "analyzer-decls.h" + +static void __attribute__((noinline)) +__analyzer_callee_1 (void) +{ + /* empty. */ +} + +void +test_1 (int flag) +{ + if (flag) + __analyzer_callee_1 (); + + /* Verify that we merge state, whether or not the call happens. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} -- cgit v1.1 From b8b80b8aa3d9a7abbcb59b651ea5e84c2ea12d0b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 11 Jun 2021 12:06:08 +0200 Subject: tree-optimization/101025 - fix store-motion dependence checking This plugs a hole in store-motion where it fails to perform dependence checking on conditionally executed but not store-motioned refs. 2021-06-11 Richard Biener PR tree-optimization/101025 * tree-ssa-loop-im.c (sm_seq_valid_bb): Make sure to process all refs that require dependence checking. * gcc.dg/torture/pr101025.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101025.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101025.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101025.c b/gcc/testsuite/gcc.dg/torture/pr101025.c new file mode 100644 index 0000000..483e0ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101025.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ + +int a[10]; +int b, d, g; +volatile char c; +short e; +volatile int f; +int main() +{ + for (; d <= 9; d++) { + b = e = 0; + for (; e < 4; e++) + a[e] = 4; + for (; b <= 3; b++) + if (g) + f = 0; + else + a[b] = c; + } + if (a[1] != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 5b02ed4b87685c0f7c5da9b46cde3ce56fcfd457 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 11 Jun 2021 17:15:38 +0100 Subject: [PATCH] PR tree-optimization/96392 Optimize x+0.0 if x is an integer The patch implements a missed optimization enhancement. Under usual IEEE rules, x+0.0 can't be simplified to x when x might potentially be an IEEE minus zero (-0.0). The current logic in the middle-end checks whether the type of x should honor signed zeros, but with this patch we introduce tree_expr_maybe_real_minus_zero_p that allows us to confirm that the value can't possibly be -0.0, for example, the result of a conversion from an integer type, or the result of fabs (or has a type that doesn't honor signed zero). Whilst modifying match.pd, I also converted some additional folding transformations from "testing the type" to "testing the value". 2020-06-10 Roger Sayle gcc/ChangeLog PR tree-optimization/96392 * fold-const.c (fold_real_zero_addition_p): Take both arguments of the addition or subtraction, not just the zero. Use this other argument in tests for signaling NaNs and signed zeros. (tree_expr_maybe_real_minus_zero_p): New predicate. * fold-const.h (fold_real_zero_addition_p): Update prototype. (tree_expr_maybe_real_minus_zero_p): New function prototype. * match.pd: Update calls to fold_real_zero_addition_p. Replace HONOR_NANS with tree_expr_maybe_nan_p. Replace HONOR_SIGNED_ZEROS with tree_expr_maybe_real_minus_zero_p. Replace HONOR_SNANS with tree_expr_maybe_signaling_nan_p. * tree-ssa-reassoc.c (eliminate_using_constants): Update call to fold_real_zero_addition_p. gcc/testsuite/ChangeLog PR tree-optimization/96392 * gcc.dg/pr96392.c: New test. --- gcc/testsuite/gcc.dg/pr96392.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr96392.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr96392.c b/gcc/testsuite/gcc.dg/pr96392.c new file mode 100644 index 0000000..662bacb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr96392.c @@ -0,0 +1,33 @@ +/* PR tree-optimization/96392 */ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +double plus0(int x) +{ + return x + 0.0; +} + +double sub0(int x) +{ + return x - 0.0; +} + +double mult0(int x) +{ + return 0.0 * x; +} + +double negate(int x) +{ + return 0.0 - x; +} + +double subtract(int x) +{ + return (double)x - (double)x; +} + +/* { dg-final { scan-tree-dump-not " \\+ " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\- " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */ + -- cgit v1.1 From 2973090c4c62105cbb61bfc6f83be903e3c46c71 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Fri, 11 Jun 2021 15:37:33 +0200 Subject: For 'OMP_CLAUSE' in 'dump_generic_node', dump the whole OMP clause chain ... instead of just the first clause. gcc/ * tree-pretty-print.h (dump_omp_clauses): Add 'bool = true' default argument. * tree-pretty-print.c (dump_omp_clauses): Update. (dump_generic_node) : Use it. gcc/testsuite/ * gcc.dg/gomp/simd-clones-2.c: Enhance. --- gcc/testsuite/gcc.dg/gomp/simd-clones-2.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c index 75554de..9f7c84d 100644 --- a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c +++ b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c @@ -7,6 +7,7 @@ int addit(int a, int b, int *c) return a + b; } /* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64*-*-* } .-4 } */ +/* { dg-final { scan-tree-dump {(?n)^__attribute__\(\(omp declare simd \(notinbranch aligned\(2:32\)\), omp declare simd \(inbranch uniform\(2\) linear\(1:66\)\)\)\)$} "optimized" } } */ #pragma omp declare simd uniform(a) aligned(a:32) linear(k:1) notinbranch float setArray(float *a, float x, int k) @@ -14,6 +15,7 @@ float setArray(float *a, float x, int k) a[k] = a[k] + x; return a[k]; } +/* { dg-final { scan-tree-dump {(?n)^__attribute__\(\(omp declare simd \(notinbranch uniform\(0\) aligned\(0:32\) linear\(2:1\)\)\)\)$} "optimized" } } */ /* { dg-final { scan-tree-dump "_ZGVbN4ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */ /* { dg-final { scan-tree-dump "_ZGVbN4vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */ -- cgit v1.1 From d64584d2fbe79b34e7176681a9d9f85851628ce8 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Thu, 10 Jun 2021 20:12:08 -0400 Subject: testsuite: fix AIX testsuite failures * g++.dg/ext/builtin-shufflevector-2.C: Ignore psabi warning. * gcc.dg/uninit-pr93100.c: Skip on AIX. * gcc.target/powerpc/pr100085.c: Require int128 and float128. --- gcc/testsuite/gcc.dg/uninit-pr93100.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr93100.c b/gcc/testsuite/gcc.dg/uninit-pr93100.c index 61b7e43..531a5c3 100644 --- a/gcc/testsuite/gcc.dg/uninit-pr93100.c +++ b/gcc/testsuite/gcc.dg/uninit-pr93100.c @@ -1,6 +1,7 @@ /* PR tree-optimization/93100 - gcc -fsanitize=address inhibits -Wuninitialized { dg-do compile } - { dg-options "-Wall -fsanitize=address" } */ + { dg-options "-Wall -fsanitize=address" } + { dg-skip-if "sanitize address" { "powerpc-ibm-aix*" } } */ struct A { -- cgit v1.1 From 291cd193f8ddb4e136ebc8f1178d35fa575b3c5d Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sun, 13 Jun 2021 11:34:38 -0400 Subject: c: adjust [[maybe_unused]] testcase Another testcase update needed for my r12-1405 commit. gcc/testsuite/ChangeLog: * gcc.dg/c2x-attr-maybe_unused-1.c: Expect no warnings. --- gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c index 221ebdd..477f30d 100644 --- a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c +++ b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c @@ -20,7 +20,7 @@ g ([[maybe_unused]] int x, int y) struct [[maybe_unused]] s { double d; }; -struct s2 { [[__maybe_unused__]] int a; int b [[maybe_unused]]; } x; /* { dg-warning "attribute ignored" } */ +struct s2 { [[__maybe_unused__]] int a; int b [[maybe_unused]]; } x; enum e { E1 [[maybe_unused]] }; @@ -28,4 +28,4 @@ union [[maybe_unused]] u { int x; }; enum [[maybe_unused]] eu { E2 }; -union u2 { [[maybe_unused]] int a; int b [[maybe_unused]]; } y; /* { dg-warning "attribute ignored" } */ +union u2 { [[maybe_unused]] int a; int b [[maybe_unused]]; } y; -- cgit v1.1 From 08ce1f4c5091b80b680d15c53a17237544a3cca8 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 14 Jun 2021 09:37:24 +0200 Subject: tree-optimization/101031 - fix strlen opt invalidation logic strlen opt uses ao_ref_init_from_ptr_and_size to prepare alias queries to invalidate its knowledge about strings. It constrains the size using the number of known-nonzero chars and adds one for a terminating nul - without knowing whether such nul exists or even fits the object. The latter is now a problem since the oracle disambiguates an access of size two (as built so) against a store to a plain char variable (where a terminating nul does not fit). The fix is to instead increment max_size but leave size to the number of chars we know are accessed. 2021-06-14 Richard Biener PR tree-optimization/101031 * tree-ssa-strlen.c (maybe_invalidate): Increment max_size instead of size when accounting for a possibly string terminating nul. * gcc.dg/torture/pr101031.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101031.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101031.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101031.c b/gcc/testsuite/gcc.dg/torture/pr101031.c new file mode 100644 index 0000000..daf3bcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101031.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +int a; +char b, e; +static char *c = &b; +static long d; +void f(void); +void __attribute__((noipa)) h() { + int g = 0; + for (; g < 2; ++g) { + d = *c; + *c = 1; + b = 0; + } + f(); +} +void __attribute__((noipa)) f() { + if (d++) + c = &e; + for (; a;) + ; +} +int main() { + h(); + if (b != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 831589c227cf1a53cb08490edbafb612d0a9db7c Mon Sep 17 00:00:00 2001 From: Aaron Sawdey Date: Fri, 11 Jun 2021 13:49:18 -0500 Subject: Do not check if SMS succeeds on powerpc These tests have become unstable and SMS either succeeds or doesn't depending on things like changes in instruction latency. Removing the scan-rtl-dump-times checks for powerpc*-*-*. gcc/testsuite * gcc.dg/sms-1.c: Remove scan-rtl-dump-times check. * gcc.dg/sms-2.c: Remove scan-rtl-dump-times check. * gcc.dg/sms-3.c: Remove scan-rtl-dump-times check. * gcc.dg/sms-4.c: Remove scan-rtl-dump-times check. * gcc.dg/sms-6.c: Remove scan-rtl-dump-times check. * gcc.dg/sms-8.c: Remove scan-rtl-dump-times check. * gcc.dg/sms-10.c: Remove scan-rtl-dump-times check. --- gcc/testsuite/gcc.dg/sms-1.c | 2 -- gcc/testsuite/gcc.dg/sms-10.c | 3 --- gcc/testsuite/gcc.dg/sms-2.c | 2 -- gcc/testsuite/gcc.dg/sms-3.c | 3 --- gcc/testsuite/gcc.dg/sms-4.c | 3 --- gcc/testsuite/gcc.dg/sms-6.c | 2 -- gcc/testsuite/gcc.dg/sms-8.c | 4 ---- 7 files changed, 19 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sms-1.c b/gcc/testsuite/gcc.dg/sms-1.c index 26868c3..098e1aa 100644 --- a/gcc/testsuite/gcc.dg/sms-1.c +++ b/gcc/testsuite/gcc.dg/sms-1.c @@ -40,5 +40,3 @@ main () return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ - diff --git a/gcc/testsuite/gcc.dg/sms-10.c b/gcc/testsuite/gcc.dg/sms-10.c index d85e8e2..df3bba2 100644 --- a/gcc/testsuite/gcc.dg/sms-10.c +++ b/gcc/testsuite/gcc.dg/sms-10.c @@ -113,6 +113,3 @@ main () return 0; } - -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ - diff --git a/gcc/testsuite/gcc.dg/sms-2.c b/gcc/testsuite/gcc.dg/sms-2.c index 7b96f55..f8375f9 100644 --- a/gcc/testsuite/gcc.dg/sms-2.c +++ b/gcc/testsuite/gcc.dg/sms-2.c @@ -31,5 +31,3 @@ fun (nb) sy = 0; } } - -/* { dg-final { scan-rtl-dump-times "SMS loop many exits" 1 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-3.c b/gcc/testsuite/gcc.dg/sms-3.c index 822b516..5e56ecf 100644 --- a/gcc/testsuite/gcc.dg/sms-3.c +++ b/gcc/testsuite/gcc.dg/sms-3.c @@ -38,6 +38,3 @@ main () foo (6, 3); return 0; } - -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ - diff --git a/gcc/testsuite/gcc.dg/sms-4.c b/gcc/testsuite/gcc.dg/sms-4.c index f5ebb55..8416b8b 100644 --- a/gcc/testsuite/gcc.dg/sms-4.c +++ b/gcc/testsuite/gcc.dg/sms-4.c @@ -34,6 +34,3 @@ main () foo (5, a, b, c, dst); return 0; } - -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ - diff --git a/gcc/testsuite/gcc.dg/sms-6.c b/gcc/testsuite/gcc.dg/sms-6.c index e57e015..d6fa45a 100644 --- a/gcc/testsuite/gcc.dg/sms-6.c +++ b/gcc/testsuite/gcc.dg/sms-6.c @@ -41,5 +41,3 @@ int main() return 0; } - -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 3 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-8.c b/gcc/testsuite/gcc.dg/sms-8.c index 7ccaa45..dc0a3fc 100644 --- a/gcc/testsuite/gcc.dg/sms-8.c +++ b/gcc/testsuite/gcc.dg/sms-8.c @@ -34,7 +34,3 @@ main () res = foo (3, 4); return 0; } - -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ - - -- cgit v1.1 From 788bb7edb3975b80c4cb16323e7a5e55a2471e46 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 14 Jun 2021 14:57:26 +0200 Subject: tree-optimization/100934 - properly mark irreducible regions for DOM The jump threading code requires marked irreducible regions for the purpose of validating jump threading paths but DOM fails to provide that resulting in mised number of iteration upper bounds clearing. 2021-06-14 Richard Biener PR tree-optimization/100934 * tree-ssa-dom.c (pass_dominator::execute): Properly mark irreducible regions. * gcc.dg/torture/pr100934.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100934.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100934.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100934.c b/gcc/testsuite/gcc.dg/torture/pr100934.c new file mode 100644 index 0000000..43b7884 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100934.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ + +int a, b, c, d, e; +int main() +{ + int f = 0, g = 0; + for (; f < 2; f++) + { + int h, i; + for (h = 0; h < 2; h++) + { + b = e = g ? a % g : 0; + c = d; + for (i = 0; i < 1; i++) + g = 0; + for (; g < 2; g++) + ; + } + } + return 0; +} -- cgit v1.1 From 93bfadf3a1db7d73e9ca4a4a3d40f7f81ea16d39 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 14 Jun 2021 11:38:11 +0100 Subject: c-family: Add fix-it suggestions for more names [PR101052] PR c++/101052 gcc/c-family/ChangeLog: * known-headers.cc (get_stdlib_header_for_name): Add known headers for EXIT_FAILURE, EXIT_SUCCESS, abort, atexit, calloc, exit, and getenv. gcc/testsuite/ChangeLog: * g++.dg/spellcheck-stdlib.C: Add checks for names. * gcc.dg/spellcheck-stdlib.c: Likewise. --- gcc/testsuite/gcc.dg/spellcheck-stdlib.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/spellcheck-stdlib.c b/gcc/testsuite/gcc.dg/spellcheck-stdlib.c index 1ae3b5e..7297a92 100644 --- a/gcc/testsuite/gcc.dg/spellcheck-stdlib.c +++ b/gcc/testsuite/gcc.dg/spellcheck-stdlib.c @@ -38,6 +38,16 @@ void test_stdio_h (void) /* { dg-message "'EOF' is defined in header ''; did you forget to '#include '?" "" { target *-*-* } .-1 } */ } +/* Missing . */ + +void test_stdlib (int i) +{ + i = EXIT_SUCCESS; /* { dg-error "'EXIT_SUCCESS' undeclared" } */ + /* { dg-message "'EXIT_SUCCESS' is defined in header ''; did you forget to '#include '?" "" { target *-*-* } .-1 } */ + i = EXIT_FAILURE; /* { dg-error "'EXIT_FAILURE' undeclared" } */ + /* { dg-message "'EXIT_FAILURE' is defined in header ''; did you forget to '#include '?" "" { target *-*-* } .-1 } */ +} + /* Missing . */ int test_errno_h (void) -- cgit v1.1 From 3fe54645374b1d7992555e97d906a5ba281d3c54 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Tue, 15 Jun 2021 09:06:15 +0200 Subject: testsuite: Fix Wattributes test cases for s390 and add new tests. There are several FAILs because we have an s390-specific check for a warning which is not necessary anymore. Remove it. Add a new test case that expects a warning about conflicting function alignment. This would fail on s390 before but most likely on other targets as well so it can be a target-independent test. Also, add a test to verify that we do not emit a note when specifying conflicting alignment for the same declaration. Need to explicitly handle every dg-note because handling one disables dg-note pruning. gcc/testsuite/ChangeLog: * c-c++-common/Wattributes.c: Remove s390-specific check and add new tests. * gcc.dg/Wattributes-6.c: Likewise. --- gcc/testsuite/gcc.dg/Wattributes-6.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wattributes-6.c b/gcc/testsuite/gcc.dg/Wattributes-6.c index 4ba59bf..978f3f9 100644 --- a/gcc/testsuite/gcc.dg/Wattributes-6.c +++ b/gcc/testsuite/gcc.dg/Wattributes-6.c @@ -97,6 +97,8 @@ fnoinline1 (void); /* { dg-message "previous declaration here" } */ /* Verify a warning for always_inline conflict. */ void ATTR ((always_inline)) fnoinline1 (void) { } /* { dg-warning "ignoring attribute .always_inline. because it conflicts with attribute .noinline." } */ + /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ + /* { dg-note "previous definition" "" { target *-*-* } .-2 } */ /* Verify a warning for gnu_inline conflict. */ inline void ATTR ((gnu_inline)) @@ -364,13 +366,15 @@ inline int ATTR ((cold)) finline_cold_noreturn (int); inline int ATTR ((noreturn)) -finline_cold_noreturn (int); +finline_cold_noreturn (int); /* { dg-note "previous declaration here" } */ inline int ATTR ((noinline)) finline_cold_noreturn (int); /* { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } */ + /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ inline int ATTR ((hot)) finline_cold_noreturn (int); /* { dg-warning "ignoring attribute .hot. because it conflicts with attribute .cold." } */ + /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ inline int ATTR ((warn_unused_result)) finline_cold_noreturn (int); /* { dg-warning "ignoring attribute .warn_unused_result. because it conflicts with attribute .noreturn." } */ @@ -389,23 +393,25 @@ finline_cold_noreturn (int i) { (void)&i; __builtin_abort (); } and some on distinct declarations. */ inline int ATTR ((always_inline, hot)) -finline_hot_noret_align (int); +finline_hot_noret_align (int); /* { dg-note "previous declaration here" } */ inline int ATTR ((noreturn, noinline)) finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } */ + /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ inline int ATTR ((cold, aligned (8))) finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .cold. because it conflicts with attribute .hot." } */ + /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ inline int ATTR ((warn_unused_result)) finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .warn_unused_result. because it conflicts with attribute .noreturn." } */ + /* { dg-note "previous declaration here" "" { target *-*-* } .-1 } */ inline int ATTR ((aligned (4))) - finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(8\\)." "" { target { ! { hppa*64*-*-* s390*-*-* } } } } */ -/* { dg-error "alignment for 'finline_hot_noret_align' must be at least 8" "" { target s390*-*-* } .-1 } */ + finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(8\\)." "" { target { ! { hppa*64*-*-* } } } } */ inline int ATTR ((aligned (8))) -finline_hot_noret_align (int); +finline_hot_noret_align (int); /* { dg-note "previous declaration here" } */ inline int ATTR ((const)) finline_hot_noret_align (int); /* { dg-warning "ignoring attribute .const. because it conflicts with attribute .noreturn." } */ @@ -416,6 +422,26 @@ inline int ATTR ((noreturn)) finline_hot_noret_align (int i) { (void)&i; __builtin_abort (); } +/* Expect a warning about conflicting alignment but without + other declarations inbetween. */ +inline int ATTR ((aligned (32))) +finline_align (int); /* { dg-note "previous declaration here" } */ + +inline int ATTR ((aligned (4))) +finline_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(32\\)." "" } */ + +inline int ATTR ((noreturn)) +finline_align (int i) { (void)&i; __builtin_abort (); } + + +/* Expect no note that would refer to the same declaration. */ +inline int ATTR ((aligned (32), aligned (4))) +finline_double_align (int); /* { dg-warning "ignoring attribute .aligned \\(4\\). because it conflicts with attribute .aligned \\(32\\)." } */ + +inline int ATTR ((noreturn)) +finline_double_align (int i) { (void)&i; __builtin_abort (); } + + /* Exercise variable attributes. */ extern int ATTR ((common)) -- cgit v1.1 From 954c9235297f2e63acacefd448bc5dabe039ea7c Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 15 Jun 2021 09:29:23 -0400 Subject: analyzer testsuite: add explode-2a.c [PR101068] Due to a bug (PR analyzer/101068), the analyzer only explores a limited subset of the possible paths through gcc.dg/analyzer/explode-2.c, and this artifically helps stop this testcase from exploding. I intend to fix this at some point, but for now, this patch adds a revised test case which captures the effective CFG due to the bug, so that we explicitly have test coverage for that CFG. gcc/testsuite/ChangeLog: PR analyzer/101068 * gcc.dg/analyzer/explode-2a.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/explode-2a.c | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/explode-2a.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2a.c b/gcc/testsuite/gcc.dg/analyzer/explode-2a.c new file mode 100644 index 0000000..126407f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/explode-2a.c @@ -0,0 +1,51 @@ +/* PR analyzer/101068. */ + +/* { dg-additional-options "--param analyzer-max-enodes-per-program-point=200 --param analyzer-bb-explosion-factor=50" } */ + +#include + +extern int get (void); + +void test (void) +{ + void *p0, *p1, *p2, *p3; + /* Due to not purging constraints on SSA names within loops + (PR analyzer/101068), the analyzer effectively treats the original + explode-2.c as this code. */ + int a = get (); + int b = get (); + while (a) + { + switch (b) + { + default: + case 0: + p0 = malloc (16); /* { dg-warning "leak" } */ + break; + case 1: + free (p0); /* { dg-warning "double-'free' of 'p0'" "" { xfail *-*-* } } */ + break; + + case 2: + p1 = malloc (16); /* { dg-warning "leak" } */ + break; + case 3: + free (p1); /* { dg-warning "double-'free' of 'p1'" "" { xfail *-*-* } } */ + break; + + case 4: + p2 = malloc (16); /* { dg-warning "leak" } */ + break; + case 5: + free (p2); /* { dg-warning "double-'free' of 'p2'" "" { xfail *-*-* } } */ + break; + + case 6: + p3 = malloc (16); /* { dg-warning "leak" } */ + break; + case 7: + free (p3); /* { dg-warning "double-'free' of 'p3'" "" { xfail *-*-* } } */ + break; + } + } +} -- cgit v1.1 From 9a2c9579fdbf5d24dfe27fb961286ad7a9c3a98b Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 15 Jun 2021 09:31:26 -0400 Subject: analyzer: track dynamic extents of regions This patch extends region_model to add tracking of the sizes of dynamically-allocated regions, both on the heap (via malloc etc) and stack (via alloca). It adds enough purging of this state to avoid blowing up any existing analyzer test cases. The state can be queried via a new "__analyzer_dump_capacity" for use in DejaGnu tests but other than that doesn't do anything - I have various followup experiments that make use of this. gcc/analyzer/ChangeLog: * engine.cc (exploded_node::on_stmt): Handle __analyzer_dump_capacity. (exploded_node::on_stmt): Drop m_sm_changes from on_stmt_flags. (state_change_requires_new_enode_p): New function... (exploded_graph::process_node): Call it, rather than querying flags.m_sm_changes, so that dynamic-extent differences can also trigger the splitting of nodes. * exploded-graph.h (struct on_stmt_flags): Drop field m_sm_changes. * program-state.cc (program_state::detect_leaks): Purge dead heap-allocated regions from dynamic extents. (selftest::test_program_state_1): Fix type of "size_in_bytes". (selftest::test_program_state_merging): Likewise. * region-model-impl-calls.cc (region_model::impl_call_analyzer_dump_capacity): New. (region_model::impl_call_free): Remove dynamic extents from the freed region. * region-model-reachability.h (reachable_regions::begin_mutable_base_regs): New. (reachable_regions::end_mutable_base_regs): New. * region-model.cc: Include "tree-object-size.h". (region_model::region_model): Support new field m_dynamic_extents. (region_model::operator=): Likewise. (region_model::operator==): Likewise. (region_model::dump_to_pp): Dump sizes of dynamic regions. (region_model::handle_unrecognized_call): Purge dynamic extents from any regions that have escaped mutably:. (region_model::get_capacity): New function. (region_model::add_constraint): Unset dynamic extents when a heap-allocated region's address is NULL. (region_model::unbind_region_and_descendents): Purge dynamic extents of unbound regions. (region_model::can_merge_with_p): Call m_dynamic_extents.can_merge_with_p. (region_model::create_region_for_heap_alloc): Assert that size_in_bytes's type is compatible with size_type_node. Update for renaming of record_dynamic_extents to set_dynamic_extents. (region_model::create_region_for_alloca): Likewise. (region_model::record_dynamic_extents): Rename to... (region_model::set_dynamic_extents): ...this. Assert that size_in_bytes's type is compatible with size_type_node. Add it to the m_dynamic_extents map. (region_model::get_dynamic_extents): New. (region_model::unset_dynamic_extents): New. (selftest::test_state_merging): Fix type of "size". (selftest::test_malloc_constraints): Likewise. (selftest::test_malloc): Verify dynamic extents. (selftest::test_alloca): Likewise. * region-model.h (region_to_value_map::is_empty): New. (region_model::dynamic_extents_t): New typedef. (region_model::impl_call_analyzer_dump_capacity): New decl. (region_model::get_dynamic_extents): New function. (region_model::get_dynamic_extents): New decl. (region_model::set_dynamic_extents): New decl. (region_model::unset_dynamic_extents): New decl. (region_model::get_capacity): New decl. (region_model::record_dynamic_extents): Rename to set_dynamic_extents. (region_model::m_dynamic_extents): New field. gcc/ChangeLog: * doc/analyzer.texi (Special Functions for Debugging the Analyzer): Add __analyzer_dump_capacity. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/analyzer-decls.h (__analyzer_dump_capacity): New decl. * gcc.dg/analyzer/capacity-1.c: New test. * gcc.dg/analyzer/capacity-2.c: New test. * gcc.dg/analyzer/capacity-3.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h | 3 + gcc/testsuite/gcc.dg/analyzer/capacity-1.c | 106 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/capacity-2.c | 53 +++++++++++++ gcc/testsuite/gcc.dg/analyzer/capacity-3.c | 82 +++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/capacity-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/capacity-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/capacity-3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h index d96b3f2..2446693 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h +++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h @@ -15,6 +15,9 @@ extern void __analyzer_describe (int verbosity, ...); /* Dump copious information about the analyzer’s state when reached. */ extern void __analyzer_dump (void); +/* Emit a warning describing the size of the base region of (*ptr). */ +extern void __analyzer_dump_capacity (const void *ptr); + /* Dump information after analysis on all of the exploded nodes at this program point. diff --git a/gcc/testsuite/gcc.dg/analyzer/capacity-1.c b/gcc/testsuite/gcc.dg/analyzer/capacity-1.c new file mode 100644 index 0000000..9ea41f7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/capacity-1.c @@ -0,0 +1,106 @@ +#include +#include "analyzer-decls.h" + +typedef unsigned __INT32_TYPE__ u32; + +void +test_1 (void) +{ + char buf[16]; + __analyzer_dump_capacity (buf); /* { dg-warning "capacity: '\\(sizetype\\)16'" } */ +} + +void +test_2 (void) +{ + char ch; + __analyzer_dump_capacity (&ch); /* { dg-warning "capacity: '\\(sizetype\\)1'" } */ +} + +struct s3 { char buf[100]; }; + +void +test_3 (void) +{ + struct s3 s; + __analyzer_dump_capacity (&s); /* { dg-warning "capacity: '\\(sizetype\\)100'" } */ +} + +/* Capacity refers to the base region, not any offset within it. */ + +void +test_4 (void) +{ + char buf[1024]; + __analyzer_dump_capacity (buf + 100); /* { dg-warning "capacity: '\\(sizetype\\)1024'" } */ +} + +void +test_5 (void *p) +{ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ +} + +void +test_malloc (void) +{ + void *p = malloc (1024); + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)1024'" } */ + free (p); +} + +void +test_alloca (size_t sz) +{ + void *p = alloca (sz); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz_\[^\n\r\]*\\)'" } */ +} + +void +test_vla (size_t sz) +{ + char buf[sz]; + __analyzer_dump_capacity (buf); /* { dg-warning "capacity: 'INIT_VAL\\(sz_\[^\n\r\]*\\)'" } */ +} + +static void * __attribute__((noinline)) +called_by_test_interproc_malloc (size_t a) +{ + return malloc (a); +} + +void * +test_interproc_malloc (size_t sz) +{ + void *p = called_by_test_interproc_malloc (sz); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz_\[^\n\r\]*\\)'" } */ + return p; +} + +struct s +{ + u32 f1; + char arr[]; +}; + +static struct s * __attribute__((noinline)) +alloc_s (size_t num) +{ + struct s *p = malloc (sizeof(struct s) + num); + return p; +} + +struct s * +test_trailing_array (void) +{ + struct s *p = alloc_s (5); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)9'" } */ + return p; +} + +void +test_unknown_arr (int p[]) +{ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/capacity-2.c b/gcc/testsuite/gcc.dg/analyzer/capacity-2.c new file mode 100644 index 0000000..9f92bcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/capacity-2.c @@ -0,0 +1,53 @@ +#include +#include "analyzer-decls.h" + +extern void might_realloc (void *); +extern void cant_realloc (const void *); + +void * +test_realloc_1 (void *p, size_t new_sz) +{ + void *q = realloc (p, new_sz); + __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + return q; +} + +void * +test_realloc_2 (size_t sz_a, size_t sz_b) +{ + void *p = malloc (sz_a); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz_a_\[^\n\r\]*\\)'" } */ + void *q = realloc (p, sz_b); + __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + return p; +} + +void * +test_might_realloc (void) +{ + void *p = malloc (1024); + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)1024'" } */ + + might_realloc (p); + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + + return p; +} + +void * +test_cant_realloc (void) +{ + void *p = malloc (1024); + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)1024'" } */ + + cant_realloc (p); + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)1024'" } */ + + return p; +} + + diff --git a/gcc/testsuite/gcc.dg/analyzer/capacity-3.c b/gcc/testsuite/gcc.dg/analyzer/capacity-3.c new file mode 100644 index 0000000..41e282c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/capacity-3.c @@ -0,0 +1,82 @@ +#include +#include "analyzer-decls.h" + +static void __attribute__((noinline)) +__analyzer_callee_1 (size_t inner_sz) +{ + void *p = alloca (inner_sz); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(outer_sz_\[^\n\r\]*\\)'" } */ +} + +void +test_1 (int flag, size_t outer_sz) +{ + if (flag) + __analyzer_callee_1 (outer_sz); + + /* Verify that we merge state; in particular, the dynamic size of "p" + in the called frame should have been purged. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} + +void +test_2 (int flag, size_t sz) +{ + if (flag) + { + void *p = malloc (sz); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz_\[^\n\r\]*\\)'" } */ + free (p); + /* The dynamic size of "p" should have been purged. */ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + } + + /* Verify that we merge state. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} +/* Verify that we purge state on the NULL branch when a malloc result is + tested against NULL. */ + +void +test_3 (size_t sz) +{ + void *p = malloc (sz); + + if (p) + { + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz_\[^\n\r\]*\\)'" } */ + } + else + { + /* The dynamic size of "p" should have been purged + due to "p" being equal to NULL. */ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + } + + free (p); + + /* The dynamic size of "p" should have been purged. */ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + + /* Verify that we merge state. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} + +/* Verify that we purge dynamic extent of a pointer when it leaks. */ + +static void __attribute__((noinline)) +__analyzer_callee_4 (size_t inner_sz) +{ + void *p = malloc (inner_sz); + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(outer_sz_\[^\n\r\]*\\)'" } */ +} /* { dg-warning "leak of 'p'" } */ + +void +test_4 (int flag, size_t outer_sz) +{ + if (flag) + __analyzer_callee_4 (outer_sz); + + /* Verify that we merge state. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} -- cgit v1.1 From 4e56b1347687a33efa47d13d357ae3b7ab759c99 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 16 Jun 2021 08:56:21 +0200 Subject: tree-optimization/101083 - fix ICE with SLP reassoc This makes us pass down the vector type for the two-operand SLP node build rather than picking that from operand one which, when constant or external, could be NULL. 2021-06-16 Richard Biener PR tree-optimization/101083 * tree-vect-slp.c (vect_slp_build_two_operator_nodes): Get vectype as argument. (vect_build_slp_tree_2): Adjust. * gcc.dg/vect/pr97832-4.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr97832-4.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr97832-4.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr97832-4.c b/gcc/testsuite/gcc.dg/vect/pr97832-4.c new file mode 100644 index 0000000..74ae27f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr97832-4.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast" } */ +/* { dg-require-effective-target vect_double } */ + +void foo1x1(double* restrict y, const double* restrict x, int clen) +{ + int xi = clen & 2; + double f_re = x[0+xi+0]; + double f_im = x[4+xi+0]; + int clen2 = (clen+xi) * 2; +#pragma GCC unroll 0 + for (int c = 0; c < clen2; c += 8) { +#pragma GCC unroll 4 + for (int k = 0; k < 4; ++k) { + double x_re = x[k]; + double x_im = x[c+4+k]; + double y_re = y[c+0+k]; + double y_im = y[c+4+k]; + y_re = y_re - x_re * f_re - x_im * f_im;; + y_im = y_im + x_re * f_im - x_im * f_re; + y[c+0+k] = y_re; + y[c+4+k] = y_im; + } + } +} + +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */ -- cgit v1.1 From 43fc4234ad3d9302d3460385b6fdb5e3f59b6986 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 16 Jun 2021 09:49:18 +0200 Subject: tree-optimization/101088 - fix SM invalidation issue When we face a sm_ord vs sm_unord for the same ref during store sequence merging we assert that the ref is already marked unsupported. But it can be that it will only be marked so during the ongoing merging so instead of asserting mark it here. Also apply some optimization to not waste resources to search for already unsupported refs. 2021-06-16 Richard Biener PR tree-optimization/101088 * tree-ssa-loop-im.c (sm_seq_valid_bb): Only look for supported refs on edges. Do not assert same ref but different kind stores are unsuported but mark them so. (hoist_memory_references): Only look for supported refs on exits. * gcc.dg/torture/pr101088.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101088.c | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101088.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101088.c b/gcc/testsuite/gcc.dg/torture/pr101088.c new file mode 100644 index 0000000..00fce39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101088.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ + +int bh, on, h0; + +void +qw (int n2) +{ + int *e5; + + if (n2 == 0) + { + n2 = 1; + while (n2 != 0) + for (n2 = 0; n2 < 1; ++n2) + { + } + + e5 = &n2; + } + else + e5 = &on; + + while (h0 < 1) + { + if (on == 0) + { + ++*e5; + bh = 0; + } + else + { + bh = 0; + ++on; + *e5 = on; + h0 = *e5; + if (h0 == 0) + { + *e5 = 0; + ++h0; + } + } + + ++h0; + } +} -- cgit v1.1 From b4b50bf2864e09f028a39a3f460222632c4d7348 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 16 Jun 2021 12:17:55 +0200 Subject: stor-layout: Create DECL_BIT_FIELD_REPRESENTATIVE even for bitfields in unions [PR101062] The following testcase is miscompiled on x86_64-linux, the bitfield store is implemented as a RMW 64-bit operation at d+24 when the d variable has size of only 28 bytes and scheduling moves in between the R and W part a store to a different variable that happens to be right after the d variable. The reason for this is that we weren't creating DECL_BIT_FIELD_REPRESENTATIVEs for bitfields in unions. The following patch does create them, but treats all such bitfields as if they were in a structure where the particular bitfield is the only field. 2021-06-16 Jakub Jelinek PR middle-end/101062 * stor-layout.c (finish_bitfield_representative): For fields in unions assume nextf is always NULL. (finish_bitfield_layout): Compute bit field representatives also in unions, but handle it as if each bitfield was the only field in the aggregate. * gcc.dg/pr101062.c: New test. --- gcc/testsuite/gcc.dg/pr101062.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101062.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101062.c b/gcc/testsuite/gcc.dg/pr101062.c new file mode 100644 index 0000000..6c37ed8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101062.c @@ -0,0 +1,29 @@ +/* PR middle-end/101062 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-toplevel-reorder -frename-registers" } */ + +union U { signed b : 5; }; +int c; +volatile union U d[7] = { { 8 } }; +short e = 1; + +__attribute__((noipa)) void +foo () +{ + d[6].b = 0; + d[6].b = 0; + d[6].b = 0; + d[6].b = 0; + d[6].b = 0; + e = 0; + c = 0; +} + +int +main () +{ + foo (); + if (e != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From a490b1dc0b3c26bff2ee00ac0da2d606d2009e3a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 16 Jun 2021 13:10:48 +0200 Subject: testsuite: Use noipa attribute instead of noinline, noclone I've noticed this test now on various arches sometimes FAILs, sometimes PASSes (the line 12 test in particular). The problem is that a = 0; initialization in the caller no longer happens before the f(&a) call as what the argument points to is only used in debug info. Making the function noipa forces the caller to initialize it and still tests what the test wants to test, namely that we don't consider *p as valid location for the c variable at line 18 (after it has been overwritten with *p = 1;). 2021-06-16 Jakub Jelinek * gcc.dg/guality/pr49888.c (f): Use noipa attribute instead of noinline, noclone. --- gcc/testsuite/gcc.dg/guality/pr49888.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/guality/pr49888.c b/gcc/testsuite/gcc.dg/guality/pr49888.c index 4f3a250..919cfc9 100644 --- a/gcc/testsuite/gcc.dg/guality/pr49888.c +++ b/gcc/testsuite/gcc.dg/guality/pr49888.c @@ -4,7 +4,7 @@ static int v __attribute__((used)); -static void __attribute__((noinline, noclone)) +static void __attribute__((noipa)) f (int *p) { int c = *p; -- cgit v1.1 From d7deee423f993bee8ee440f6fe0c9126c316c64b Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Wed, 16 Jun 2021 13:18:46 +0200 Subject: tree-sra: Do not refresh readonly decls (PR 100453) When SRA transforms an assignment where the RHS is an aggregate decl that it creates replacements for, the (least efficient) fallback method of dealing with them is to store all the replacements back into the original decl and then let the original assignment takes its course. That of course should not need to be done for TREE_READONLY bases which cannot change contents. The SRA code handled this situation only for DECL_IN_CONSTANT_POOL const decls, this patch modifies the check so that it tests for TREE_READONLY and I also looked at all other callers of generate_subtree_copies and added checks to another one dealing with the same exact situation and one which deals with it in a non-assignment context. gcc/ChangeLog: 2021-06-11 Martin Jambor PR tree-optimization/100453 * tree-sra.c (create_access): Disqualify any const candidates which are written to. (sra_modify_expr): Do not store sub-replacements back to a const base. (handle_unscalarized_data_in_subtree): Likewise. (sra_modify_assign): Likewise. Earlier, use TREE_READONLy test instead of constant_decl_p. gcc/testsuite/ChangeLog: 2021-06-10 Martin Jambor PR tree-optimization/100453 * gcc.dg/tree-ssa/pr100453.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr100453.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr100453.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c new file mode 100644 index 0000000..0cf0ad2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +struct a { + int b : 4; +} d; +static int c, e; +static const struct a f; +static void g(const struct a h) { + for (; c < 1; c++) + d = h; + e = h.b; + c = h.b; +} +int main() { + g(f); + return 0; +} -- cgit v1.1 From 3dfa4fe9f1a089b2b3906c83e22a1b39c49d937c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 8 Jun 2021 15:10:45 +0200 Subject: Vectorization of BB reductions This adds a simple reduction vectorization capability to the non-loop vectorizer. Simple meaning it lacks any of the fancy ways to generate the reduction epilogue but only supports those we can handle via a direct internal function reducing a vector to a scalar. One of the main reasons is to avoid massive refactoring at this point but also that more complex epilogue operations are hardly profitable. Mixed sign reductions are for now fend off and I'm not finally settled with whether we want an explicit SLP node for the reduction epilogue operation. Handling mixed signs could be done by multiplying with a { 1, -1, .. } vector. Fend off are also reductions with non-internal operands (constants or register parameters for example). Costing is done by accounting the original scalar participating stmts for the scalar cost and log2 permutes and operations for the vectorized epilogue. -- SPEC CPU 2017 FP with rate workload measurements show (picked fastest runs of three) regressions for 507.cactuBSSN_r (1.5%), 508.namd_r (2.5%), 511.povray_r (2.5%), 526.blender_r (0.5) and 527.cam4_r (2.5%) and improvements for 510.parest_r (5%) and 538.imagick_r (1.5%). This is with -Ofast -march=znver2 on a Zen2. Statistics on CPU 2017 shows that the overwhelming number of seeds we find are reductions of two lanes (well - that's basically every associative operation). That means we put a quite high pressure on the SLP discovery process this way. In total we find 583218 seeds we put to SLP discovery out of which 66205 pass that and only 6185 of those make it through code generation checks. 796 of those are discarded because the reduction is part of a larger SLP instance. 4195 of the remaining are deemed not profitable to vectorize and 1194 are finally vectorized. That's a poor 0.2% rate. Of the 583218 seeds 486826 (83%) have two lanes, 60912 have three (10%), 28181 four (5%), 4808 five, 909 six and there are instances up to 120 lanes. There's a set of 54086 candidate seeds we reject because they contain a constant or invariant (not implemented yet) but still have two or more lanes that could be put to SLP discovery. 2021-06-16 Richard Biener PR tree-optimization/54400 * tree-vectorizer.h (enum slp_instance_kind): Add slp_inst_kind_bb_reduc. (reduction_fn_for_scalar_code): Declare. * tree-vect-data-refs.c (vect_slp_analyze_instance_dependence): Check SLP_INSTANCE_KIND instead of looking at the representative. (vect_slp_analyze_instance_alignment): Likewise. * tree-vect-loop.c (reduction_fn_for_scalar_code): Export. * tree-vect-slp.c (vect_slp_linearize_chain): Split out chain linearization from vect_build_slp_tree_2 and generalize for the use of BB reduction vectorization. (vect_build_slp_tree_2): Adjust accordingly. (vect_optimize_slp): Elide permutes at the root of BB reduction instances. (vectorizable_bb_reduc_epilogue): New function. (vect_slp_prune_covered_roots): Likewise. (vect_slp_analyze_operations): Use them. (vect_slp_check_for_constructors): Recognize associatable chains for BB reduction vectorization. (vectorize_slp_instance_root_stmt): Generate code for the BB reduction epilogue. * gcc.dg/vect/bb-slp-pr54400.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c new file mode 100644 index 0000000..6b427aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vect_float} */ +/* { dg-additional-options "-w -Wno-psabi -ffast-math" } */ + +#include "tree-vect.h" + +typedef float v4sf __attribute__((vector_size(sizeof(float)*4))); + +float __attribute__((noipa)) +f(v4sf v) +{ + return v[0]+v[1]+v[2]+v[3]; +} + +float __attribute__((noipa)) +g(float *v) +{ + return v[0]+v[1]+v[2]+v[3]; +} + +float __attribute__((noipa)) +h(float *v) +{ + return 2*v[0]+3*v[1]+4*v[2]+5*v[3]; +} + +int +main () +{ + check_vect (); + v4sf v = (v4sf) { 1.f, 3.f, 4.f, 2.f }; + if (f (v) != 10.f) + abort (); + if (g (&v[0]) != 10.f) + abort (); + if (h (&v[0]) != 37.f) + abort (); + return 0; +} + +/* We are lacking an effective target for .REDUC_PLUS support. */ +/* { dg-final { scan-tree-dump-times "basic block part vectorized" 3 "slp2" { target x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-not " = VEC_PERM_EXPR" "slp2" { target x86_64-*-* } } } */ -- cgit v1.1 From f1555d4013ed3cae2589270436387063d1c2f1a3 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 13 May 2021 13:47:41 -0400 Subject: Cleanup clz and ctz code in range_of_builtin_call. These are various cleanups to the clz/ctz code. First, ranges from range_of_expr are always numeric so we should adjust. Also, the checks for non-zero were assuming the argument was unsigned, which in the PR's testcase is clearly not. I've cleaned this up, so that it works either way. I've also removed the following annoying idiom: - int newmini = prec - 1 - wi::floor_log2 (r.upper_bound ()); - if (newmini == prec) This is really a check for r.upper_bound() == 0, as floor_log2(0) returns -1. It's confusing. Tested on x86-64 Linux. gcc/ChangeLog: PR tree-optimization/100790 * gimple-range.cc (range_of_builtin_call): Cleanup clz and ctz code. gcc/testsuite/ChangeLog: * gcc.dg/pr100790.c: New test. --- gcc/testsuite/gcc.dg/pr100790.c | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr100790.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr100790.c b/gcc/testsuite/gcc.dg/pr100790.c new file mode 100644 index 0000000..31e0eff --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100790.c @@ -0,0 +1,4 @@ +// { dg-do compile } +// { dg-options "-O2 -w" } + +__builtin_clz(int x) { x ? __builtin_clz(x) : 32; } -- cgit v1.1 From 3bb85b868722e69aef0d37858c0dc3c88d92a0eb Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 18 Jun 2021 13:24:19 -0400 Subject: analyzer: fix issue with symbolic reads with concrete bindings gcc/analyzer/ChangeLog: * store.cc (binding_cluster::get_any_binding): Make symbolic reads from a cluster with concrete bindings return unknown. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/symbolic-7.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/symbolic-7.c | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/symbolic-7.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c new file mode 100644 index 0000000..4f01367 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c @@ -0,0 +1,44 @@ +#include "analyzer-decls.h" + +extern void maybe_write (int *); + +void test_1 (int i) +{ + /* An array with purely concrete bindings. */ + int arr[2]; + arr[0] = 1066; + arr[1] = 1776; + + /* Concrete reads. */ + __analyzer_eval (arr[0] == 1066); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[1] == 1776); /* { dg-warning "TRUE" } */ + + /* Symbolic read. */ + __analyzer_describe (0, arr[i]); /* { dg-warning "svalue: 'UNKNOWN\\(int\\)'" } */ + __analyzer_eval (arr[i] == 1776); /* { dg-warning "UNKNOWN" } */ +} + +void test_2 (int i) +{ + /* An array that could have been touched. */ + int arr[2]; + maybe_write (arr); + + /* Concrete reads. */ + __analyzer_eval (arr[0] == 42); /* { dg-warning "UNKNOWN" } */ + + /* Symbolic read. */ + __analyzer_eval (arr[i] == 42); /* { dg-warning "UNKNOWN" } */ +} + +void test_3 (int i) +{ + /* An array that can't have been touched. */ + int arr[2]; + + /* Concrete reads. */ + __analyzer_eval (arr[0] == 42); /* { dg-warning "UNKNOWN" } */ + + /* Symbolic read. */ + __analyzer_eval (arr[i] == 42); /* { dg-warning "UNKNOWN" } */ +} -- cgit v1.1 From 644c2cc5f2c09506a7bfef293a7f90efa8d7e5fa Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 21 Jun 2021 13:30:42 +0200 Subject: inline-asm: Fix ICE with bitfields in "m" operands [PR100785] Bitfields, while they live in memory, aren't something inline-asm can easily operate on. For C and "=m" or "+m", we were diagnosing bitfields in the past in the FE, where c_mark_addressable had: case COMPONENT_REF: if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) { error ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); return false; } but that check got moved in GCC 6 to build_unary_op instead and now we emit an error during expansion and ICE afterwards (i.e. error-recovery). For "m" it used to be diagnosed in c_mark_addressable too, but since GCC 6 it is ice-on-invalid. For C++, this was never diagnosed in the FE, but used to be diagnosed in the gimplifier and/or during expansion before 4.8. The following patch does multiple things: 1) diagnoses it in the FEs 2) stops emitting a redundant diagnostic in the gimplifier using the usual way, if we already see error_mark_node, we assume error has been emitted already and only diagnose if it wasn't error_mark_node; this helps diagnosing the same bug with multiple different errors 3) simplifies during expansion the inline asm if any errors have been reported (similarly how e.g. vregs pass if it detects errors on inline-asm either deletes them or simplifies to bare minimum - just labels), so that we don't have error-recovery ICEs there 2021-06-11 Jakub Jelinek PR inline-asm/100785 gcc/ * gimplify.c (gimplify_asm_expr): Don't diagnose errors if output or input operands were already error_mark_node. * cfgexpand.c (expand_asm_stmt): If errors are emitted, remove all inputs, outputs and clobbers from the asm and set template to "". gcc/c/ * c-typeck.c (c_mark_addressable): Diagnose trying to make bit-fields addressable. gcc/cp/ * typeck.c (cxx_mark_addressable): Diagnose trying to make bit-fields addressable. gcc/testsuite/ * c-c++-common/pr100785.c: New test. * gcc.dg/pr48552-1.c: Don't expect invalid lvalue errors. * gcc.dg/pr48552-2.c: Likewise. --- gcc/testsuite/gcc.dg/pr48552-1.c | 4 ++-- gcc/testsuite/gcc.dg/pr48552-2.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr48552-1.c b/gcc/testsuite/gcc.dg/pr48552-1.c index 11ee401..4cd7c59 100644 --- a/gcc/testsuite/gcc.dg/pr48552-1.c +++ b/gcc/testsuite/gcc.dg/pr48552-1.c @@ -15,7 +15,7 @@ f2 (void *x) { __asm volatile ("" : "=r" (*x)); /* { dg-warning "dereferencing" "deref" } */ } /* { dg-error "invalid use of void expression" "void expr" { target *-*-* } .-1 } */ - /* { dg-error "invalid lvalue in 'asm' output 0" "invalid lvalue" { target *-*-* } .-2 } */ + void f3 (void *x) { @@ -39,7 +39,7 @@ f6 (void *x) { __asm volatile ("" : "=g" (*x)); /* { dg-warning "dereferencing" "deref" } */ } /* { dg-error "invalid use of void expression" "void expr" { target *-*-* } .-1 } */ - /* { dg-error "invalid lvalue in 'asm' output 0" "invalid lvalue" { target *-*-* } .-2 } */ + void f7 (struct S *x) { diff --git a/gcc/testsuite/gcc.dg/pr48552-2.c b/gcc/testsuite/gcc.dg/pr48552-2.c index 2d2a00c..e22600a 100644 --- a/gcc/testsuite/gcc.dg/pr48552-2.c +++ b/gcc/testsuite/gcc.dg/pr48552-2.c @@ -15,7 +15,7 @@ f2 (void *x) { __asm ("" : "=r" (*x)); /* { dg-warning "dereferencing" "deref" } */ } /* { dg-error "invalid use of void expression" "void expr" { target *-*-* } .-1 } */ - /* { dg-error "invalid lvalue in 'asm' output 0" "invalid lvalue" { target *-*-* } .-2 } */ + void f3 (void *x) { @@ -39,7 +39,7 @@ f6 (void *x) { __asm ("" : "=g" (*x)); /* { dg-warning "dereferencing" "deref" } */ } /* { dg-error "invalid use of void expression" "void expr" { target *-*-* } .-1 } */ - /* { dg-error "invalid lvalue in 'asm' output 0" "invalid lvalue" { target *-*-* } .-2 } */ + void f7 (struct S *x) { -- cgit v1.1 From a2ef8395fa970498985764514044e5fd00f7d5c0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 22 Jun 2021 10:14:02 +0200 Subject: tree-optimization/101151 - fix irreducible region check for sinking The check whether two blocks are in the same irreducible region and thus post-dominance checks being unreliable was incomplete since an irreducible region can contain reducible sub-regions but if one block is in the irreducible part and one not the check still doesn't work as expected. 2021-06-22 Richard Biener PR tree-optimization/101151 * tree-ssa-sink.c (statement_sink_location): Expand irreducible region check. * gcc.dg/torture/pr101151.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101151.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101151.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101151.c b/gcc/testsuite/gcc.dg/torture/pr101151.c new file mode 100644 index 0000000..15c9a7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101151.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +int a, *b = &a, c, d; +int main() { + *b; + if (a) { + L1: + a = 0; + L2: + if (d) { + while (b) + ; + goto L1; + } + } + if (c) + goto L2; + return 0; +} -- cgit v1.1 From b4e21c80462682c4e6e5e487fe87107b27f8b4bd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 22 Jun 2021 12:13:44 +0200 Subject: middle-end/101156 - remove not working optimization in gimplification This removes a premature and not working optimization from the gimplifier. When gimplification is requested not to produce a SSA name we try to avoid generating a copy when we did so anyway but instead replace the LHS of its definition. But that only works in case there are no uses of the SSA name already which is something we cannot easily check, so the following removes said optimization. Statistics on the whole bootstrap shows we hit this optimization only for libiberty/cp-demangle.c and overall we have 21652112 gimplifications where just 240 copies are elided. Preserving the optimization would require scanning the original expression and the pre and post sequences for SSA names and uses, that seems excessive to avoid these 240 copies. 2021-06-22 Richard Biener PR middle-end/101156 * gimplify.c (gimplify_expr): Remove premature incorrect optimization. * gcc.dg/pr101156.c: New testcase. --- gcc/testsuite/gcc.dg/pr101156.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101156.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101156.c b/gcc/testsuite/gcc.dg/pr101156.c new file mode 100644 index 0000000..5c25bd7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101156.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fchecking" } */ + +struct S { int i; }; +void baz(struct S *p) +{ + __builtin_setjmp(p--); +} -- cgit v1.1 From ea4e32181d7a36055b57421abd0ced4735654cf6 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 22 Jun 2021 13:44:57 -0400 Subject: analyzer: fix ICE on malloc/alloca param type mismatch [PR101143] gcc/analyzer/ChangeLog: PR analyzer/101143 * region-model.cc (compat_types_p): New function. (region_model::create_region_for_heap_alloc): Convert assertion to an error check. (region_model::create_region_for_alloca): Likewise. gcc/testsuite/ChangeLog: PR analyzer/101143 * gcc.dg/analyzer/pr101143.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/pr101143.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101143.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101143.c b/gcc/testsuite/gcc.dg/analyzer/pr101143.c new file mode 100644 index 0000000..bcc0974 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101143.c @@ -0,0 +1,18 @@ +/* { dg-additional-options "-Wno-builtin-declaration-mismatch" } */ + +extern void *malloc (unsigned int); +extern void *alloca (unsigned int); +extern void unknown_fn (void *); + +void * +test_malloc (void) +{ + return malloc (sizeof (int)); +} + +void * +test_alloca (void) +{ + void *p = alloca (sizeof (int)); + unknown_fn (p); +} -- cgit v1.1 From 50374fdacbd121bc4a61b073e559208ff61bee06 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 23 Jun 2021 12:43:03 +0200 Subject: tree-optimization/101105 - fix runtime alias test optimization We were ignoring DR_STEP for VF == 1 which is OK only in case the scalar order is preserved or both DR steps are the same. 2021-06-23 Richard Biener PR tree-optimization/101105 * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list): Only ignore steps when they are equal or scalar order is preserved. * gcc.dg/torture/pr101105.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101105.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101105.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101105.c b/gcc/testsuite/gcc.dg/torture/pr101105.c new file mode 100644 index 0000000..9222351 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101105.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ + +short a; +int b[5][4] = {2, 2}; +int d; +short e(int f) { return f == 0 || a && f == 1 ? 0 : a; } +int main() { + int g, h; + g = 3; + for (; g >= 0; g--) { + h = 3; + for (; h >= 0; h--) + b[g][h] = b[0][1] && e(1); + } + d = b[0][1]; + if (d != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 65371066d8967560e3508af4a804e0ddb90acee7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 24 Jun 2021 12:22:14 +0200 Subject: stor-layout: Avoid DECL_BIT_FIELD_REPRESENTATIVE with NULL TREE_TYPE [PR101172] finish_bitfield_representative has an early out if the field after a bitfield has error_mark_node type, but that early out leads to TREE_TYPE of the DECL_BIT_FIELD_REPRESENTATIVE being NULL, which breaks assumptions on code that uses the DECL_BIT_FIELD_REPRESENTATIVE during error-recovery. The following patch instead sets TREE_TYPE of the representative to error_mark_node, something the users can deal with better. At this point the representative can be set as DECL_BIT_FIELD_REPRESENTATIVE for multiple bitfields, so making sure that we clear the DECL_BIT_FIELD_REPRESENTATIVE instead would be harder (but doable, e.g. with the error_mark_node TREE_TYPE set by this patch set some flag in the caller and if the flag is there, walk all the fields once again and clear all DECL_BIT_FIELD_REPRESENTATIVE that have error_mark_node TREE_TYPE). 2021-06-24 Jakub Jelinek PR middle-end/101172 * stor-layout.c (finish_bitfield_representative): If nextf has error_mark_node type, set repr type to error_mark_node too. * gcc.dg/pr101172.c: New test. --- gcc/testsuite/gcc.dg/pr101172.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101172.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101172.c b/gcc/testsuite/gcc.dg/pr101172.c new file mode 100644 index 0000000..b9d098b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101172.c @@ -0,0 +1,20 @@ +/* PR middle-end/101172 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +union U +{ + int a[3]; + struct + { + int a : 3; + struct this_struct var; /* { dg-error "field 'var' has incomplete type" } */ + } b; +}; + +const union U hello = {.a = {1, 2, 3}}; + +void foo() +{ + int x = hello.b.a; +} -- cgit v1.1 From 9872bd8c35be0f4d475fac739115cf5b82cdabc0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 24 Jun 2021 12:24:48 +0200 Subject: df: Fix up handling of paradoxical subregs in debug insns [PR101170] The recent addition of gcc_assert (regno < endregno); triggers during glibc build on m68k. The problem is that RA decisions shouldn't depend on expressions in DEBUG_INSNs and those expressions can contain paradoxical subregs of certain pseudos. If RA then decides to allocate the pseudo to a register with very small hard register REGNO, we can trigger the new assert, as (int) subreg_regno_offset may be negative on big endian and the small REGNO + the negative offset can wrap around. The following patch in that case records the range from the REGNO 0 to endregno, before the addition of the assert as both regno and endregno are unsigned it wouldn't record anything at all silently. 2021-06-24 Jakub Jelinek PR middle-end/101170 * df-scan.c (df_ref_record): For paradoxical big-endian SUBREGs where regno + subreg_regno_offset wraps around use 0 as starting regno. * gcc.dg/pr101170.c: New test. --- gcc/testsuite/gcc.dg/pr101170.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101170.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101170.c b/gcc/testsuite/gcc.dg/pr101170.c new file mode 100644 index 0000000..fc81062 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101170.c @@ -0,0 +1,37 @@ +/* PR middle-end/101170 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +#include + +struct S { int a; int b[4]; } s; +va_list ap; +int i; +long long l; + +struct S +foo (int x) +{ + struct S a = {}; + do + if (x) + return a; + while (1); +} + +__attribute__((noipa)) void +bar (void) +{ + for (; i; i++) + l |= va_arg (ap, long long) << s.b[i]; + if (l) + foo (l); +} + +void +baz (int v, ...) +{ + va_start (ap, v); + bar (); + va_end (ap); +} -- cgit v1.1 From 836328b2c99f5b8d45dcca5797f162af322e74da Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 24 Jun 2021 15:39:26 +0200 Subject: i386: Add pack/unpack patterns for 64bit vectors [PR89021] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2021-06-24 Uroš Bizjak gcc/ PR target/89021 * config/i386/i386-expand.c (ix86_expand_sse_unpack): Handle V8QI and V4HI modes. * config/i386/mmx.md (sse4_1_v4qiv4hi2): New insn pattern. (sse4_1_v4qiv4hi2): Ditto. (mmxpackmode): New mode attribute. (vec_pack_trunc_): New expander. (mmxunpackmode): New mode attribute. (vec_unpacks_lo_): New expander. (vec_unpacks_hi_): Ditto. (vec_unpacku_lo_): Ditto. (vec_unpacku_hi_): Ditto. * config/i386/i386.md (extsuffix): Move from ... * config/i386/sse.md: ... here. gcc/testsuite/ PR target/89021 * gcc.dg/vect/vect-nb-iter-ub-3.c (dg-additional-options): Add --param vect-epilogues-nomask=0. * gcc.target/i386/pr97249-1.c (foo): Add #pragma GCC unroll to avoid loop vectorization. (foo1): Ditto. (foo2): Ditto. --- gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c b/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c index dbf5091..1666526 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c @@ -1,4 +1,4 @@ -/* { dg-additional-options "-fdump-tree-cunroll-details" } */ +/* { dg-additional-options "-fdump-tree-cunroll-details --param vect-epilogues-nomask=0" } */ #include "tree-vect.h" -- cgit v1.1 From fdc5522fb04b4a820b28c4d1f16f54897f5978de Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 24 Jun 2021 15:55:28 +0200 Subject: c: Fix C cast error-recovery [PR101171] The following testcase ICEs during error-recovery, as build_c_cast calls note_integer_operands on error_mark_node and that wraps it into C_MAYBE_CONST_EXPR which is unexpected and causes ICE later on. Seems most other callers of note_integer_operands check early if something is error_mark_node and return before calling note_integer_operands on it. The following patch fixes it by not calling on error_mark_node, another possibility would be to handle error_mark_node in note_integer_operands and just return it. 2021-06-24 Jakub Jelinek PR c/101171 * c-typeck.c (build_c_cast): Don't call note_integer_operands on error_mark_node. * gcc.dg/pr101171.c: New test. --- gcc/testsuite/gcc.dg/pr101171.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101171.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101171.c b/gcc/testsuite/gcc.dg/pr101171.c new file mode 100644 index 0000000..8d2bcab --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101171.c @@ -0,0 +1,13 @@ +/* PR c/101171 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +extern void foo (void); +int x = 0x1234; + +void +bar (void) +{ + if (x != (sizeof ((enum T) 0x1234))) /* { dg-error "conversion to incomplete type" } */ + foo (); +} -- cgit v1.1 From a0accaa99844b0c40661202635859f8c0be76cdd Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 24 Jun 2021 13:35:21 -0400 Subject: Only register relations on live edges Register a relation on a conditional edge only if the LHS supports this edge being taken. gcc/ PR tree-optimization/101189 * gimple-range-fold.cc (fold_using_range::range_of_range_op): Pass LHS range of condition to postfold routine. (fold_using_range::postfold_gcond_edges): Only process the TRUE or FALSE edge if the LHS range supports it being taken. * gimple-range-fold.h (postfold_gcond_edges): Add range parameter. gcc/testsuite/ * gcc.dg/tree-ssa/pr101189.c: New. --- gcc/testsuite/gcc.dg/tree-ssa/pr101189.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr101189.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c new file mode 100644 index 0000000..5730708 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/101189 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +static int a, b; +int main() { + int d = 0, e, f = 5; + if (a) + f = 0; + for (; f < 4; f++) + ; + e = f ^ -f; + e && d; + if (!e) + e || b; + return 0; +} -- cgit v1.1 From ce3316e9c02c81c509173572c71a101f4eb62a24 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 24 Jun 2021 13:49:51 -0400 Subject: Add a testcase to confirm the equivalence's are being checked by EVRP. * gcc.dg/tree-ssa/evrp30.c: New. --- gcc/testsuite/gcc.dg/tree-ssa/evrp30.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/evrp30.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp30.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp30.c new file mode 100644 index 0000000..2c5ff41 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp30.c @@ -0,0 +1,16 @@ +/* Confirm the ranger is picking up a relationship with equivalences. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void foo (); + +void f (unsigned int a, unsigned int b) +{ + if (a == b) + for (unsigned i = 0; i < a; i++) + if (i == b) // Confirm i < a also means i < b. + foo (); /* Unreachable */ +} + +/* { dg-final { scan-tree-dump-times "foo\\(" 0 "evrp"} } */ + -- cgit v1.1 From 55a1546b73b60d2601f35671ba9e8f12a52a7b77 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 25 Jun 2021 09:20:56 +0200 Subject: tree-optimization/101202 - fix ICE with failed backedge SLP nodes This fixes an ICE with failed backedge SLP nodes still in the graph while doing permute optimization by explicitely handling those. 2021-06-25 Richard Biener PR tree-optimization/101202 * tree-vect-slp.c (vect_optimize_slp): Explicitely handle failed nodes. * gcc.dg/torture/pr101202.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101202.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101202.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101202.c b/gcc/testsuite/gcc.dg/torture/pr101202.c new file mode 100644 index 0000000..e76c908 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101202.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +int printf(const char *, ...); +unsigned a, b, d; +int c, e, f; +int main() +{ + while (a) + if (b) + { + f = a; + while (e) + { + int h, i; + if (d) + { + h = a; + i = d; +L: + d = a | d && c; + if (a) + { + printf("%d", a); + goto L; + } + } + a = h; + d = i; + } + } + return 0; +} -- cgit v1.1 From fd51b344ca86c9673db0161d4a383cccdb2f429c Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 25 Jun 2021 17:01:01 -0600 Subject: PR middle-end/101216 - spurious notes for function calls PR middle-end/101216 gcc/ChangeLog: * calls.c (maybe_warn_rdwr_sizes): Use the no_warning constant. gcc/testsuite/ChangeLog: * gcc.dg/Wnonnull-7.c: New test. --- gcc/testsuite/gcc.dg/Wnonnull-7.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wnonnull-7.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wnonnull-7.c b/gcc/testsuite/gcc.dg/Wnonnull-7.c new file mode 100644 index 0000000..e7b331a --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wnonnull-7.c @@ -0,0 +1,15 @@ +/* PR middle-end/101216 - spurious notes for function calls + { dg-do compile } + { dg-options "-O2 -w" } */ + +__attribute__ ((access (write_only, 1, 2))) char* +getcwd (char *, __SIZE_TYPE__); + +char* f (void) +{ + char a[8]; + return getcwd (0, 8); +} + +/* Expect no messages of any kind on output. + { dg-bogus "" "" { target *-*-* } 0 } */ -- cgit v1.1 From 37ad257c06d88fdb810be336d212c1ab54b99dad Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sun, 27 Jun 2021 13:14:48 -0700 Subject: Fix PR 101230: ICE in fold_cond_expr_with_comparison This fixes PR 101230 where I had messed up and forgot that invert_tree_comparison can return ERROR_MARK if the comparsion is not invertable (floating point types). Committed as obvious after a bootstrap/test on x86_64-linux-gnu-gnu gcc/ChangeLog: PR middle-end/101230 * fold-const.c (fold_ternary_loc): Check the return value of invert_tree_comparison. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr101230-1.c: New test. --- gcc/testsuite/gcc.dg/torture/pr101230-1.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101230-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101230-1.c b/gcc/testsuite/gcc.dg/torture/pr101230-1.c new file mode 100644 index 0000000..f10ca8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101230-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fno-signed-zeros" } */ + + +double distance3d_sqr_pt4d_pt4d(void); + +int update_r_k_curr_cluster; +void update_r_k(void) { + double curr_distance = distance3d_sqr_pt4d_pt4d(); + for (int cluster; cluster; cluster++) + if (0 < curr_distance) { + curr_distance = 0; + update_r_k_curr_cluster = cluster; + } +} -- cgit v1.1 From 0ad9d88a3d7170b3d864693c9eb512f89a5096ff Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 23 Jun 2021 09:59:28 +0200 Subject: tree-optimization/101173 - fix interchange dependence checking This adjusts the loop interchange dependence checking to disallow an outer loop dependence distance of zero. 2021-06-23 Richard Biener PR tree-optimization/101173 * gimple-loop-interchange.cc (tree_loop_interchange::valid_data_dependences): Disallow outer loop dependence distance of zero. * gcc.dg/torture/pr101173.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101173.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101173.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101173.c b/gcc/testsuite/gcc.dg/torture/pr101173.c new file mode 100644 index 0000000..0c9090d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101173.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-additional-options "-floop-interchange" } */ + +int a[6][9]; +int main() +{ + a[1][3] = 8; + for (int b = 1; b <= 5; b++) + for (int d = 0; d <= 5; d++) +#pragma GCC unroll 0 + for (int c = 0; c <= 5; c++) + a[b][c] = a[b][c + 2] & 216; + for (int e = 0; e < 6; e++) + for (int f = 0; f < 9; f++) + if (a[e][f] != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 2ad71efb5de9e929ffd2b8ce0a37c3c34021c0f1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 28 Jun 2021 09:42:58 +0200 Subject: tree-optimization/101207 - fix BB reduc permute elide with life stmts This fixes breakage of live lane extracts from permuted loads we elide from BB reduction vectorization by handling the un-permuting the same as in the regular eliding code - apply the reverse permute to both the scalar stmts and the load permutation. 2021-06-28 Richard Biener PR tree-optimization/101207 * tree-vect-slp.c (vect_optimize_slp): Do BB reduction permute eliding for load permutations properly. * gcc.dg/vect/bb-slp-pr101207.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c new file mode 100644 index 0000000..1f51d66 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ffast-math" } */ + +#include "tree-vect.h" + +double a[2]; +double x, y; + +void __attribute__((noipa)) foo () +{ + x = a[1] - a[0]; + y = a[0] + a[1]; +} + +int main() +{ + check_vect (); + + a[0] = 0.; + a[1] = 1.; + foo (); + if (x != 1. || y != 1.) + __builtin_abort (); + return 0; +} -- cgit v1.1 From f80c4eaca0805bc9e68ed944519519c3dd1c12e1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 28 Jun 2021 11:05:46 +0200 Subject: tree-optimization/101229 - fix vectorizer SLP hybrid detection with PHIs This fixes the missing handling of PHIs in gimple_walk_op which causes the new vectorizer SLP hybrid detection scheme to fail. 2021-06-28 Richard Biener PR tree-optimization/101229 * gimple-walk.c (gimple_walk_op): Handle PHIs. * gcc.dg/torture/pr101229.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101229.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101229.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101229.c b/gcc/testsuite/gcc.dg/torture/pr101229.c new file mode 100644 index 0000000..3708031 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101229.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +int a[1024]; +void foo() +{ + for (int i; i; i += 4) { + int suma = a[i]; + int sumb = a[i + 1]; + int sumc; + for (unsigned j = 0; j < 77; ++j) { + suma = (suma ^ i) + 1; + sumb = (sumb ^ i) + 2; + sumc = suma ^ i; + } + a[i] = suma; + a[i + 1] = sumb; + a[i + 2] = sumc; + } +} -- cgit v1.1 From 2902991a6b61d473f7cb996a2b80eef4a90f8eda Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 28 Jun 2021 18:20:00 +0200 Subject: ipa-sra: Introduce a mini-DCE to tree-inline.c (PR 93385) I was asked by Richi to split my fix for PR 93385 for easier review into IPA-SRA materialization refactoring and the actual DCE addition. This is the second part that actually contains the DCE of statements that IPA-SRA should not leave behind because they can have problematic side effects, even if they are useless, so that we do not depend on tree-dce to remove them for correctness. The patch fixes the problem by doing a def-use walk when materializing clones, marking which statements should not be copied and which SSA_NAMEs do not need to be computed because eventually they would be DCEd. We do this on the original function body and tree-inline simply does not copy statements which are "dead." The only complication is removing dead argument calls because that needs to be communicated to callee redirection code using the infrastructure introduced by the previous patch. I added all testcases of the original patch to this one, although some probably test behavior introduced in the previous patch. gcc/ChangeLog: 2021-05-12 Martin Jambor PR ipa/93385 * ipa-param-manipulation.h (class ipa_param_body_adjustments): New members m_dead_stmts and m_dead_ssas. * ipa-param-manipulation.c (ipa_param_body_adjustments::mark_dead_statements): New function. (ipa_param_body_adjustments::common_initialization): Call it on all removed but not split parameters. (ipa_param_body_adjustments::ipa_param_body_adjustments): Initialize new mwmbers. (ipa_param_body_adjustments::modify_call_stmt): Remove arguments that are dead. * tree-inline.c (remap_gimple_stmt): Do not copy dead statements, reset dead debug statements. (copy_phis_for_bb): Do not copy dead PHI nodes. gcc/testsuite/ChangeLog: 2021-03-22 Martin Jambor PR ipa/93385 * gcc.dg/ipa/pr93385.c: New test. * gcc.dg/ipa/ipa-sra-23.c: Likewise. * gcc.dg/ipa/ipa-sra-24.c: Likewise. * g++.dg/ipa/ipa-sra-4.C: Likewise. --- gcc/testsuite/gcc.dg/ipa/ipa-sra-23.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/ipa-sra-24.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/pr93385.c | 27 +++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-sra-23.c create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-sra-24.c create mode 100644 gcc/testsuite/gcc.dg/ipa/pr93385.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-23.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-23.c new file mode 100644 index 0000000..f438b50 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-23.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern int g; + +static int __attribute__((noinline)) +bar (int i, int j) +{ + return 2*g + i; +} + +static int __attribute__((noinline)) +foo (int i, int j) +{ + if (i > 5) + j = 22; + return bar (i, j) + 1; +} + +int +entry (int l, int k) +{ + return foo (l, k); +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-24.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-24.c new file mode 100644 index 0000000..7b5bf08 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-24.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wmaybe-uninitialized -Werror" } */ + +int *ttmp_1; +_Bool pt_ins_tipdo, pq_ins_apd, pq_ins_tt2; +int gtrphdt; + +void pl_ins(int, _Bool, _Bool); +inline void pt_ins(int *, _Bool apdo) { + int list = *ttmp_1; + pl_ins(list, apdo, pt_ins_tipdo); +} +void pq_ins(int *t) { + if (pq_ins_tt2) + pt_ins(t, pq_ins_apd); +} +int gtr_post_hd() { + pq_ins(>rphdt); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr93385.c b/gcc/testsuite/gcc.dg/ipa/pr93385.c new file mode 100644 index 0000000..6d1d0d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr93385.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-dce -fno-ipa-cp -fno-tree-dce" } */ + +char a, b; + +#ifdef __SIZEOF_INT128__ +#define T unsigned __int128 +#else +#define T unsigned +#endif + +static inline int +c (T d) +{ + char e = 0; + d %= (unsigned) d; + e -= 0; + __builtin_strncpy (&a, &e, 1); + return e + b; +} + +int +main (void) +{ + c (~0); + return 0; +} -- cgit v1.1 From c1f76af469388d3df815c82de566387da5ae000f Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Thu, 20 May 2021 11:19:04 -0700 Subject: CTF/BTF testsuites This commit adds a new testsuite for the CTF debug format. 2021-06-28 Indu Bhagat David Faust gcc/testsuite/ * lib/gcc-dg.exp (gcc-dg-frontend-supports-ctf): New procedure. (gcc-dg-debug-runtest): Add -gctf support. * gcc.dg/debug/btf/btf-1.c: New test. * gcc.dg/debug/btf/btf-2.c: Likewise. * gcc.dg/debug/btf/btf-anonymous-struct-1.c: Likewise. * gcc.dg/debug/btf/btf-anonymous-union-1.c: Likewise. * gcc.dg/debug/btf/btf-array-1.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-1.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-2.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-3.c: Likewise. * gcc.dg/debug/btf/btf-cvr-quals-1.c: Likewise. * gcc.dg/debug/btf/btf-enum-1.c: Likewise. * gcc.dg/debug/btf/btf-forward-1.c: Likewise. * gcc.dg/debug/btf/btf-function-1.c: Likewise. * gcc.dg/debug/btf/btf-function-2.c: Likewise. * gcc.dg/debug/btf/btf-int-1.c: Likewise. * gcc.dg/debug/btf/btf-pointers-1.c: Likewise. * gcc.dg/debug/btf/btf-struct-1.c: Likewise. * gcc.dg/debug/btf/btf-typedef-1.c: Likewise. * gcc.dg/debug/btf/btf-union-1.c: Likewise. * gcc.dg/debug/btf/btf-variables-1.c: Likewise. * gcc.dg/debug/btf/btf.exp: Likewise. * gcc.dg/debug/ctf/ctf-1.c: Likewise. * gcc.dg/debug/ctf/ctf-2.c: Likewise. * gcc.dg/debug/ctf/ctf-anonymous-struct-1.c: Likewise. * gcc.dg/debug/ctf/ctf-anonymous-union-1.c: Likewise. * gcc.dg/debug/ctf/ctf-array-1.c: Likewise. * gcc.dg/debug/ctf/ctf-array-2.c: Likewise. * gcc.dg/debug/ctf/ctf-array-3.c: Likewise. * gcc.dg/debug/ctf/ctf-array-4.c: Likewise. * gcc.dg/debug/ctf/ctf-attr-mode-1.c: Likewise. * gcc.dg/debug/ctf/ctf-attr-used-1.c: Likewise. * gcc.dg/debug/ctf/ctf-bitfields-1.c: Likewise. * gcc.dg/debug/ctf/ctf-bitfields-2.c: Likewise. * gcc.dg/debug/ctf/ctf-bitfields-3.c: Likewise. * gcc.dg/debug/ctf/ctf-bitfields-4.c: Likewise. * gcc.dg/debug/ctf/ctf-complex-1.c: Likewise. * gcc.dg/debug/ctf/ctf-cvr-quals-1.c: Likewise. * gcc.dg/debug/ctf/ctf-cvr-quals-2.c: Likewise. * gcc.dg/debug/ctf/ctf-cvr-quals-3.c: Likewise. * gcc.dg/debug/ctf/ctf-cvr-quals-4.c: Likewise. * gcc.dg/debug/ctf/ctf-enum-1.c: Likewise. * gcc.dg/debug/ctf/ctf-enum-2.c: Likewise. * gcc.dg/debug/ctf/ctf-file-scope-1.c: Likewise. * gcc.dg/debug/ctf/ctf-float-1.c: Likewise. * gcc.dg/debug/ctf/ctf-forward-1.c: Likewise. * gcc.dg/debug/ctf/ctf-forward-2.c: Likewise. * gcc.dg/debug/ctf/ctf-func-index-1.c: Likewise. * gcc.dg/debug/ctf/ctf-function-pointers-1.c: Likewise. * gcc.dg/debug/ctf/ctf-function-pointers-2.c: Likewise. * gcc.dg/debug/ctf/ctf-function-pointers-3.c: Likewise. * gcc.dg/debug/ctf/ctf-functions-1.c: Likewise. * gcc.dg/debug/ctf/ctf-int-1.c: Likewise. * gcc.dg/debug/ctf/ctf-objt-index-1.c: Likewise. * gcc.dg/debug/ctf/ctf-pointers-1.c: Likewise. * gcc.dg/debug/ctf/ctf-pointers-2.c: Likewise. * gcc.dg/debug/ctf/ctf-preamble-1.c: Likewise. * gcc.dg/debug/ctf/ctf-skip-types-1.c: Likewise. * gcc.dg/debug/ctf/ctf-skip-types-2.c: Likewise. * gcc.dg/debug/ctf/ctf-skip-types-3.c: Likewise. * gcc.dg/debug/ctf/ctf-skip-types-4.c: Likewise. * gcc.dg/debug/ctf/ctf-skip-types-5.c: Likewise. * gcc.dg/debug/ctf/ctf-skip-types-6.c: Likewise. * gcc.dg/debug/ctf/ctf-str-table-1.c: Likewise. * gcc.dg/debug/ctf/ctf-struct-1.c: Likewise. * gcc.dg/debug/ctf/ctf-struct-2.c: Likewise. * gcc.dg/debug/ctf/ctf-struct-array-1.c: Likewise. * gcc.dg/debug/ctf/ctf-struct-pointer-1.c: Likewise. * gcc.dg/debug/ctf/ctf-struct-pointer-2.c: Likewise. * gcc.dg/debug/ctf/ctf-typedef-1.c: Likewise. * gcc.dg/debug/ctf/ctf-typedef-2.c: Likewise. * gcc.dg/debug/ctf/ctf-typedef-3.c: Likewise. * gcc.dg/debug/ctf/ctf-typedef-struct-1.c: Likewise. * gcc.dg/debug/ctf/ctf-typedef-struct-2.c: Likewise. * gcc.dg/debug/ctf/ctf-typedef-struct-3.c: Likewise. * gcc.dg/debug/ctf/ctf-union-1.c: Likewise. * gcc.dg/debug/ctf/ctf-variables-1.c: Likewise. * gcc.dg/debug/ctf/ctf-variables-2.c: Likewise. * gcc.dg/debug/ctf/ctf.exp: Likewise. --- gcc/testsuite/gcc.dg/debug/btf/btf-1.c | 6 ++ gcc/testsuite/gcc.dg/debug/btf/btf-2.c | 10 +++ .../gcc.dg/debug/btf/btf-anonymous-struct-1.c | 23 ++++++ .../gcc.dg/debug/btf/btf-anonymous-union-1.c | 23 ++++++ gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c | 31 ++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c | 34 +++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-2.c | 26 +++++++ gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c | 43 ++++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c | 23 ++++++ gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c | 52 ++++++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c | 45 ++++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 30 ++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-forward-1.c | 24 +++++++ gcc/testsuite/gcc.dg/debug/btf/btf-function-1.c | 18 +++++ gcc/testsuite/gcc.dg/debug/btf/btf-function-2.c | 18 +++++ gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c | 22 ++++++ gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c | 44 ++++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-pointers-1.c | 25 +++++++ gcc/testsuite/gcc.dg/debug/btf/btf-pointers-2.c | 13 ++++ gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c | 22 ++++++ gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c | 19 +++++ gcc/testsuite/gcc.dg/debug/btf/btf-typedef-1.c | 82 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c | 16 +++++ gcc/testsuite/gcc.dg/debug/btf/btf-variables-1.c | 33 +++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c | 27 +++++++ gcc/testsuite/gcc.dg/debug/btf/btf-variables-3.c | 36 ++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf.exp | 41 +++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-1.c | 6 ++ gcc/testsuite/gcc.dg/debug/ctf/ctf-2.c | 10 +++ .../gcc.dg/debug/ctf/ctf-anonymous-struct-1.c | 23 ++++++ .../gcc.dg/debug/ctf/ctf-anonymous-union-1.c | 26 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-array-1.c | 31 ++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c | 38 ++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-array-3.c | 17 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-array-4.c | 13 ++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c | 22 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-used-1.c | 22 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-1.c | 30 ++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-2.c | 39 ++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-3.c | 16 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-4.c | 19 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c | 21 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c | 65 +++++++++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-2.c | 30 ++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-3.c | 25 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-4.c | 23 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-1.c | 7 ++ gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-2.c | 7 ++ gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-1.c | 21 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-2.c | 27 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c | 25 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-float-1.c | 16 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-1.c | 40 +++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-2.c | 16 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-func-index-1.c | 25 +++++++ .../gcc.dg/debug/ctf/ctf-function-pointers-1.c | 24 +++++++ .../gcc.dg/debug/ctf/ctf-function-pointers-2.c | 22 ++++++ .../gcc.dg/debug/ctf/ctf-function-pointers-3.c | 21 ++++++ .../gcc.dg/debug/ctf/ctf-function-pointers-4.c | 18 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-functions-1.c | 34 +++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-int-1.c | 17 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-objt-index-1.c | 30 ++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-1.c | 26 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-2.c | 25 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-preamble-1.c | 11 +++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-1.c | 38 ++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c | 17 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-3.c | 20 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c | 19 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-5.c | 19 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-6.c | 18 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-7.c | 18 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-8.c | 27 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-str-table-1.c | 26 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-1.c | 25 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-2.c | 32 +++++++++ .../gcc.dg/debug/ctf/ctf-struct-array-1.c | 65 +++++++++++++++++ .../gcc.dg/debug/ctf/ctf-struct-array-2.c | 15 ++++ .../gcc.dg/debug/ctf/ctf-struct-pointer-1.c | 21 ++++++ .../gcc.dg/debug/ctf/ctf-struct-pointer-2.c | 22 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-1.c | 68 ++++++++++++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-2.c | 20 ++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-3.c | 24 +++++++ .../gcc.dg/debug/ctf/ctf-typedef-struct-1.c | 14 ++++ .../gcc.dg/debug/ctf/ctf-typedef-struct-2.c | 17 +++++ .../gcc.dg/debug/ctf/ctf-typedef-struct-3.c | 32 +++++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-union-1.c | 14 ++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-1.c | 25 +++++++ gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-2.c | 16 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf.exp | 41 +++++++++++ 90 files changed, 2327 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-struct-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-union-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-forward-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-pointers-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-pointers-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-typedef-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf.exp create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-struct-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-union-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-used-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-float-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-func-index-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-functions-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-int-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-objt-index-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-preamble-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-5.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-6.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-7.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-8.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-str-table-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-union-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf.exp (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-1.c new file mode 100644 index 0000000..bcbc949 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-gbtf" } */ + +void func(void) +{ +} diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-2.c new file mode 100644 index 0000000..70e2ff1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-2.c @@ -0,0 +1,10 @@ +/* Check the BTF header information. */ + +/* { dg-do compile } */ +/* { dg-options "-gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "0xeb9f.*btf_magic" 1} } */ +/* { dg-final { scan-assembler-times "0x1.*btf_version" 1 } } */ +/* { dg-final { scan-assembler-times "0.*btf_flags" 1 } } */ + +int foo; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-struct-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-struct-1.c new file mode 100644 index 0000000..89a5701 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-struct-1.c @@ -0,0 +1,23 @@ +/* Test BTF generation of anonymous struct. + + We expect two BTF struct records: + - struct foo, with two fields "a" and "bar" + - struct with one field "b" + + The anonymous struct should have a name of 0, pointing to the null string + at the start of the string table. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Struct type with 2 members (struct foo). */ +/* { dg-final { scan-assembler-times "\[\t \]0x4000002\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Struct type with 1 member (anon struct). */ +/* { dg-final { scan-assembler-times "\[\t \]0x4000001\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*btt_name" 1 } } */ + +struct foo +{ + int a; + struct { int b; } bar; +} myfoo; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-union-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-union-1.c new file mode 100644 index 0000000..f3b120bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-anonymous-union-1.c @@ -0,0 +1,23 @@ +/* Test BTF generation of anonymous union. + + We expect a named struct type and an anonymous union type record to + be generated. The anonymous union record should have a name of 0, + pointing to the null string at the start of the string table. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Struct type with 1 member. */ +/* { dg-final { scan-assembler-times "\[\t \]0x4000001\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Union type with 2 members. */ +/* { dg-final { scan-assembler-times "\[\t \]0x5000002\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*btt_name" 1 } } */ + +struct foo +{ + union + { + int value; + char ascii; + }; +} myfoo; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c new file mode 100644 index 0000000..ab55445 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c @@ -0,0 +1,31 @@ +/* BTF generation for array type. + + Unsized arrays are encoded with a 0 for the number of elements. + + In this testcase, 5 distinct BTF records for arrays are expected + b1 : cta_nelems = 2 + c1 : cta_nelems = 3 + a1 : cta_nelems = 2, 5 + buf : cta_nelems = 0. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "0x3000000\[\t \]+\[^\n\]*btt_info" 5 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*bta_nelems" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*bta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*bta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*bta_nelems" 1 } } */ + +int b1[2] = {0,1}; +int c1[5] = {0,1,2,3,4}; +int a1[2][3] = { {3,4,5}, {2,3,4} }; + +/* Variable length struct using arrays. */ +struct my_array +{ + int flags; + int length; + int buf[]; +} my_array_obj; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c new file mode 100644 index 0000000..c6bf521 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c @@ -0,0 +1,34 @@ +/* Basic tests for BTF bitfields. + + The structure containing bitfield members should be marked with KIND_FLAG=1 + The bitfield member offsets should be encoded as: + (bit_size << 24) | bit_offset + - (0xa << 24) | 0x20 + - (0x7 << 24) | 0x2a + - (0x13 << 24) | 0x40 - note that this is aligned to 0x40. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x84000004\[\t \]+\[^\n\]*btt_info" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0xa000020\[\t \]+\[^\n\]*btm_offset" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x700002a\[\t \]+\[^\n\]*btm_offset" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x13000040\[\t \]+\[^\n\]*btm_offset" 1 } } */ + +struct bitt { + int a; + unsigned int bitfield_a : 10; + unsigned int bitfield_b : 7; + unsigned int bitfield_c : 19; +} bitty; + +struct no_bitt { + int a; + int b; +} no_bitty; + +int main () +{ + return bitty.bitfield_b + bitty.a; +} diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-2.c new file mode 100644 index 0000000..9665ab6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-2.c @@ -0,0 +1,26 @@ +/* Test BTF generation for struct with 0 size bitfield. + + We expect a struct with 2 members to be generated. The size 0 bitfield + should not have any entry in the member list. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Struct with bitfield members, and 2 members. */ +/* { dg-final { scan-assembler-times "\[\t \]0x84000002\[\t \]+\[^\n\]*btt_info" 1 } } */ + +/* Bitfield size 31 (0x1f) at offset 0. */ +/* { dg-final { scan-assembler-times "\[\t \]0x1f000000\[\t \]+\[^\n\]*btm_offset" 1 } } */ + +/* Bitfield size 32 (0x20) at offset 32. */ +/* { dg-final { scan-assembler-times "\[\t \]0x20000020\[\t \]+\[^\n\]*btm_offset" 1 } } */ + +/* Only 2 members. */ +/* { dg-final { scan-assembler-times "btm_name" 2 } } */ + +struct foo +{ + unsigned a : 31; + unsigned : 0; + unsigned c : 32; +} myfoo; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c new file mode 100644 index 0000000..440623c3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c @@ -0,0 +1,43 @@ +/* Test BTF generation for enum-type bitfields + + It is allowed to have a bitfield type be an enum type. + We expect the following types: + + [1] enum 'foo'(1U#B) size=4U#B + 'BAR' value=0 + 'BAZ' value=1 + 'QUZ' value=2 + 'QUX' value=3 + [2] int 'unsigned int' size=4 offset=0 bits=32 + [3] struct 'bitt' size=4 + member 'f' type=1 bitfield_size=2 bit_offset=0 + member 'data' type=2 bitfield_size=14 bit_offset=2 + */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Enum with 4 members. */ +/* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Struct with bitfield members, and 2 members. */ +/* { dg-final { scan-assembler-times "\[\t \]0x84000002\[\t \]+\[^\n\]*btt_info" 1 } } */ + +/* Bitfield "f" points to type ID 1. */ +/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btm_type" 1 } } */ + +/* Bitfield "data" points to type ID 2. */ +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btm_type" 1 } } */ + +enum foo +{ + BAR = 0, + BAZ = 1, + QUZ = 2, + QUX = 3 +}; + +struct bitt +{ + enum foo f : 2; + unsigned data : 14; +} bitty; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c new file mode 100644 index 0000000..af91845 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c @@ -0,0 +1,23 @@ +/* Test BTF generation for non-representable bitfields. + + Due to the limitations of BTF, we only have 24 bits in which to store + the bitfield offset (in bits, from the beginning of the struct). + + In this test, we construct a structure such that the bitfield will have + an offset so large as to be unrepresentable in BTF. We expect that the + resulting BTF will describe the rest of the structure, ignoring the + non-representable bitfield. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Struct with 3 members and no bitfield (kind_flag not set). */ +/* { dg-final { scan-assembler-times "\[\t \]0x4000003\[\t \]+\[^\n\]*btt_info" 1 } } */ + +struct bigly +{ + int a; + int b[((0xffffff + 1) / (8 * sizeof (int)))]; + unsigned unsup : 7; + char c; +} big; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c new file mode 100644 index 0000000..79e9f52 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c @@ -0,0 +1,52 @@ +/* Test BTF generation of BTF_KIND_{CONST,VOLATILE,RESTRICT} records. + + BTF const, volatile and restrict records are nameless type records pointing + to the type they modify. + + Types: + [1] int 'int' size=4U offset=0 bits=32 SIGNED + [2] const type=1 + [3] volatile type=1 + [4] const type=3 + [5] ptr type=1 + [6] restrict type=5 + [7] ptr type=2 + [8] restrict type=7 + + Note: + - Type id 3 describes a volatile int. + - Type id 2 describes a const int. + - Type id 4 describes a const volatile int by modifying id 3. + - Type id 6 describes a restrict pointer to int. + - Type id 8 describes a restrict pointer to const int. + */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +/* types 5 and 7 are pointers, to 'int' and 'const int' respectively. */ +/* { dg-final { scan-assembler-times "\[\t \]0x2000000\[\t \]+\[^\n\]*btt_info" 2 } } */ + +/* type 3 has VOLATILE qualifier */ +/* { dg-final { scan-assembler-times "\[\t \]0x9000000\[\t \]+\[^\n\]*btt_info" 1 } } */ + +/* types 2 and 4 have CONST qualifier. */ +/* { dg-final { scan-assembler-times "\[\t \]0xa000000\[\t \]+\[^\n\]*btt_info" 2 } } */ + +/* types 6 and 8 have RESTRICT qualifier. */ +/* { dg-final { scan-assembler-times "\[\t \]0xb000000\[\t \]+\[^\n\]*btt_info" 2 } } */ + +const int a = 10; + +volatile int b; + +int * restrict c; + +const volatile int d = 20; + +const int * restrict e; + +const int * f; +int const * g; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c new file mode 100644 index 0000000..88ae4c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c @@ -0,0 +1,45 @@ +/* BTF generation of BTF_KIND_DATASEC records. + + We expect 3 DATASEC records: one for each of .data, .rodata and .bss. + .rodata: the consts; c,e,my_cstruct + .bss: a,b,bigarr + .data: d + + The type IDs of the variables placed in each section are not deterministic + so we cannot check them. + */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Check for two DATASEC entries with vlen 3, and one with vlen 1. */ +/* { dg-final { scan-assembler-times "0xf000003\[\t \]+\[^\n\]*btt_info" 2 } } */ +/* { dg-final { scan-assembler-times "0xf000001\[\t \]+\[^\n\]*btt_info" 1 } } */ + +/* The offset entry for each variable in a DATSEC should be 0 at compile time. */ +/* { dg-final { scan-assembler-times "0\[\t \]+\[^\n\]*bts_offset" 7 } } */ + +/* Check that strings for each DATASEC have been added to the BTF string table. */ +/* { dg-final { scan-assembler-times "ascii \".data.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \".rodata.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \".bss.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ + +int a; +long long b; +const long unsigned int c; + +int d = 137; + +const int e = -55; + +int bigarr[20][10]; + +struct c_struct { + long x; + char c; +}; + +const struct c_struct my_cstruct = { + 99, + '?' +}; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c new file mode 100644 index 0000000..728493b --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c @@ -0,0 +1,30 @@ +/* Test BTF generation for enums. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x6000003\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"QAD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"QED.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"QOD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"QUD.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"YES.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"NO.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"IDUNNO.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "bte_value" 7 } } */ + +enum foo +{ + QAD, + QED, + QOD, + QUD, +} a; + +enum barsigned +{ + YES=1000, + NO=-1000, + IDUNNO=0, +} b; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-forward-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-forward-1.c new file mode 100644 index 0000000..c894fa2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-forward-1.c @@ -0,0 +1,24 @@ +/* Test BTF generation of forwards. + + Check that the KIND_FLAG (bit 31) of btt_info is set (1) for the forward to + union, and not set (0) for forward to struct. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x87000000\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x7000000\[\t \]+\[^\n\]*btt_info" 1 } } */ + +typedef struct _fwd_st +{ + struct unk_struct_type *data[4]; +} fwd_st_t; + +fwd_st_t struct_container; + +typedef struct _fwd_un +{ + union unk_union_type *options[4]; +} fwd_un_t; + +fwd_un_t union_container; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-function-1.c new file mode 100644 index 0000000..9fa1498 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-1.c @@ -0,0 +1,18 @@ +/* Test BTF generation for functions. + + We expect to see one BTF_KIND_FUNC_PROTO with 2 named arguments. + The parameter names should appear in the auxilliary string table. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0xd000002\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "farg_name" 2 } } */ +/* { dg-final { scan-assembler-times "farg_type" 2 } } */ +/* { dg-final { scan-assembler-times "ascii \"alpha.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"bravo.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ + +int funfoo (int alpha, long bravo) +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-function-2.c new file mode 100644 index 0000000..3c7fda9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-2.c @@ -0,0 +1,18 @@ +/* Test BTF generation for functions with varargs. + + We expect one BTF_KIND_FUNC_PROTO with two arguments. The second argument + should have "farg_name" and "farg_type" both of 0, representing varargs. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0xd000002\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "farg_name" 2 } } */ +/* { dg-final { scan-assembler-times "farg_type" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*farg_name" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*farg_type" 1 } } */ + +int fmt (const char * format, ...) +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c new file mode 100644 index 0000000..35f96a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c @@ -0,0 +1,22 @@ +/* Test BTF generation for a function with an unrepresentable parameter. + + BTF has no encoding for floating point types, among others. Function + parameters of unrepresentable types are emitted as 'void' types. + + We expect one BTF_KIND_FUNC_PROTO with 3 parameters, one of which + has type_id=0. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0xd000003\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "farg_name" 3 } } */ +/* { dg-final { scan-assembler-times "farg_type" 3 } } */ + +/* Exactly one function parameter should have type_id=0. */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*farg_type" 1 } } */ + +int foo (int a, float f, long b) +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c new file mode 100644 index 0000000..2381dec --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c @@ -0,0 +1,44 @@ +/* Tests for BTF integer base types. + + 0 f ff 00 ff + | 0 | encoding | offset | 00 | bits | + encoding: + signed 1 << 24 + char 2 << 24 + + All offsets in this test should be 0. + This test does _not_ check number of bits, as it may vary between targets. + */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Check for 8 BTF_KIND_INT types. */ +/* { dg-final { scan-assembler-times "\[\t \]0x1000000\[\t \]+\[^\n\]*btt_info" 8 } } */ + +/* Check the signed/char flags, but not bit size. */ +/* { dg-final { scan-assembler-times "\[\t \]0x10000..\[\t \]+\[^\n\]*bti_encoding" 3 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x20000..\[\t \]+\[^\n\]*bti_encoding" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x30000..\[\t \]+\[^\n\]*bti_encoding" 1 } } */ + +/* Check that there is a string entry for each type name. */ +/* { dg-final { scan-assembler-times "ascii \"unsigned char.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"signed char.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"short unsigned int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"short int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"unsigned int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"long unsigned int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"long int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +unsigned char a = 11; +signed char b = -22; + +unsigned short c = 33; +signed short d = 44; + +unsigned int e = 55; +signed int f = -66; + +unsigned long int g = 77; +signed long int h = 88; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-pointers-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-pointers-1.c new file mode 100644 index 0000000..a14ac0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-pointers-1.c @@ -0,0 +1,25 @@ +/* Test BTF generation for pointer types. + + Two pointer types are expected: + - int * + - struct st * + */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2000000\[\t \]+\[^\n\]*btt_info" 2 } } */ +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"st.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +int foo = 10; +int *pfoo = &foo; + +struct st +{ + int a; + int *pb; + struct st * next; +}; + +struct st * bar; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-pointers-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-pointers-2.c new file mode 100644 index 0000000..c77b224 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-pointers-2.c @@ -0,0 +1,13 @@ +/* Test BTF generation for pointers to void. + + In this test, we expect that the pointer references type ID 0, the reserved + void typeid, and that no intermediate type is generated for void. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2000000\[\t \]+\[^\n\]*btt_info" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x1000000\[\t \]+\[^\n\]*btt_info" 0 } } */ + +void *ptr; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c new file mode 100644 index 0000000..bc32814 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c @@ -0,0 +1,22 @@ +/* Test BTF generation of struct type. + + Two BTF_KIND_STRUCT records are expected. + - struct foo with 3 members + - struct data with 2 members */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x4000003\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x4000002\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "btm_name" 5 } } */ + +struct foo +{ + int after; + int before; + struct { + unsigned short n_valid; + int set[10]; + } data; +} my_foo; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c new file mode 100644 index 0000000..24514fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c @@ -0,0 +1,19 @@ +/* Test BTF generation for struct type with a member which refers to an + unsupported type. + + BTF does not support floating point types (among other things). When + generating BTF for a struct (or union) type, members which refer to + unsupported types should be skipped. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Expect a struct with only 2 members - 'f' should not be present. */ +/* { dg-final { scan-assembler-times "\[\t \]0x4000002\[\t \]+\[^\n\]*btt_info" 1 } } */ + +struct with_float +{ + int a; + float f; + char c; +} instance; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-typedef-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-typedef-1.c new file mode 100644 index 0000000..472cc63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-typedef-1.c @@ -0,0 +1,82 @@ +/* Test BTF generation for BTF_KIND_TYPEDEF records. + + 7 typedef records are expected. We expect the following types (among others): + [1] int 'int' size=4 offset=0 bits=32 SIGNED + [2] typedef 'my_int' type=1 + [3] typedef 'foo_int' type=1 + [4] typedef 'bar_int' type=1 + .. + [6] typedef 'CBAR' type=5 + .. + [8] typedef 'CBARP' type=7 + [9] struct '_node' size=16 + .. + [11] typedef 'node_t' type=9 + [12] struct '_arena' + .. + [15] typedef 'arena_t' type=12 + [16] var 'a' type=2 linkage=1 (global) + [17] var 'suitcase' type=15 linkage=1 (global) + [18] var 'b' type=3 linkage=1 (global) + [19] var 'c' type=4 linkage=1 (global) + [20] var 'd' type=11 linkage=1 (global) + [21] var 'destination' type=6 linkage=1 (global) + [22] var 'ticket' type=8 linkage=1 (global) + + Note that the order of the variables is not guaranteed, so we do not check + particular variables have exactly the right typedef. Instead, we check: + 1. 7 typedef records are generated, along with the correct strings for them. + 2. There is one variable pointing to each typedef. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x8000000\[\t \]+\[^\n\]*btt_info" 7 } } */ + +/* { dg-final { scan-assembler-times "ascii \"my_int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo_int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"bar_int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"CBAR.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"CBARP.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"node_t.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"arena_t.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btv_type" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*btv_type" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*btv_type" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x6\[\t \]+\[^\n\]*btv_type" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x8\[\t \]+\[^\n\]*btv_type" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xb\[\t \]+\[^\n\]*btv_type" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xf\[\t \]+\[^\n\]*btv_type" 1 } } */ + +typedef int my_int; +typedef int foo_int; +typedef int bar_int; + +typedef const bar_int CBAR; +typedef const bar_int * CBARP; + +typedef struct _node +{ + foo_int name_off; + bar_int info; + struct _node * next; +} node_t; + + +typedef struct _arena +{ + node_t nodes[16]; + my_int vardata; + bar_int flags; +} arena_t; + +my_int a; +foo_int b; +bar_int c; +node_t d; + +CBAR destination; +CBARP ticket = &destination; + +arena_t suitcase; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c new file mode 100644 index 0000000..d668437 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c @@ -0,0 +1,16 @@ +/* Test BTF generation for union type. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* One union type with 4 members */ +/* { dg-final { scan-assembler-times "\[\t \]0x5000004\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times "btm_name" 4 } } */ + +union onion +{ + int redness; + char *name; + unsigned short freshness; + unsigned short flavor; +} my_onion; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-1.c new file mode 100644 index 0000000..a79ed1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-1.c @@ -0,0 +1,33 @@ +/* BTF generation for variables. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* We expect 6 variables */ +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*btv_info" 6 } } */ + +unsigned int x1; + +struct st +{ + int a; + int b; +}; + +union { + long int value; + struct st * pointer; +} bar; + +enum +{ + FOO = 0, + BAR = 2, + BAZ, +} lala; + +int arr[10][20]; + +unsigned long * plong; + +struct st st_inst; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c new file mode 100644 index 0000000..0f9742e --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c @@ -0,0 +1,27 @@ +/* BTF generation for variables with removed type. + + BTF does not support floating point types, so no representation for the type + 'float' will be emitted. In this test, we check to also ensure that the + variable 'bar' is not emitted, as it references a type that is not supported + in BTF. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* We expect only 3 variables. */ +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*btv_info" 3 } } */ + +/* { dg-final { scan-assembler-times "ascii \"foo.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"baz.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"myst.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +int foo; +float bar; +int baz[10]; + +struct st +{ + int a; + int b : 6; + int c : 2; +} myst; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-3.c new file mode 100644 index 0000000..8cae221 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-3.c @@ -0,0 +1,36 @@ +/* Test BTF generation for static versus global variables. + + BTF_KIND_VAR types represeting variables are followed by a 32-bit + "linkage", which can take one of currently two valid values: + 0 = static + 1 = global + + In this test, make a few static and a few global variables, and ensure + they are noted with the correct "linkage" values. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Expect 6 variables. */ +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*btv_info" 6 } } */ + +/* 3 global, 3 static. */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*btv_linkage" 3 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btv_linkage" 3 } } */ + +int a; + +static long b; + +struct foo { + int x; + int y; +}; + +struct foo g_foo; + +static struct foo s_foo; + +static unsigned int s_arr [10][5]; + +unsigned int g_arr [20]; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf.exp b/gcc/testsuite/gcc.dg/debug/btf/btf.exp new file mode 100644 index 0000000..e72a2be --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2002-2019 Free Software Foundation, Inc. + +# This program 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 of the License, or +# (at your option) any later version. +# +# This program 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Disable on ptx (in sync with DWARF testsuite) +if { [istarget nvptx-*-*] } { + return +} + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-1.c new file mode 100644 index 0000000..6f637df --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ + +void func(void) +{ +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-2.c new file mode 100644 index 0000000..ccbb109 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-2.c @@ -0,0 +1,10 @@ +/* A LEVEL of 0 with -gctf turns off CTF debug info generation. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf0 -dA" } */ + +/* { dg-final { scan-assembler-times "0xdff2.*CTF preamble magic number" 0} } */ +/* { dg-final { scan-assembler-times "0x4.*CTF preamble version" 0 } } */ +/* { dg-final { scan-assembler-times "0.*CTF preamble flags" 0 } } */ + +const char * _CONTEXT_NAME = "foobar"; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-struct-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-struct-1.c new file mode 100644 index 0000000..93547d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-struct-1.c @@ -0,0 +1,23 @@ +/* Test compilation and CTF generation of anonymous structs. An anonymous + struct type is encoded as no-name CTF struct type. + + For this testcase, a single CTF anonymous struct is expected. + struct {} : ctt_name = 0 (point to offset 0 in the CTF string table to + denote empty string) + + Two CTF struct records should be generated in total. + struct a : ctt_info = 0x1a000002 (2 fields) + struct {} : ctt_info = 0x1a000001 (1 field) */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 1 } } */ +/* { dg-final { scan-assembler-times "0x1a000002\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "0x1a000001\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +struct a +{ + struct { int b1; } a1; + int a2; +} my_a; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-union-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-union-1.c new file mode 100644 index 0000000..f45af9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-anonymous-union-1.c @@ -0,0 +1,26 @@ +/* Test compilation and CTF generation of anonymous union. An anonymous union + is encoded as no-name CTF union type. + + For this testcase, a single CTF anonymous union is expected. + struct {} : ctt_name = 0 (point to offset 0 in the CTF string table to + denote empty string) + + Two CTF struct records should be generated in total. + struct anon_union : ctt_info = 0x1a000001 (1 field) + union {} : ctt_info = 0x1e000002 (2 fields) */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 1 } } */ +/* { dg-final { scan-assembler-times "0x1a000001\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "0x1e000002\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +struct anon_union +{ + union + { + char name; + int value; + }; +} my_anon_u; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-1.c new file mode 100644 index 0000000..006a758 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-1.c @@ -0,0 +1,31 @@ +/* CTF generation for array type. + + Unsized arrays are encoded with a 0 for the number of elements. + + In this testcase, 5 distinct CTF records for arrays are expected + b1 : cta_nelems = 2 + c1 : cta_nelems = 3 + a1 : cta_nelems = 2, 5 + buf : cta_nelems = 0. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 5 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*cta_nelems" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 1 } } */ + +int b1[2] = {0,1}; +int c1[5] = {0,1,2,3,4}; +int a1[2][3] = { {3,4,5}, {2,3,4} }; + +/* Variable length struct using arrays. */ +struct my_array +{ + int flags; + int length; + int buf[]; +} my_array_obj; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c new file mode 100644 index 0000000..2a19da0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c @@ -0,0 +1,38 @@ +/* CTF generation for unsized arrays. + + Unsized arrays are encoded with a 0 for the number of elements. The type + of array index is the INT type. + + TBD_CTF_FORMAT_OPEN_ISSUES (1) - + This testcase makes a note of the case of a probable misrepresentation. + See Note 1 and Note 2 below. + + In the CTF section, these types are encoded as : + + Variables: + _CTF_NEWSTR -> 7: const char [0] (size 0x0) + _CTF_SECTION -> 6: const char [5] (size 0x5) + b1 -> 2: int [0] (size 0x0) + b2 -> 3: int [0] (size 0x0) + + Note 1 : There is misrepresentation in that b1 and b2 are specified + differently by the user. + Note 2 : It is arguable though whether the representation for + _CTF_NEWSTR is incorrect. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 5 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 3 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cta_nelems" 1 } } */ + +static int b1[] = {}; + +int b2[0]; + +const char _CTF_SECTION[] = ".ctf"; + +extern const char _CTF_NEWSTR[]; +const char _CTF_NEWSTR[] = "ctfinfo"; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-3.c new file mode 100644 index 0000000..8def208 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-3.c @@ -0,0 +1,17 @@ +/* CTF generation for variable length arrays. + + In this testcase, a specific flavor of vla appears in the function + signature. + + TBD_CTF_FORMAT_OPEN_ISSUES (1) - + This testcase makes a note of another case of a probable misrepresentation. + See ctf-array-2.c for some context on how vla's are a case of a probable + misrepresentation in CTF. Nevertheless, compilation should not fail. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ + +int foo (int a, int b[a][a]) +{ + return b[a-1][a-3]; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-4.c new file mode 100644 index 0000000..013a8ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-4.c @@ -0,0 +1,13 @@ +/* CTF generation for array type. + + Test CTF generation for single element arrays. In this testcase, one CTF + record for array is expected with cta_nelems = 1. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*cta_nelems" 1 } } */ + +int b[1]; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c new file mode 100644 index 0000000..fc3af03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c @@ -0,0 +1,22 @@ +/* Test CTF generation works well with ((mode)) attribute. + + In this testcase, CTF should report type of bqi to be an enum and + not an int. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"B1.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"B2.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"B3.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "cte_value" 3} } */ + +/* There are no better/direct methods to assert that the CTF for typedef of + enum has been added. */ +/* { dg-final { scan-assembler-times "\[\t \]0x22000003\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*ctv_typeidx" 1} } */ + +typedef enum { B1 = 1, B2 = 2, B3 = 3 } B; +B __attribute__ ((mode (QI))) bqi; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-used-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-used-1.c new file mode 100644 index 0000000..61f6b64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-used-1.c @@ -0,0 +1,22 @@ +/* Test CTF generation works well with ((used)) function attribute. + + This attribute, attached to a function, means that code must be emitted for + the function even if it appears that the function is not referenced. */ + +/* { dg-do compile ) */ +/* { dg-options "-O2 -gctf -dA" } */ + +/* These should be true for higher optimization levels. */ +/* { dg-final { scan-assembler-times "ascii \"keep_this.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"lose_this.0\"\[\t \]+\[^\n\]*ctf_string" 0 } } */ + +static int lose_this(int a) +{ + return a + 2; +} + +__attribute__((used)) +static int keep_this(double a) +{ + return a * 2; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-1.c new file mode 100644 index 0000000..1deac90 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-1.c @@ -0,0 +1,30 @@ +/* CTF generation for bitfields. + + In this testcase, two slices are expected - one for enum and the other for + int. CTF slices are unnamed records. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*cts_bits" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*cts_bits" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 2 } } */ + +enum color +{ + RED, + GREEN, + BLUE, + YELLOW, + ORANGE, + BLACK +}; + +struct quickcolor +{ + enum color col:3; + int brushid:2; + int strokes; +}; + +struct quickcolor qc; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-2.c new file mode 100644 index 0000000..aea0921 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-2.c @@ -0,0 +1,39 @@ +/* The bitfield type (int) may be shared, but slices are not de-duplicated. + + In this testcase, it is expected to see a total of 6 CTF slices and 2 CTF + integer types for the bitfields - unsigned long long and signed long long. + + cts_offset is the offset of the bitfield into a machine word. + TBD - hardcoding cts_offset checks into the testcase will cause it to break + across targets with different BIT_PER_WORD. Is there a way to add + cts_offset related checks in the testcase? */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x6\[\t \]+\[^\n\]*cts_type" 3 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*cts_type" 3 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0xf\[\t \]+\[^\n\]*cts_bits" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x21\[\t \]+\[^\n\]*cts_bits" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x10\[\t \]+\[^\n\]*cts_bits" 2 } } */ + +/* { dg-final { scan-assembler-times "ascii \"long long unsigned int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"long long int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct fields +{ + unsigned long long u1 : 15; + unsigned long long u2 : 33; + unsigned long long u3 : 16; + signed long long s1 : 15; + signed long long s2 : 33; + signed long long s3 : 16; +} flags; + +int i = 33; + +int main () +{ + return flags.u1 + i; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-3.c new file mode 100644 index 0000000..8fbcf12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-3.c @@ -0,0 +1,16 @@ +/* The bool bitfield type. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*cts_type" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*cts_bits" 2 } } */ + +/* { dg-final { scan-assembler-times "ascii \"_Bool.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +#include + +struct open_file { + bool mmapped:1; + bool released:1; +} of; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-4.c new file mode 100644 index 0000000..012069a --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-4.c @@ -0,0 +1,19 @@ +/* The zero sized bitfield. + + In this testcase, two slices are expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*cts_type" 2 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cts_bits" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xa\[\t \]+\[^\n\]*cts_bits" 1 } } */ + +/* { dg-final { scan-assembler-times "ctm_name" 2 } } */ +struct foo +{ + int a:5; + unsigned:0; + int b:10; +} foome; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c new file mode 100644 index 0000000..a36dd9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c @@ -0,0 +1,21 @@ +/* Tests for CTF complex base types. + + CTF does not have representation for complex integer types. + + This testcase has a mix of C constructs containing COMPLEX_TYPE. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-require-effective-target libc_has_complex_functions } */ + +/* { dg-final { scan-assembler-times "ascii \"complex double.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"complex long double.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"complex float.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +#include + +double complex z1 = I * I; + +const long double complex z2 = I * I; + +float complex z4 = 1+2.11*I; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c new file mode 100644 index 0000000..9368d47 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c @@ -0,0 +1,65 @@ +/* Test compilation of stubs with various qualifiers - const, restrict and + volatile. + + Testcase includes a std header to allow testing of shared types across + files. Only one CTF record for int is expected. + + CTF records for CVR qualifiers are no-name records. In this testcase, there + are 5 qualifiers across constructs. 2 more no-name CTF records correspond to + CTF pointer records. + + TYPEID: name string (size) -> ref TYPEID : ref name string (size) -> ... + + Types: + 1: long int (size 0x8) + 2: long unsigned int (size 0x8) + 3: size_t (size 0x8) -> 2: long unsigned int (size 0x8) + 4: int (size 0x4) + 5: const int (size 0x4) -> 4: int (size 0x4) + 6: volatile const int (size 0x4) -> 5: const int (size 0x4) -> 4: int (size 0x4) + 7: long long int (size 0x8) + 8: long double (size 0x10) + 9: int * (size 0x8) -> 4: int (size 0x4) + a: int *restrict (size 0x8) -> 9: int * (size 0x8) -> 4: int (size 0x4) + b: const int * (size 0x8) -> 5: const int (size 0x4) -> 4: int (size 0x4) + c: const int *restrict (size 0x8) -> b: const int * (size 0x8) -> 5: const int (size 0x4) -> 4: int (size 0x4) + d: INTP (size 0x8) -> 9: int * (size 0x8) -> 4: int (size 0x4) + e: const INTP (size 0x8) -> d: INTP (size 0x8) -> 9: int * (size 0x8) -> 4: int (size 0x4) + f: void (size 0x0) + 10: void (*) (size_t, int *restrict, const int *restrict) (size 0x0) + */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 7 } } */ + +/* type id 9, b have POINTER type. */ +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + +/* type id 5, e have CONST qualifier. */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + +/* type id a, c have RESTRICT qualifier. */ +/* { dg-final { scan-assembler-times "\[\t \]0x36000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + +/* type id 6 has VOLATILE qualifier. */ +/* { dg-final { scan-assembler-times "\[\t \]0x2e000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +#include "stddef.h" + +const volatile int a = 5; +int *restrict b; + +const int * i; +int const * j; + +typedef int * INTP; +const INTP int_p; + +void foo (size_t n, int *restrict p, const int *restrict q) +{ + while (n-- > 0) + *p++ = *q++; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-2.c new file mode 100644 index 0000000..4f328f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-2.c @@ -0,0 +1,30 @@ +/* Test compilation of stubs with various expressions involving const + qualifier. + + In this testcase, a single CTF record for const int is expected. A total of + two const qualifier CTF records are expected (const int and const struct + s1). */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + +struct mystruct +{ + struct + { + int a; + const int b; + } s1; + char * name; +} my_a; + +struct s1 +{ + int i; + const int ci; +} s; + +const struct s1 cs; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-3.c new file mode 100644 index 0000000..97317a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-3.c @@ -0,0 +1,25 @@ +/* Test compilation of stubs with various expressions involving const and + volatile qualifiers. + + In this testcase, it is expected to have const and volatile CTF + records. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"unsigned char.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2e000000\[\t \]+\[^\n\]*ctt_info" 5 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 3 } } */ +/* Two arrays. */ +/* { dg-final { scan-assembler-times "\[\t \]0x12000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + + +const volatile unsigned char vicar = 11; + +const volatile unsigned char * vicarage = &vicar; + +volatile float vilify[2]; + +const volatile char victor = 'Y'; + +const volatile char vindictive[2]; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-4.c new file mode 100644 index 0000000..c1633ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-4.c @@ -0,0 +1,23 @@ +/* Test compilation of stubs with various qualifiers - const, restrict and + volatile. + + CTF records for CVR qualifiers are no-name records. In this testcase, there + is 1 const qualifier. 1 more no-name CTF record corresponds to the CTF + pointer record. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +typedef const struct howto_struct howto_type; + +typedef struct entry +{ + int addend; + howto_type *howto; +} how_ent; + +how_ent hent; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-1.c new file mode 100644 index 0000000..1ad5f25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-1.c @@ -0,0 +1,7 @@ +/* Verify that CTF debug info can co-exist with dwarf. */ +/* { dg-do compile } */ +/* { dg-options "-gctf -gdwarf -dA" } */ +/* { dg-final { scan-assembler "0xdff2.*CTF preamble magic number" } } */ + +void func (void) +{ } diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-2.c new file mode 100644 index 0000000..df2c1eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-debug-2.c @@ -0,0 +1,7 @@ +/* Verify that CTF debug info can co-exist with dwarf. */ +/* { dg-do compile } */ +/* { dg-options "-gdwarf -gctf -dA" } */ +/* { dg-final { scan-assembler "0xdff2.*CTF preamble magic number" } } */ + +void func (void) +{ } diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-1.c new file mode 100644 index 0000000..9693544 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-1.c @@ -0,0 +1,21 @@ +/* CTF generation for enums. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"RED.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"GREEN.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"BLUE.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"YELLOW.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "cte_value" 4} } */ + + +enum foo_color +{ + RED, + GREEN, + BLUE, + YELLOW +}; + +enum foo_color my_color; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-2.c new file mode 100644 index 0000000..fd8aaec --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-enum-2.c @@ -0,0 +1,27 @@ +/* CTF generation for enums. + + CTF represents enum values with an int32_t. For enum values not + representable with int32_t data type, the compiler skips adding CTF for + them. This will be fixed soon in the CTF format. + TBD_CTF_REPRESENTATION_LIMIT. + + In this testcase, CTF for enumerator GFS_MONOTONIC will not be generated. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"GFS_MONOTONIC.0\"\[\t \]+\[^\n\]*ctf_string" 0 } } */ +/* { dg-final { scan-assembler-times "ascii \"GFS_RUNTIME.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"GFS_STATIC.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "cte_value" 2} } */ + + +enum gomp_schedule_type +{ + GFS_RUNTIME, + GFS_STATIC, + GFS_MONOTONIC = 0x80000000U +}; + +enum gomp_schedule_type gsch_type; + diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c new file mode 100644 index 0000000..a683113 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c @@ -0,0 +1,25 @@ +/* CTF is not generated for entities not at file-scope. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"SFOO.0\"\[\t \]+\[^\n\]*ctf_string" 0 } } */ +/* { dg-final { scan-assembler-times "ascii \"gfoo.0\"\[\t \]+\[^\n\]*ctf_string" 0 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +int foo (int n) +{ + typedef struct { int a[n]; } SFOO; + + SFOO a; + __attribute__ ((noinline)) SFOO gfoo (void) { return a; } + + a.a[0] = 1; + a.a[9] = 2; + + SFOO b; + b = gfoo (); + + return b.a[0] == 1 && b.a[9] == 2; +} + diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-float-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-float-1.c new file mode 100644 index 0000000..9e24b45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-float-1.c @@ -0,0 +1,16 @@ +/* Tests for CTF float base types. + - Verify that there is a single record for the base types. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "ascii \"float.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"double.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"long double.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +float a; +float b = 33; + +double c = 44; +double d = 45; + +long double e; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-1.c new file mode 100644 index 0000000..fdec743 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-1.c @@ -0,0 +1,40 @@ +/* CTF forward type is generated for forward declarations of types in C. + + Check that the ctf-kind of CTF_K_FOWARD type is CTF_K_STRUCT or CTF_K_UNION. + For forward types, the compiler encodes the CTF kind in the ctt_type field. + CTF_K_FORWARD is used as the CTF type as usual in the ctt_info. */ + +/* Note - A value of 6 in "ctt_size or ctt_type" appears twice in this + testcase. This might be misconstrued as 2 CTK_K_FORWARD records of struct + type. The second assembler tag is due to a ref type in a CVR CTF record. + TBD - perhaps a more robust string pattern is needed. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x26000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x6\[\t \]+\[^\n\]*ctt_size or ctt_type" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x7\[\t \]+\[^\n\]*ctt_size or ctt_type" 2 } } */ + +typedef struct __locale_struct +{ + struct __locale_data *__locales[13]; /* forward struct type. */ + + const int *__ctype_toupper; + const char *__names[13]; +} *__locale_t; + +typedef __locale_t locale_t; + +locale_t loc; + +typedef struct __inter_struct +{ + union __inter_data * __inters[13]; /* forward union type. */ + + const int * __ctype_kind; +} * __inter_t; + +typedef __inter_t inter_t; + +inter_t inter; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-2.c new file mode 100644 index 0000000..a3154f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-forward-2.c @@ -0,0 +1,16 @@ +/* CTF forward type is generated for forward declarations of enum types in C. + + Check that the ctf-kind of CTF_K_FOWARD type is CTF_K_ENUM. + For forward types, the compiler encodes the CTF kind in the ctt_type field. + CTF_K_FORWARD is used as the CTF type as usual in the ctt_info. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x26000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x8\[\t \]+\[^\n\]*ctt_size or ctt_type" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"vibgyor.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +enum vibgyor; + +char * (*get_color_name) (enum vibgyor); diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-func-index-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-func-index-1.c new file mode 100644 index 0000000..86ca795 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-func-index-1.c @@ -0,0 +1,25 @@ +/* CTF function index sub-section. + + A function index sub-section in the CTF section contains the offset to the + string name of the global function symbols. The number of entries in the + func info section and the func index section are always the same. + + In this testcase, 2 records in the function index section are expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "funcinfo_name" 2 } } */ +/* { dg-final { scan-assembler-times "funcinfo_func_type" 2 } } */ +/* { dg-final { scan-assembler-times "ascii \"bar.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +int foo (void) +{ + return 0; +} + +int bar (int a) +{ + return 33 + a; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-1.c new file mode 100644 index 0000000..cc1a600a --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-1.c @@ -0,0 +1,24 @@ +/* CTF generation of function pointers. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "\[\t \]0x16000001\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x16000002\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x16000003\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"__foo_fn.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"destroy.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"func.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +int (*func) (int *, char); + +typedef int (*__foo_fn) (void *__cookie, char *__buf, int __nbytes); + +typedef struct object +{ + int myint; + char mychar; + void (*destroy)(struct object *); +} object_t; + +object_t myobj; +__foo_fn fooit; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-2.c new file mode 100644 index 0000000..a4a1104 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-2.c @@ -0,0 +1,22 @@ +/* CTF generation of function pointers. + + In this testcase, there is a single function type expected for two + different function pointer types. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "\[\t \]0x16000001\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"rcu_callback_t.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"func.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct callback_head { + struct callback_head *next; + void (*func) (struct callback_head *head); +} __attribute__ (( aligned (sizeof (void *)))); +#define rcu_head callback_head + +struct callback_head chead; + +typedef void (*rcu_callback_t) (struct rcu_head *head); + +rcu_callback_t rcb; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-3.c new file mode 100644 index 0000000..fe35d6c --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-3.c @@ -0,0 +1,21 @@ +/* CTF generation of function pointers. + + In this testcase, there is a single function type expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "\[\t \]0x16000001\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo_init_callback.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"fn.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct foo; + +typedef void (* foo_init_callback) (struct foo *f1); + +struct foo +{ + /* Function to call to initialize. */ + foo_init_callback fn; +}; + +struct foo f; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-4.c new file mode 100644 index 0000000..b8a7417 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-function-pointers-4.c @@ -0,0 +1,18 @@ +/* CTF generation of function pointers. + + In this testcase, Type de-duplication of function type is exercised. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "\[\t \]0x16000001\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"var_assign_func_t.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct variable; + +typedef struct variable *var_assign_func_t (struct variable *); + +typedef struct variable { + var_assign_func_t *assign_func; +} shell_var_t; + +shell_var_t a; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-functions-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-functions-1.c new file mode 100644 index 0000000..0b086a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-functions-1.c @@ -0,0 +1,34 @@ +/* CTF generation for functions with varargs or otherwise. + + In this testcase, it is expected to see one CTF_K_FUNCTION record with two + function arguments. The second function argument with a value of 0 + corresponds to the ellipsis. + + Example CTF section excerpt on x86_64 : + + .long 0x5 # ctt_name (name = format) + .long 0x16000002 # ctt_info (CTF_K_FUNCTION with 2 arguments) + .long 0x2 # ctt_size or ctt_type (return typeID) + .long 0x2 # dtu_argv (TypeID of the First argument) + .long 0 # dtu_argv (TypeID of the second argument) + .ascii "\0" # ctf_string + .ascii "int\0" # ctf_string + .ascii "format\0" # ctf_string + + */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x16000002\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "dtu_argv" 2 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*dtu_argv" 1 } } */ + +int foo (void); + +int bar (int); + +int * format (int * fmt, ...) +{ + return fmt; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-int-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-int-1.c new file mode 100644 index 0000000..8c68b2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-int-1.c @@ -0,0 +1,17 @@ +/* Tests for CTF integer base types. + - Verify that there is a single record for the base types. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"short int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"long int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +int a; +int b = 33; + +short int c = 44; +short int d = 45; + +long int e = 90; +long int f; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-objt-index-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-objt-index-1.c new file mode 100644 index 0000000..ee3481a --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-objt-index-1.c @@ -0,0 +1,30 @@ +/* CTF objext index sub-section. + + An object index sub-section in the CTF section contains the offset to the + string name of the global object symbols. The number of entries in the + obj info section and objt index section are always the same. + + In this testcase, 4 records in the object index section are expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "objtinfo_name" 4 } } */ +/* { dg-final { scan-assembler-times "objtinfo_var_type" 4 } } */ +/* { dg-final { scan-assembler-times "ascii \"a.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"b.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"a1.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"d_instance.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +static int b = 33; + +int a = 44; +int a1[2] = {22, 33}; + +struct d +{ + int d1; + int d2; +}; + +struct d d_instance; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-1.c new file mode 100644 index 0000000..e1fccec --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-1.c @@ -0,0 +1,26 @@ +/* CTF generation for pointer types. + + In this testcase, two CTF pointer type records are expected + - int * + - struct foo_struct * + */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"foo_struct.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + +int b = 44; +int * a = &b; + +struct foo_struct +{ + int bar_mem_1; + int bar_mem_2; + float d; + struct foo_struct *next; +}; + +struct foo_struct * node; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-2.c new file mode 100644 index 0000000..e36e5ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-pointers-2.c @@ -0,0 +1,25 @@ +/* CTF generation for pointer types. + + In this testcase, de-duplication of pointer types is exercised. The + compostition of structs in this testcase is such that when adding CTF for + pointer type (link), the pointed-to-type type already adds the pointer to + struct link. + + In this testcase, one CTF pointer type record is expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0xe000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +struct link; + +typedef struct items { + struct link * link; + int str; +} itemslist; + +itemslist il; + +struct link { struct link * next; }; + diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-preamble-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-preamble-1.c new file mode 100644 index 0000000..28547fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-preamble-1.c @@ -0,0 +1,11 @@ +/* Verify the CTF preamble in the CTF section. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler "0xdff2.*CTF preamble magic number" } } */ +/* { dg-final { scan-assembler "0x4.*CTF preamble version" } } */ +/* { dg-final { scan-assembler "0.*CTF preamble flags" } } */ + +void func (void) +{ +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-1.c new file mode 100644 index 0000000..0c51839 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-1.c @@ -0,0 +1,38 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + An explicit CTF type with kind CTF_K_UNKNOWN is created for types that do + not have representation in CTF. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf -dA" } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"unknown.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +/* { dg-require-effective-target libc_has_complex_functions } */ + +#include + +typedef float La_x86_64_xmm __attribute__ ((__vector_size__ (16))); +La_x86_64_xmm a1; + +/* GCC also supports complex integer data types. */ +complex char a; +complex signed char b; +complex unsigned char c; +complex short int d; +complex short unsigned int e; +complex int f; +complex unsigned int g; +complex long int h; +complex long unsigned int i; +complex long long int j; + +enum gomp_schedule_type +{ + GFS_RUNTIME, + GFS_STATIC, + GFS_MONOTONIC = 0x80000000U +}; + +enum gomp_schedule_type gsch_type; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c new file mode 100644 index 0000000..7c8b17d --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c @@ -0,0 +1,17 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + Skip IEEE interchange and extended formats for CTF generation. + + In this testcase, CTF records for types are not added as CTF has no + representation for IEEE interchange and extended formats. + + CTF records for variables do exist, however. The referenced type is + CTF_TYPE_NULLID. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ + +/* { dg-require-effective-target float16 } */ + +_Float16 f16; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-3.c new file mode 100644 index 0000000..394fa2f --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-3.c @@ -0,0 +1,20 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + Skip IEEE interchange and extended formats for CTF generation. + + In this testcase, CTF records for types are not added as CTF has no + representation for IEEE interchange and extended formats. + + CTF records for variables and pointer do exist, however. The referenced + type is CTF_TYPE_NULLID. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ + +/* { dg-require-effective-target float32 } */ +/* { dg-require-effective-target float32x } */ + +_Float32 f32; +_Float32x f32x; +_Float32 * f32p; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c new file mode 100644 index 0000000..f4374e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c @@ -0,0 +1,19 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + Skip IEEE interchange and extended formats for CTF generation. + + In this testcase, CTF records for types are not added as CTF has no + representation for IEEE interchange and extended formats. + + CTF records for variables and pointer do exist, however. The referenced + type is CTF_TYPE_NULLID. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ + +/* { dg-require-effective-target float64 } */ +/* { dg-require-effective-target float64x } */ + +_Float64 f64; +_Float64x f64x; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-5.c new file mode 100644 index 0000000..026f9e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-5.c @@ -0,0 +1,19 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + Skip IEEE interchange and extended formats for CTF generation. + + In this testcase, CTF records for types are not added as CTF has no + representation for IEEE interchange and extended formats. + + CTF records for variables and pointer do exist, however. The referenced + type is CTF_TYPE_NULLID. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ + +/* { dg-require-effective-target float128 } */ +/* { dg-require-effective-target float128x } */ + +_Float128 f128; +_Float128x f128x; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-6.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-6.c new file mode 100644 index 0000000..f2dbe08 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-6.c @@ -0,0 +1,18 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + Skip Decimal Floating Point format types for CTF generation. + + In this testcase, CTF records for types are not added as CTF has no + representation for Decimal floating point format. + + CTF records for variables do exist, however. The referenced type is + CTF_TYPE_NULLID. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf" } */ +/* { dg-require-effective-target dfp } */ + +_Decimal32 d32; +_Decimal64 d64; +_Decimal128 d128; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-7.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-7.c new file mode 100644 index 0000000..a9d86de --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-7.c @@ -0,0 +1,18 @@ +/* CTF does not have representation for some types at this time. These types + are skipped in the CTF generation phase in the compiler. + + Skip IEEE interchange and extended formats for CTF generation. + + In this testcase, CTF records for types are not added as CTF has no + representation for IEEE interchange and extended formats. This testcase + checks that CTF generation skips the 128-bit float gracefully, when code + generation is for a 32-bit environment. */ + +/* { dg-do compile } */ +/* { dg-options "-gctf -m32" } */ + +/* { dg-require-effective-target float128 } */ +/* { dg-require-effective-target float128x } */ + +_Float128 f128; +_Float128x f128x; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-8.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-8.c new file mode 100644 index 0000000..2413e91 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-8.c @@ -0,0 +1,27 @@ +/* CTF does not have representation for _Atomic qualifier. This qualifier is + skipped in the CTF generation phase in the compiler. + + In this testcase, CTF records for the _Atomic qualifier are not added as + CTF has no representation for it. CTF records for the underlying type are, + however, added. So, CTF records for typedef, const and the underlying + struct are expected. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1a000003\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ctm_name" 3 } } */ + +/* { dg-final { scan-assembler-times "ascii \"comp_type.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"comp_type_t.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"c1.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +typedef struct comp_type +{ + int a; + float b; + char c; +} comp_type_t; + +_Atomic const comp_type_t c1; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-str-table-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-str-table-1.c new file mode 100644 index 0000000..0a0f1f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-str-table-1.c @@ -0,0 +1,26 @@ +/* CTF String Table as generated by the compiler is expected to have only a + single empty string. Just an optimization by the compiler, it is not + mandated by the CTF format. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "ascii \".0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +union wait +{ + int w_status; + struct + { + int __w_termsig; + int __w_coredump; + } __wait_terminated; + struct + { + int __w_stopval; + int __w_stopsig; + } __wait_stopped; +}; + +typedef union { union wait * __uptr; int * iptr; } __WAIT_STATUS; + +__WAIT_STATUS waitstatus; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-1.c new file mode 100644 index 0000000..19711c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-1.c @@ -0,0 +1,25 @@ +/* Test compilation of struct type. + + In this testcase, two CTF_K_STRUCT records are expected + struct a : ctt_info = 0x1a000004 (4 field members) + struct b : ctt_into = 0x1a000002 (2 field members) +*/ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x1a000004\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1a000002\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ctm_name" 6 } } */ + +struct a +{ + int d1; + int d2; + float c; + struct b + { + int time; + int wall; + } b1; +} my_a; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-2.c new file mode 100644 index 0000000..09b4d2f --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-2.c @@ -0,0 +1,32 @@ +/* Test for compilation of self-referntial structs. + + Further, the compiler is expected to generate a single CTF struct type for + struct dmx_dtdef (due to Type de-duplication at CTF generation). */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "ascii \"dmx_dtdef.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"dtd_name.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"dtd_type.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"dmx_dtdef_t.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct link +{ + struct link * next; +} * s_link; + +typedef long dmx_id_t; + +typedef struct dmx_dtdef +{ + char * dtd_name; + dmx_id_t dtd_type; +} dmx_dtdef_t; + +typedef struct dmx_bundle +{ + dmx_id_t dmb_type; + dmx_dtdef_t * dmb_dtd; +} dmx_bundle_t; + +dmx_bundle_t dbt; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-1.c new file mode 100644 index 0000000..d6c6b6b --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-1.c @@ -0,0 +1,65 @@ +/* Test Compilation of mixed constructs containing structs and arrays. + + Further, the compiler is expected to generate a single CTF struct type for + struct cmodel (due to Type de-duplication at the time of CTF generation). + + const qualifier in fields of structs should be processed. It appears as a + no-name CTF record with appropriate ctt_info. In this testcase, there are + two const qualifiers - const char and const struct cmodel. However, due to + way the debug information is represented in DWARF die, 3 const qualifier + records appear in the CTF section. + + <1>: Abbrev Number: 14 (DW_TAG_typedef) + DW_AT_name : (indirect string, offset: 0x114): cmodel_t + DW_AT_type : <0x9a> + <1>: Abbrev Number: 13 (DW_TAG_const_type) + DW_AT_type : <0xe1> + <1>: Abbrev Number: 4 (DW_TAG_array_type) + DW_AT_type : <0xed> + DW_AT_sibling : <0x102> + + <2><101>: Abbrev Number: 0 + <1><102>: Abbrev Number: 13 (DW_TAG_const_type) + <103> DW_AT_type : <0xf2> + <1><107>: Abbrev Number: 15 (DW_TAG_variable) + <108> DW_AT_name : (indirect string, offset: 0x57): _models + <10f> DW_AT_type : <0x102> + <1><11d>: Abbrev Number: 0 + + This results in: + + _models -> e: const const cmodel_t [3] (size 0x30) -> d: const cmodel_t [3] (size 0x30) + + Deemed as acceptable for now. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ascii \"cmodel.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"cname.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"cpointer.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"cmodel_t.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +/* 3 const records are expected. */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 3 } } */ + +struct a +{ + int a1[2]; + struct { int b[3]; } a2; +}; + +struct a my_a; + +typedef struct cmodel +{ + const char *cname; + int ccode; + int cpointer; +} cmodel_t; + +static const cmodel_t _models[] = { + {"ILP32", 0, 4}, + {"LP64", 0, 8}, + {"", 0, 0} +}; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c new file mode 100644 index 0000000..9e698fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c @@ -0,0 +1,15 @@ +/* CTF generation for struct type in presence of DWARF2. + + In case of DWARF2, the data member location is an expression containing + the location. CTF generation feeds off DWARF dies; this testcase tests + that the location expr is handled. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA -gdwarf-2" } */ + +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctm_offset" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*ctm_offset" 1 } } */ + +static struct ranges {int from, to;} lim_regs[] = {{ 16, 7}, { 16, 6}, { 20, 7},{ 20, 6}}; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-1.c new file mode 100644 index 0000000..22005ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* This tests the following scenario: + + 1. struct foo; + 2. struct foo *a_foo; + 3. struct foo { int bar; }; + 4. void baz (struct foo *f) { f->bar = 0; } + + At 2. a forward for struct foo is generated and at 3. the struct + type is fully defined. When a pointer to foo is encountered at 4., + an additional CTF type for the completed struct shall be emitted as + well. The linker will deduplicate both types. */ + +struct foo; +struct foo *a_foo; +struct foo { int bar; }; +void baz (struct foo *f) { f->bar = 0; } + +/* { dg-final { scan-assembler-times "\[\t \]\"bar.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-2.c new file mode 100644 index 0000000..569e5e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-pointer-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* This tests the following scenario: + + 1. struct foo; + 2. struct foo *a_foo; + 3. struct foo { int bar; }; + 4. void baz (struct foo **f) { f->bar = 0; } + + At 2. a forward for struct foo is generated and at 3. the struct + type is fully defined. When a pointer to a pointer to foo is + encountered at 4., an additional CTF type for the completed struct + shall be emitted as well. The linker will deduplicate both + types. */ + +struct foo; +struct foo *a_foo; +struct foo { int bar; }; +void baz (struct foo **f) { (*f)->bar = 0; } + +/* { dg-final { scan-assembler-times "\[\t \]\"bar.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-1.c new file mode 100644 index 0000000..aa40ab0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-1.c @@ -0,0 +1,68 @@ +/* CTF_K_TYPEDEF record generation. + + In this testcase, 7 typedef records are expected. + + Further, the declared variables must be of type typedef + + Variables: + a -> 2: my_int (size 0x4) -> 1: int (size 0x4) + b -> 3: bar_int (size 0x4) -> 1: int (size 0x4) + c -> 4: foo_int (size 0x4) -> 1: int (size 0x4) + d -> 7: my_array (size 0x8) -> 5: struct (size 0x8) + e -> 9: CINT (size 0x4) -> 8: const int (size 0x4) -> 1: int (size 0x4) + f -> c: CINTP (size 0x8) -> b: const int * (size 0x8) -> a: const int (size 0x4) -> 1: int (size 0x4) + g -> f: my_node_t (size 0x8) -> d: struct my_node (size 0x8) + + There is no direct way to check that the variables are of type typedef. + So in this testcase, we simply check that: + 1. The typedef records are generated (Check for 7 specific ctt_info, and + check for the ascii strings for the typedef names). + 2. The ctv_typeidx are distinct (each pointing to a specfic unique type). + Note that if variables were not of type typedef, ctv_typeidx will not be + unique (type of a, b, c will all point to int); hence, the check. + */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x2a000000\[\t \]+\[^\n\]*ctt_info" 7 } } */ +/* { dg-final { scan-assembler-times "ascii \"my_int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"bar_int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo_int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"my_array.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"CINT.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"CINTP.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"my_node_t.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x9\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xa\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xc\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0xf\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ + +typedef int my_int; +typedef int bar_int; +typedef int foo_int; + +typedef struct { int a[2]; } my_array; + +typedef const int CINT; +typedef const int * CINTP; + +typedef struct my_node +{ + int flags; + char value; +} my_node_t; + +my_int a; +bar_int b; +foo_int c; + +my_array d; +CINT e = 3; +CINTP f = &e; + +my_node_t g; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-2.c new file mode 100644 index 0000000..8c9d3bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-2.c @@ -0,0 +1,20 @@ +/* CTF_K_TYPEDEF record generation. + + In this testcase, typedef of type void should be generated. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo_void_type.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"void.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +typedef void foo_void_type; + +struct bar +{ + int a; + foo_void_type *b; +}; + +struct bar c; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-3.c new file mode 100644 index 0000000..93d0845 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-3.c @@ -0,0 +1,24 @@ +/* Type de-duplication of CTF_K_TYPEDEF records. + + In this testcase, a single CTF record for typedef is expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo_type.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"foo.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +typedef struct foo foo_type; + +struct bar +{ + struct foo * f1; + foo_type * f2; +}; + +struct testme { + struct bar * b1; +}; + +struct testme * t1; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-1.c new file mode 100644 index 0000000..19e8f49 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +typedef struct my_int +{ + int upper; + int lower; + struct bitmask + { + int flags; + } my_mask; +} my_int_t; + +my_int_t mit; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-2.c new file mode 100644 index 0000000..deeb85a --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-2.c @@ -0,0 +1,17 @@ +/* Test compilation of typedef composition in structs. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +typedef struct +{ + int day, month, year; +} Date; + +typedef struct +{ + Date filedDate, fixedDate; + int severity; +} BugRef; + +BugRef CR2112; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-3.c new file mode 100644 index 0000000..6d6918b --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-typedef-struct-3.c @@ -0,0 +1,32 @@ +/* Test CTF generation for a typedef instantiation with CVR quals. + + Caveat: There is no direct way to test that the type of foo is + "const my_int_t" via scanning the assembly. This test instead + checks for the presence of some of the CTF constructs involved + individually. Specifically, it checks for CTF const record and + CTF typedef record. + + Variables: + foo -> 4: const my_int_t (size 0x8) -> 3: my_int_t (size 0x8) -> 1: struct my_int (size 0x8) + + Types: + 1: struct my_int (size 0x8) + 2: int (size 0x4) + 3: my_int_t (size 0x8) -> 1: struct my_int (size 0x8) + 4: const my_int_t (size 0x8) -> 3: my_int_t (size 0x8) -> 1: struct my_int (size 0x8) +*/ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*ctv_typeidx" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x32000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +typedef struct my_int +{ + int upper; + int lower; +} my_int_t; + +const my_int_t foo = {10, 20}; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-union-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-union-1.c new file mode 100644 index 0000000..929d532 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-union-1.c @@ -0,0 +1,14 @@ +/* CTF generation for union type. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1e000004\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ctm_name" 4 } } */ + +union c +{ + int c1; + int c2; + int c3; + int c4; +} my_u_c; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-1.c new file mode 100644 index 0000000..8c3ab10 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-1.c @@ -0,0 +1,25 @@ +/* CTF generation for global variables. + + In this testcase, 7 records in the variable info section are expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ctv_name" 7 } } */ + +float var1; +double var2; +long double var3; + +char ascii = 'a'; + +int a = 33; +int a1[2] = {22, 33}; + +struct d +{ + int d1; + int d2; +}; + +struct d d_instance; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-2.c new file mode 100644 index 0000000..75c3ed7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-2.c @@ -0,0 +1,16 @@ +/* CTF generation for static variables inside a function. + + In this testcase, CTF record for bstatic is NOT expected. CTF generation + is only carried out for variables at file-scope or global-scope. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "ctv_name" 0 } } */ +/* { dg-final { scan-assembler-times "ascii \"bstatic.0\"\[\t \]+\[^\n\]*ctf_string" 0 } } */ + +int foo (int a) +{ + static int bstatic = 3; + return a + bstatic; +} diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp new file mode 100644 index 0000000..46055f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2002-2019 Free Software Foundation, Inc. + +# This program 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 of the License, or +# (at your option) any later version. +# +# This program 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Disable on ptx (in sync with DWARF testsuite) +if { [istarget nvptx-*-*] } { + return +} + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish -- cgit v1.1 From c01760bc548ba79bc9ac15168b27fe7aabcb19ae Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 29 Jun 2021 09:33:24 +0200 Subject: tree-optimization/101242 - fix reverse graph entry detection This avoids detecting random unrelated nodes as possible entries to not backwards reachable regions of the SLP graph. Instead explicitely add the problematic nodes. This temporary XFAILs gcc.dg/vect/pr67790.c until I get the permute propagation adjusted to when it needs more than one optimistic iteration. 2021-06-29 Richard Biener PR tree-optimization/101242 * tree-vect-slp.c (vect_slp_build_vertices): Force-add PHIs with not represented initial values as leafs. * gcc.dg/vect/bb-slp-pr101242.c: New testcase. * gcc.dg/vect/pr67790.c: XFAIL scan for zero VEC_PERM_EXPR. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101242.c | 38 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/pr67790.c | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr101242.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101242.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101242.c new file mode 100644 index 0000000..d885446 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101242.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast" } */ + +typedef struct { + double real; + double imag; +} complex; +typedef struct { + complex e[3][3]; +} su3_matrix; +su3_matrix check_su3_c; +double check_su3_ar, check_su3_ari, check_su3_max; +int arireturn(); +int check_su3() { + check_su3_ar = check_su3_c.e[0][0].real * check_su3_c.e[1][0].real + + check_su3_c.e[0][0].imag * check_su3_c.e[1][0].imag + + check_su3_c.e[0][1].real * check_su3_c.e[1][1].real + + check_su3_c.e[0][1].imag * check_su3_c.e[1][1].imag + + check_su3_c.e[0][2].real * check_su3_c.e[1][2].real + + check_su3_c.e[0][2].imag * check_su3_c.e[1][2].imag; + check_su3_max = check_su3_c.e[0][0].real * check_su3_c.e[2][0].real + + check_su3_c.e[0][0].imag * check_su3_c.e[2][0].imag + + check_su3_c.e[0][1].real * check_su3_c.e[2][1].real + + check_su3_c.e[0][1].imag * check_su3_c.e[2][1].imag + + check_su3_c.e[0][2].real * check_su3_c.e[2][2].real + + check_su3_c.e[0][2].imag * check_su3_c.e[2][2].imag; + check_su3_ari = check_su3_ar; + if (check_su3_ari) + check_su3_max = check_su3_c.e[1][0].real * check_su3_c.e[2][0].real + + check_su3_c.e[1][0].imag * check_su3_c.e[2][0].imag + + check_su3_c.e[1][1].real * check_su3_c.e[2][1].real + + check_su3_c.e[1][1].imag * check_su3_c.e[2][1].imag + + check_su3_c.e[1][2].real * check_su3_c.e[2][2].real + + check_su3_c.e[1][2].imag * check_su3_c.e[2][2].imag; + if (check_su3_max) + arireturn(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr67790.c b/gcc/testsuite/gcc.dg/vect/pr67790.c index 32eacd9..0555d41 100644 --- a/gcc/testsuite/gcc.dg/vect/pr67790.c +++ b/gcc/testsuite/gcc.dg/vect/pr67790.c @@ -38,4 +38,4 @@ int main() } /* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail *-*-* } } } */ -- cgit v1.1 From 2dfc0f2203e875621f4aeb2e2496aaeb9a2dc05b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 29 Jun 2021 11:30:23 +0200 Subject: Refactor SLP permute opt propagation This rewrites the SLP permute opt propagation to elide the visited bit for an incoming permute of -1 as well as allowing the initial propagation to take more than one iteration before starting on materialization. As we still lack propagation in the reverse direction I've added gcc.dg/vect/bb-slp-71.c and a stopgap to restrict "any" permute handling to the supported cases. 2021-06-29 Richard Biener * tree-vect-slp.c (slpg_vertex::visited): Remove. (vect_slp_perms_eq): Handle -1 permutes. (vect_optimize_slp): Rewrite permute propagation. * gcc.dg/vect/pr67790.c: Un-XFAIL. * gcc.dg/vect/bb-slp-71.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-71.c | 32 ++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/pr67790.c | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-71.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-71.c b/gcc/testsuite/gcc.dg/vect/bb-slp-71.c new file mode 100644 index 0000000..6816511 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-71.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +int a[4], b[4]; + +void __attribute__((noipa)) +foo(int x, int y) +{ + int tem0 = x + 1; + int tem1 = y + 2; + int tem2 = x + 3; + int tem3 = y + 4; + a[0] = tem0 + b[1]; + a[1] = tem1 + b[0]; + a[2] = tem2 + b[2]; + a[3] = tem3 + b[3]; +} + +int main() +{ + check_vect (); + + b[0] = 10; + b[1] = 14; + b[2] = 18; + b[3] = 22; + foo (-1, -3); + if (a[0] != 14 || a[1] != 9 || a[2] != 20 || a[3] != 23) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr67790.c b/gcc/testsuite/gcc.dg/vect/pr67790.c index 0555d41..32eacd9 100644 --- a/gcc/testsuite/gcc.dg/vect/pr67790.c +++ b/gcc/testsuite/gcc.dg/vect/pr67790.c @@ -38,4 +38,4 @@ int main() } /* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */ -- cgit v1.1 From a96d8d67d0073a7031c0712bc3fb7759417b2125 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 29 Jun 2021 10:52:58 -0400 Subject: Fix MINUS_EXPR relations. Flesh out and correct relations for both wrapping and non-wrapping values. gcc/ PR tree-optimization/101254 * range-op.cc (operator_minus::op1_op2_relation_effect): Check for wrapping/non-wrapping when setting the result range. gcc/testsuite * gcc.dg/pr101254.c: New. --- gcc/testsuite/gcc.dg/pr101254.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101254.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101254.c b/gcc/testsuite/gcc.dg/pr101254.c new file mode 100644 index 0000000..b2460ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101254.c @@ -0,0 +1,27 @@ +/* PR tree-optimization/101254 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fwrapv" } */ + +int +foo (long long imin, long long imax) +{ + if (imin > imax) + return 0; + else if (imax - imin < 0 || (imax - imin) + 1 < 0) + return 0; + return 1; +} + +int +main () +{ + long long imax = __LONG_LONG_MAX__; + long long imin = -imax - 1; + if (!foo (-10, 10)) + __builtin_abort (); + if (foo (-10, imax)) + __builtin_abort (); + if (foo (imin, imax)) + __builtin_abort (); + return 0; +} -- cgit v1.1 From f6bc9d9bddad7f9e3aad939bb6750770ac67f003 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 30 Jun 2021 11:44:00 +0000 Subject: [testsuite]: Add missing dg-add-options float16 to gcc.dg/debug/ctf/ctf-skip-types-2.c The test already checks dg-require-effective-target float16, but this is not sufficient to use the flags needed, if any. This patch makes the test pass on arm. 2021-06-30 Christophe Lyon gcc/testsuite/ * gcc.dg/debug/ctf/ctf-skip-types-2.c: Add dg-add-options float16. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c index 7c8b17d..79d5cb2 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-2.c @@ -13,5 +13,6 @@ /* { dg-options "-gctf" } */ /* { dg-require-effective-target float16 } */ +/* { dg-add-options float16 } */ _Float16 f16; -- cgit v1.1 From e61ffa201403e3814a43b176883e176716b1492f Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 30 Jun 2021 09:39:04 -0400 Subject: analyzer: eliminate enum binding_key [PR95006] I rewrote the way the analyzer's region_model tracks the state of memory in GCC 11 (in 808f4dfeb3a95f50f15e71148e5c1067f90a126d), which introduced a store with a binding_map class, mapping binding keys to symbolic values. The GCC 11 implementation of binding keys has an enum binding_kind, which can be "default" vs "direct"; the idea being that direct bindings take priority over default bindings, where the latter could be used to represent e.g. a zero-fill of a buffer, and the former expresses those subregions that have since been touched. This doesn't work well: it doesn't express the idea of filling different subregions with different values, or a memset that only touches part of a buffer, leading to numerous XFAILs in the memset test cases (and elsewhere). As preparatory work towards tracking uninitialized values, this patch eliminates the enum binding_kind, so that all bindings have equal weight; the order in which they happen is all that matters. If a write happens which partially overwrites an existing binding, the new code can partially overwrite a binding, potentially punching a hole so that an existing binding is split into two parts. The patch adds some new classes: - a new "bits_within_svalue" symbolic value to support extracting parts of an existing value when its binding is partially clobbered - a new "repeated_svalue" symbolic value to better express filling a region with repeated copies of a symbolic value (e.g. constant zero) - a new "sized_region" region to express accessing a subregion with a symbolic size in bytes and it rewrites e.g. how memset is implemented, so that we can precisely track which bits in a region have not been touched. That said, the patch doesn't actually implement "uninitialized" values; I'm saving that for a followup. gcc/analyzer/ChangeLog: PR analyzer/95006 * analyzer.h (class repeated_svalue): New forward decl. (class bits_within_svalue): New forward decl. (class sized_region): New forward decl. (get_field_at_bit_offset): New forward decl. * engine.cc (exploded_graph::get_or_create_node): Validate the merged state. (exploded_graph::maybe_process_run_of_before_supernode_enodes): Validate the states at each stage. * program-state.cc (program_state::validate): Validate m_region_model. * region-model-impl-calls.cc (region_model::impl_call_memset): Replace special-case logic for handling constant sizes with a call to fill_region of a sized_region with the given fill value. * region-model-manager.cc (maybe_undo_optimize_bit_field_compare): Drop DK_direct. (region_model_manager::maybe_fold_sub_svalue): Fold element-based subregions of an initial value into initial values of an element. Fold subvalues of repeated svalues. (region_model_manager::maybe_fold_repeated_svalue): New. (region_model_manager::get_or_create_repeated_svalue): New. (get_bit_range_for_field): New. (get_byte_range_for_field): New. (get_field_at_byte_range): New. (region_model_manager::maybe_fold_bits_within_svalue): New. (region_model_manager::get_or_create_bits_within): New. (region_model_manager::get_sized_region): New. (region_model_manager::log_stats): Update for addition of m_repeated_values_map, m_bits_within_values_map, and m_sized_regions. * region-model.cc (region_model::validate): New. (region_model::on_assignment): Drop enum binding_kind. (region_model::get_initial_value_for_global): Likewise. (region_model::get_rvalue_for_bits): Replace body with call to get_or_create_bits_within. (region_model::get_capacity): Handle RK_SIZED. (region_model::set_value): Drop enum binding_kind. (region_model::fill_region): New. (region_model::get_representative_path_var_1): Handle RK_SIZED. * region-model.h (visitor::visit_repeated_svalue): New. (visitor::visit_bits_within_svalue): New. (region_model_manager::get_or_create_repeated_svalue): New decl. (region_model_manager::get_or_create_bits_within): New decl. (region_model_manager::get_sized_region): New decl. (region_model_manager::maybe_fold_repeated_svalue): New decl. (region_model_manager::maybe_fold_bits_within_svalue): New decl. (region_model_manager::repeated_values_map_t): New typedef. (region_model_manager::m_repeated_values_map): New field. (region_model_manager::bits_within_values_map_t): New typedef. (region_model_manager::m_bits_within_values_map): New field. (region_model_manager::m_sized_regions): New field. (region_model::fill_region): New decl. * region.cc (region::get_base_region): Handle RK_SIZED. (region::base_region_p): Likewise. (region::get_byte_size_sval): New. (get_field_at_bit_offset): Make non-static. (region::calc_offset): Move implementation of cases to get_relative_concrete_offset vfunc implementations. Handle RK_SIZED. (region::get_relative_concrete_offset): New. (decl_region::get_svalue_for_initializer): Drop enum binding_kind. (field_region::get_relative_concrete_offset): New, from region::calc_offset. (element_region::get_relative_concrete_offset): Likewise. (offset_region::get_relative_concrete_offset): Likewise. (sized_region::accept): New. (sized_region::dump_to_pp): New. (sized_region::get_byte_size): New. (sized_region::get_bit_size): New. * region.h (enum region_kind): Add RK_SIZED. (region::dyn_cast_sized_region): New. (region::get_byte_size): Make virtual. (region::get_bit_size): Likewise. (region::get_byte_size_sval): New decl. (region::get_relative_concrete_offset): New decl. (field_region::get_relative_concrete_offset): New decl. (element_region::get_relative_concrete_offset): Likewise. (offset_region::get_relative_concrete_offset): Likewise. (class sized_region): New. * store.cc (binding_kind_to_string): Delete. (binding_key::make): Drop enum binding_kind. (binding_key::dump_to_pp): Delete. (binding_key::cmp_ptrs): Drop enum binding_kind. (bit_range::contains_p): New. (byte_range::dump): New. (byte_range::contains_p): New. (byte_range::cmp): New. (concrete_binding::dump_to_pp): Drop enum binding_kind. (concrete_binding::cmp_ptr_ptr): Likewise. (symbolic_binding::dump_to_pp): Likewise. (symbolic_binding::cmp_ptr_ptr): Likewise. (binding_map::apply_ctor_val_to_range): Likewise. (binding_map::apply_ctor_pair_to_child_region): Likewise. (binding_map::get_overlapping_bindings): New. (binding_map::remove_overlapping_bindings): New. (binding_cluster::validate): New. (binding_cluster::bind): Drop enum binding_kind. (binding_cluster::bind_compound_sval): Likewise. (binding_cluster::purge_region): Likewise. (binding_cluster::zero_fill_region): Reimplement in terms of... (binding_cluster::fill_region): New. (binding_cluster::mark_region_as_unknown): Drop enum binding_kind. (binding_cluster::get_binding): Likewise. (binding_cluster::get_binding_recursive): Likewise. (binding_cluster::get_any_binding): Likewise. (binding_cluster::maybe_get_compound_binding): Reimplement. (binding_cluster::get_overlapping_bindings): Delete. (binding_cluster::remove_overlapping_bindings): Reimplement in terms of binding_map::remove_overlapping_bindings. (binding_cluster::can_merge_p): Update for removal of enum binding_kind. (binding_cluster::on_unknown_fncall): Drop enum binding_kind. (binding_cluster::maybe_get_simple_value): Likewise. (store_manager::get_concrete_binding): Likewise. (store_manager::get_symbolic_binding): Likewise. (store::validate): New. (store::set_value): Drop enum binding_kind. (store::zero_fill_region): Reimplement in terms of... (store::fill_region): New. (selftest::test_binding_key_overlap): Drop enum binding_kind. * store.h (enum binding_kind): Delete. (binding_kind_to_string): Delete decl. (binding_key::make): Drop enum binding_kind. (binding_key::dump_to_pp): Make pure virtual. (binding_key::get_kind): Delete. (binding_key::mark_deleted): Delete. (binding_key::mark_empty): Delete. (binding_key::is_deleted): Delete. (binding_key::is_empty): Delete. (binding_key::binding_key): Delete. (binding_key::impl_hash): Delete. (binding_key::impl_eq): Delete. (binding_key::m_kind): Delete. (bit_range::get_last_bit_offset): New. (bit_range::contains_p): New. (byte_range::contains_p): New. (byte_range::operator==): New. (byte_range::get_start_byte_offset): New. (byte_range::get_next_byte_offset): New. (byte_range::get_last_byte_offset): New. (byte_range::as_bit_range): New. (byte_range::cmp): New. (concrete_binding::concrete_binding): Drop enum binding_kind. (concrete_binding::hash): Likewise. (concrete_binding::operator==): Likewise. (concrete_binding::mark_deleted): New. (concrete_binding::mark_empty): New. (concrete_binding::is_deleted): New. (concrete_binding::is_empty): New. (default_hash_traits::empty_zero_p): Make false. (symbolic_binding::symbolic_binding): Drop enum binding_kind. (symbolic_binding::hash): Likewise. (symbolic_binding::operator==): Likewise. (symbolic_binding::mark_deleted): New. (symbolic_binding::mark_empty): New. (symbolic_binding::is_deleted): New. (symbolic_binding::is_empty): New. (binding_map::remove_overlapping_bindings): New decl. (binding_map::get_overlapping_bindings): New decl. (binding_cluster::validate): New decl. (binding_cluster::bind): Drop enum binding_kind. (binding_cluster::fill_region): New decl. (binding_cluster::get_binding): Drop enum binding_kind. (binding_cluster::get_binding_recursive): Likewise. (binding_cluster::get_overlapping_bindings): Delete. (store::validate): New decl. (store::set_value): Drop enum binding_kind. (store::fill_region): New decl. (store_manager::get_concrete_binding): Drop enum binding_kind. (store_manager::get_symbolic_binding): Likewise. * svalue.cc (svalue::cmp_ptr): Handle SK_REPEATED and SK_BITS_WITHIN. (svalue::extract_bit_range): New. (svalue::maybe_fold_bits_within): New. (constant_svalue::maybe_fold_bits_within): New. (unknown_svalue::maybe_fold_bits_within): New. (unaryop_svalue::maybe_fold_bits_within): New. (repeated_svalue::repeated_svalue): New. (repeated_svalue::dump_to_pp): New. (repeated_svalue::accept): New. (repeated_svalue::all_zeroes_p): New. (repeated_svalue::maybe_fold_bits_within): New. (bits_within_svalue::bits_within_svalue): New. (bits_within_svalue::dump_to_pp): New. (bits_within_svalue::maybe_fold_bits_within): New. (bits_within_svalue::accept): New. (bits_within_svalue::implicitly_live_p): New. (compound_svalue::maybe_fold_bits_within): New. * svalue.h (enum svalue_kind): Add SK_REPEATED and SK_BITS_WITHIN. (svalue::dyn_cast_repeated_svalue): New. (svalue::dyn_cast_bits_within_svalue): New. (svalue::extract_bit_range): New decl. (svalue::maybe_fold_bits_within): New vfunc decl. (region_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (region_svalue::key_t::is_empty): Likewise. (default_hash_traits::empty_zero_p): Make false. (constant_svalue::maybe_fold_bits_within): New. (unknown_svalue::maybe_fold_bits_within): New. (poisoned_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (poisoned_svalue::key_t::is_empty): Likewise. (default_hash_traits::empty_zero_p): Make false. (setjmp_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (setjmp_svalue::key_t::is_empty): Likewise. (default_hash_traits::empty_zero_p): Make false. (unaryop_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (unaryop_svalue::key_t::is_empty): Likewise. (unaryop_svalue::maybe_fold_bits_within): New. (default_hash_traits::empty_zero_p): Make false. (binop_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (binop_svalue::key_t::is_empty): Likewise. (default_hash_traits::empty_zero_p): Make false. (sub_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (sub_svalue::key_t::is_empty): Likewise. (default_hash_traits::empty_zero_p): Make false. (class repeated_svalue): New. (is_a_helper ::test): New. (struct default_hash_traits): New. (class bits_within_svalue): New. (is_a_helper ::test): New. (struct default_hash_traits): New. (widening_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (widening_svalue::key_t::is_empty): Likewise. (default_hash_traits::empty_zero_p): Make false. (compound_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE. (compound_svalue::key_t::is_empty): Likewise. (compound_svalue::maybe_fold_bits_within): New. (default_hash_traits::empty_zero_p): Make false. gcc/testsuite/ChangeLog: PR analyzer/95006 * gcc.dg/analyzer/clobbers-1.c: New test. * gcc.dg/analyzer/clobbers-2.c: New test. * gcc.dg/analyzer/data-model-1.c (test_26): Mark xfail as fixed. (test_28): Likewise. (test_52): Likewise. Add coverage for end of buffer. * gcc.dg/analyzer/explode-1.c: Add leak warning. * gcc.dg/analyzer/memset-1.c (test_3): Mark xfail as fixed. (test_4): Use char. Mark xfail as fixed. (test_6b): New. (test_7): Mark xfail as fixed. Add coverage for start of buffer. (test_8): New. (test_9): New. * gcc.dg/analyzer/memset-CVE-2017-18549-1.c: New test. * gcc.dg/analyzer/symbolic-8.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/clobbers-1.c | 98 +++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/clobbers-2.c | 72 +++++++++++++ gcc/testsuite/gcc.dg/analyzer/data-model-1.c | 24 ++--- gcc/testsuite/gcc.dg/analyzer/explode-1.c | 2 +- gcc/testsuite/gcc.dg/analyzer/memset-1.c | 118 ++++++++++++++++++--- .../gcc.dg/analyzer/memset-CVE-2017-18549-1.c | 107 +++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/symbolic-8.c | 11 ++ 7 files changed, 399 insertions(+), 33 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/clobbers-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/clobbers-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/symbolic-8.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c b/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c new file mode 100644 index 0000000..824dbd4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c @@ -0,0 +1,98 @@ +#include "analyzer-decls.h" + +struct foo +{ + int i; + int j; +}; + +struct coord +{ + int x; + int y; + int z; +}; + +struct foo g; + +void test_1 (void) +{ + g.i = 42; + if (g.j) + __analyzer_eval (g.j); /* { dg-warning "TRUE" } */ + else + __analyzer_eval (g.j); /* { dg-warning "FALSE" } */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} + +void test_2 (void) +{ + struct foo f; + f.i = 42; + if (f.j) + __analyzer_eval (f.j); /* { dg-warning "TRUE" } */ + else + __analyzer_eval (f.j); /* { dg-warning "FALSE" } */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} + +void test_3 (struct foo *p) +{ + struct foo f = *p; + f.i = 42; + if (f.j) + __analyzer_eval (f.j); /* { dg-warning "TRUE" } */ + else + __analyzer_eval (f.j); /* { dg-warning "FALSE" } */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} + +void test_4 (struct coord *p) +{ + struct coord f = *p; + f.x = 42; + __analyzer_eval (f.y == p->y); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.z == p->z); /* { dg-warning "TRUE" } */ +} + +struct s5 +{ + char arr[8]; +}; + +void test_5 (struct s5 *p) +{ + struct s5 f = *p; + f.arr[3] = 42; + __analyzer_eval (f.arr[0] == p->arr[0]); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[1] == p->arr[1]); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[2] == p->arr[2]); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[3] == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[4] == p->arr[4]); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[5] == p->arr[5]); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[6] == p->arr[6]); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[7] == p->arr[7]); /* { dg-warning "TRUE" } */ +} + +struct s6 +{ + int before; /* Give "arr" a nonzero offset. */ + struct foo arr[4]; + int after; +}; + +void test_6 (struct s6 *p, struct foo *q) +{ + struct s6 f = *p; + f.arr[1] = *q; + __analyzer_eval (f.before == p->before); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[0].i == p->arr[0].i); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[0].j == p->arr[0].j); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[1].i == q->i); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[1].j == q->j); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[2].i == p->arr[2].i); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[2].j == p->arr[2].j); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[3].i == p->arr[3].i); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.arr[3].j == p->arr[3].j); /* { dg-warning "TRUE" } */ + __analyzer_eval (f.after == p->after); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/clobbers-2.c b/gcc/testsuite/gcc.dg/analyzer/clobbers-2.c new file mode 100644 index 0000000..9a88349 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/clobbers-2.c @@ -0,0 +1,72 @@ +#include "analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; +extern void bzero (void *s, size_t n); +extern void *memset(void *s, int c, size_t n); + +void test_1 (void) +{ + char arr[16]; + bzero (arr, sizeof (arr)); + __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[7] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[8] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[9] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */ + + /* Clobber in the middle (with prefix and suffix). */ + arr[8] = 42; + __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[7] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[8] == 0); /* { dg-warning "FALSE" } */ + __analyzer_eval (arr[8] == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[9] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */ +} + +void test_2 (void) +{ + char arr[16]; + bzero (arr, sizeof (arr)); + __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */ + + /* Clobber at the front (suffix, but no prefix). */ + arr[0] = 42; + __analyzer_eval (arr[0] == 0); /* { dg-warning "FALSE" } */ + __analyzer_eval (arr[0] == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */ +} + +void test_3 (void) +{ + char arr[16]; + bzero (arr, sizeof (arr)); + __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[14] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */ + + /* Clobber at the end (prefix, but no suffix). */ + arr[15] = 42; + __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[14] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "FALSE" } */ + __analyzer_eval (arr[15] == 42); /* { dg-warning "TRUE" } */ +} + +void test_4 (void) +{ + char arr[16]; + bzero (arr, sizeof (arr)); + __analyzer_eval (arr[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "TRUE" } */ + + /* Exact overlap, no prefix or suffix. */ + memset (arr, 1, 16); + __analyzer_eval (arr[0] == 0); /* { dg-warning "FALSE" } */ + __analyzer_eval (arr[15] == 0); /* { dg-warning "FALSE" } */ + __analyzer_eval (arr[0] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (arr[15] == 1); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index 4a62a0e..34932da 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -503,9 +503,7 @@ void test_26 (struct coord *p, struct coord *q) the dest value. */ *p = *q; __analyzer_eval (p->x); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (p->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): should have been overwritten with q->y + __analyzer_eval (p->y == 17); /* { dg-warning "TRUE" } */ __analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ @@ -522,19 +520,11 @@ void test_27 (struct coord *p) void test_28 (struct coord *p) { memset (p, 0, sizeof (struct coord) * 10); - __analyzer_eval (p[0].x == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): - __analyzer_eval (p[0].y == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): + __analyzer_eval (p[0].x == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[0].y == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[9].x == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): - __analyzer_eval (p[9].y == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - // TODO(xfail): + __analyzer_eval (p[9].x == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[9].y == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */ @@ -1035,8 +1025,8 @@ void test_52 (struct big b) { struct big d; memcpy (&d, &b, sizeof (struct big)); - __analyzer_eval (b.ia[0] == d.ia[0]); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ + __analyzer_eval (b.ia[0] == d.ia[0]); /* { dg-warning "TRUE" } */ + __analyzer_eval (b.ia[1023] == d.ia[1023]); /* { dg-warning "TRUE" } */ } void test_53 (const char *msg) diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-1.c b/gcc/testsuite/gcc.dg/analyzer/explode-1.c index 6b62e8e..f48408e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/explode-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/explode-1.c @@ -12,7 +12,7 @@ void test (void) { void *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8; void **pp; - while (get ()) + while (get ()) /* { dg-warning "leak" } */ { switch (get ()) { diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-1.c index 5748aa1..94c5a1b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/memset-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/memset-1.c @@ -36,22 +36,16 @@ void test_3 (int val) { char buf[256]; memset (buf, 'A', 256); - /* We currently merely mark such regions as "unknown", so querying - values within them yields UNKNOWN when ideally it would be TRUE. */ - __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */ + __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */ } /* A "memset" with unknown value. */ -void test_4 (int val) +void test_4 (char val) { char buf[256]; memset (buf, val, 256); - /* We currently merely mark such regions as "unknown", so querying - values within them yields UNKNOWN when ideally it would be TRUE. */ - __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */ + __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" } */ } /* A "memset" with unknown num bytes. */ @@ -98,6 +92,14 @@ void test_6 (int val) __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */ } +void test_6b (int val) +{ + char buf[256]; + memset (buf, 'A', sizeof (buf)); + memset (buf, 'B', get_zero ()); + __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */ +} + /* A "memset" of known size that's not the full buffer. */ void test_7 (void) @@ -105,10 +107,96 @@ void test_7 (void) char buf[256]; buf[128] = 'A'; memset (buf, 0, 128); - /* We currently merely mark the whole region as "unknown", so querying - values within them yields UNKNOWN. */ - __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */ - __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */ + __analyzer_eval (buf[0] == '\0'); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" } */ +} + +void test_8 (void) +{ + char buf[20]; + memset (buf + 0, 0, 1); + memset (buf + 1, 1, 1); + memset (buf + 2, 2, 1); + memset (buf + 3, 3, 1); + memset (buf + 4, 4, 2); + memset (buf + 6, 6, 2); + memset (buf + 8, 8, 4); + memset (buf + 12, 12, 8); + __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[3] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[4] == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[5] == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[6] == 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[7] == 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[8] == 8); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[9] == 8); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[10] == 8); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[11] == 8); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[12] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[13] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[14] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[15] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[16] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[17] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[18] == 12); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[19] == 12); /* { dg-warning "TRUE" } */ +} + +/* Various overlapping memset calls with different sizes and values. */ + +void test_9 (void) +{ + char buf[8]; + memset (buf, 0, 8); + __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[2] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[3] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[4] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[5] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */ + + memset (buf + 1, 1, 4); + __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[2] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[3] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[4] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[5] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */ + + memset (buf + 2, 2, 4); + __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[4] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[5] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */ + + memset (buf + 4, 3, 3); + __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[4] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[5] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[6] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */ + + memset (buf + 0, 4, 3); + __analyzer_eval (buf[0] == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[1] == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[2] == 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[4] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[5] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[6] == 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c new file mode 100644 index 0000000..9dd1139 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c @@ -0,0 +1,107 @@ +/* This is a very simplified version of CVE-2017-18549, + a use of uninitialized padding values affecting the Linux kernel + (and thus GPLv2). + + It was fixed by e.g. 342ffc26693b528648bdc9377e51e4f2450b4860 on linux-4.13.y + in linux-stable. */ + +#include "analyzer-decls.h" +#include + +typedef unsigned int __u32; +typedef unsigned int u32; +typedef unsigned char u8; + +/* Adapted from include/uapi/linux/types.h */ + +#define __bitwise +typedef __u32 __bitwise __le32; + +/* Adapted from drivers/scsi/aacraid/aacraid.h */ + +#define AAC_SENSE_BUFFERSIZE 30 + +struct aac_srb_reply +{ + __le32 status; + __le32 srb_status; + __le32 scsi_status; + __le32 data_xfer_length; + __le32 sense_data_size; + u8 sense_data[AAC_SENSE_BUFFERSIZE]; + + /* Manually added to help verify the fix. */ + u8 padding[2]; +}; + +#define ST_OK 0 +#define SRB_STATUS_SUCCESS 0x01 + +/* Adapted from drivers/scsi/aacraid/commctrl.c */ + +static int aac_send_raw_srb(/* [...snip...] */) +{ + u32 byte_count = 0; + + /* [...snip...] */ + + struct aac_srb_reply reply; + + reply.status = ST_OK; + + /* [...snip...] */ + + reply.srb_status = SRB_STATUS_SUCCESS; + reply.scsi_status = 0; + reply.data_xfer_length = byte_count; + reply.sense_data_size = 0; + memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE); + + /* [...snip...] */ + + __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ + /* TODO: the following should be detected as uninitialized, when + that diagnostic is reimplemented. */ + __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "UNKNOWN" } */ +} + +static int aac_send_raw_srb_fixed(/* [...snip...] */) +{ + u32 byte_count = 0; + + /* [...snip...] */ + + struct aac_srb_reply reply; + + /* This is the fix. */ + memset(&reply, 0, sizeof(reply)); + + reply.status = ST_OK; + + /* [...snip...] */ + + reply.srb_status = SRB_STATUS_SUCCESS; + reply.scsi_status = 0; + reply.data_xfer_length = byte_count; + reply.sense_data_size = 0; + memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE); + + /* [...snip...] */ + + __analyzer_eval (reply.status == ST_OK); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.srb_status == SRB_STATUS_SUCCESS); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.scsi_status == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.data_xfer_length == byte_count); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-8.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-8.c new file mode 100644 index 0000000..f9c3596 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-8.c @@ -0,0 +1,11 @@ +/* Merger where "arr" has two different symbolic bindings. */ + +void test (int i, int j, int flag) +{ + int arr[16]; + + if (flag) + arr[i] = 42; + else + arr[j] = 17; +} -- cgit v1.1 From aa31ae697087940c60d0bb2fa60c951750bb65c4 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Wed, 30 Jun 2021 15:13:50 -0700 Subject: testsuite: Add missing dg-add-options to CTF testcase ctf-skip-types-4.c The test already has the appropriate dg-require-effective-target, but requires the dg-add-options to use the flags needed, if any. This patch fixes the failure of this testcase on powerpc64. 2021-06-30 Indu Bhagat gcc/testsuite/ * gcc.dg/debug/ctf/ctf-skip-types-4.c: Add dg-add-options float64 and float64x. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c index f4374e6..7033121 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c @@ -14,6 +14,8 @@ /* { dg-require-effective-target float64 } */ /* { dg-require-effective-target float64x } */ +/* { dg-add-options float64 } */ +/* { dg-add-options float64x } */ _Float64 f64; _Float64x f64x; -- cgit v1.1 From b0ab968999c9af88d45acf552ca673ef3960306a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 1 Jul 2021 09:45:02 +0200 Subject: dwarf2out: Handle COMPOUND_LITERAL_EXPR in loc_list_from_tree_1 [PR101266] In this case dwarf2out_decl is called from the FEs with GENERIC but not yet gimplified expressions in it. As loc_list_from_tree_1 has an exhaustive list of tree codes it wants to handle and for checking asserts no other codes makes it in, we should handle even GENERIC trees that shouldn't be valid in GIMPLE. The following patch handles COMPOUND_LITERAL_EXPR by hnadling it like the underlying VAR_DECL temporary. Verified the emitted DWARF is correct (but unoptimized, we emit DW_OP_lit1 DW_OP_lit1 DW_OP_minus for the upper bound). 2021-07-01 Jakub Jelinek PR debug/101266 * dwarf2out.c (loc_list_from_tree_1): Handle COMPOUND_LITERAL_EXPR. * gcc.dg/pr101266.c: New test. --- gcc/testsuite/gcc.dg/pr101266.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101266.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101266.c b/gcc/testsuite/gcc.dg/pr101266.c new file mode 100644 index 0000000..d198089 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101266.c @@ -0,0 +1,8 @@ +/* PR debug/101266 */ +/* { dg-do compile } */ +/* { dg-options "-g -O2" } */ + +void +foo (int (*p)[(int){1}]) +{ +} -- cgit v1.1 From 7d8211603a3d04384812b481b0ae01205a287a72 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 30 Jun 2021 16:28:50 +0200 Subject: tree-optimization/101178 - handle VEC_PERM in SLP permute propagation This adds handling of VEC_PERM nodes to SLP permute propagation. Previously VEC_PERM acted as forced materialization of incoming permutes since it is a good place to do that (with the constraint of those only appearing for two-operator nodes). The following patch, in addition to supporting (but not forcing) this, enables VEC_PERM nodes acting as "any" permute on the outgoing side since they also can consume arbitrary permutes on that side. This again (meh) changes how we represent permutes and materialization on the graph vertices now explicitely having the common incoming permute as well as an outgoing permute and in case both are different the vertex acts as materialization point of the incoming permute. 2021-06-30 Richard Biener PR tree-optimization/101178 * tree-vect-slp.c (slpg_vertex::materialize): Remove. (slpg::perm_in): Add. (slpg::get_perm_in): Remove. (slpg::get_perm_materialized): Add. (vect_optimize_slp): Handle VEC_PERM nodes more optimally during permute propagation and materialization. * gcc.dg/vect/bb-slp-72.c: New testcase. * gcc.dg/vect/bb-slp-73.c: Likewise. * gcc.dg/vect/bb-slp-74.c: Likewise. --- gcc/testsuite/gcc.dg/vect/bb-slp-72.c | 29 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/bb-slp-73.c | 29 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/bb-slp-74.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-72.c create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-73.c create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-74.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-72.c b/gcc/testsuite/gcc.dg/vect/bb-slp-72.c new file mode 100644 index 0000000..5b243fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-72.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +double x[2], y[2], z[2], w[2]; + +void __attribute__((noipa)) foo () +{ + double tem0 = x[1] + y[1]; + double tem1 = x[0] - y[0]; + double tem2 = z[1] * tem0; + double tem3 = z[0] * tem1; + z[0] = tem2 - w[0]; + z[1] = tem3 + w[1]; +} + +int main() +{ + check_vect (); + + x[0] = 1.; x[1] = 2.; + y[0] = 7.; y[1] = -5.; + z[0] = 2.; z[1] = 3.; + w[0] = 9.; w[1] = -5.; + foo (); + if (z[0] != -18. || z[1] != -17.) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-73.c b/gcc/testsuite/gcc.dg/vect/bb-slp-73.c new file mode 100644 index 0000000..d4c8a51 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-73.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +double x[2], y[2], z[2], w[2]; + +void __attribute__((noipa)) foo () +{ + double tem0 = x[1] + y[1]; + double tem1 = x[0] - y[0]; + double tem2 = z[1] * tem0; + double tem3 = z[0] * tem1; + z[0] = tem2 - w[1]; + z[1] = tem3 + w[0]; +} + +int main() +{ + check_vect (); + + x[0] = 1.; x[1] = 2.; + y[0] = 7.; y[1] = -5.; + z[0] = 2.; z[1] = 3.; + w[0] = 9.; w[1] = -5.; + foo (); + if (z[0] != -4. || z[1] != -3.) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-74.c b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c new file mode 100644 index 0000000..d3d5a02 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +double a[2], b[2], c[2]; + +void __attribute__((noipa)) foo () +{ + double tem0 = a[1] + b[1]; + double tem1 = a[0] - b[0]; + c[0] = 2. * tem0; + c[1] = 5. * tem1; +} + +int main() +{ + check_vect (); + + a[0] = 1.; a[1] = 3.; + b[0] = -5.; b[1] = 13.; + foo (); + if (c[0] != 32. || c[1] != 30.) + __builtin_abort (); + return 0; +} + +/* We'd like to see at most one VEC_PERM_EXPR, not one for a blend + and one for a permute materialized somewhere else. But addsub + pattern recog can likely get in the way here. */ +/* { dg-final { scan-tree-dump-times " \[^ \]\+ = VEC_PERM_EXPR" 1 "slp2" } } */ -- cgit v1.1 From a3aaba68405751bae3f630669515b7ecdf77efa6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 1 Jul 2021 10:35:38 +0200 Subject: tree-optimization/100778 - fix placement of trapping vectorized ops This avoids placing possibly trapping vectorized operations where the corresponding scalar operation was possibly not executed. 2021-01-07 Richard Biener PR tree-optimization/100778 * tree-vect-slp.c (vect_schedule_slp_node): Do not place trapping vectorized ops ahead of their scalar BB. * gcc.dg/torture/pr100778.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr100778.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr100778.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100778.c b/gcc/testsuite/gcc.dg/torture/pr100778.c new file mode 100644 index 0000000..7997f2f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100778.c @@ -0,0 +1,31 @@ +/* { dg-do run { target *-*-*gnu* } } */ +/* { dg-additional-options "-fno-tree-sink -fno-math-errno -ftree-vectorize -D_GNU_SOURCE" } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include + +double a[2]; +void __attribute__((noipa)) foo () +{ + double x = a[0]; + double y = a[1]; + double norm = __builtin_sqrt (x*x + y*y); + if (norm > 1.) + { + x = x / norm; + y = y / norm; + } + a[0] = x; + a[1] = y; +} + +int main() +{ + feenableexcept (FE_INVALID); + a[0] = 0.; + a[1] = 0.; + foo (); + if (a[0] != 0. || a[1] != 0.) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 4a87605938428f6c4c62d5b92cfc183cd2b2554e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 1 Jul 2021 11:16:01 +0200 Subject: tree-optimization/101278 - handle self-use in DSE analysis DSE store classification short-cuts the to-be classified stmt itself from chaining but fails to first check whether the store uses itself which can be the case when it is a call with the LHS also passed by value as argument. 2021-07-01 Richard Biener PR tree-optimization/101278 * tree-ssa-dse.c (dse_classify_store): First check for uses, then ignore stmt for chaining purposes. * gcc.dg/torture/pr101278.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101278.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101278.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101278.c b/gcc/testsuite/gcc.dg/torture/pr101278.c new file mode 100644 index 0000000..1d25658 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101278.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ + +struct X { int counter; }; + +struct X __attribute__((noipa)) foo (struct X x) +{ + x.counter++; + if (x.counter == 5) + __builtin_exit (0); + return x; +} + +int +main () +{ + struct X x; + x.counter = 0; + for (int i = 0; i < 10; ++i) + x = foo (x); + __builtin_abort (); +} -- cgit v1.1 From 0a77c07b9b3fe83679358c3ef57721e09e2ad5fb Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 1 Jul 2021 12:49:45 +0200 Subject: tree-optimization/101280 - revise interchange fix for PR101173 The following revises the original fix for PR101173 to correctly check for a reversed dependence rather than disallowing a zero distance. It also adds a check from TSVC which asks for this kind of interchange (but with a valid dependence). 2021-07-01 Richard Biener PR tree-optimization/101280 PR tree-optimization/101173 * gimple-loop-interchange.cc (tree_loop_interchange::valid_data_dependences): Revert previous change and instead correctly handle DDR_REVERSED_P dependence. * gcc.dg/tree-ssa/loop-interchange-16.c: New testcase. --- .../gcc.dg/tree-ssa/loop-interchange-16.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c new file mode 100644 index 0000000..781555e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c @@ -0,0 +1,22 @@ +/* PR/101280 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-linterchange-details" } */ + +void dummy (double *, double *); +#define LEN_2D 32 +double aa[LEN_2D][LEN_2D], bb[LEN_2D][LEN_2D]; +double s231(int iterations) +{ +// loop interchange +// loop with data dependency + for (int nl = 0; nl < 100*(iterations/LEN_2D); nl++) { + for (int i = 0; i < LEN_2D; ++i) { + for (int j = 1; j < LEN_2D; j++) { + aa[j][i] = aa[j - 1][i] + bb[j][i]; + } + } + dummy(aa[0],bb[0]); + } +} + +/* { dg-final { scan-tree-dump "loops interchanged" "linterchange" } } */ -- cgit v1.1 From 4546f423ecff96f223adfbec4963d2ff17f27c7b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 2 Jul 2021 12:57:06 +0200 Subject: tree-optimization/101293 - further enhance LIMs ref canonicalization This makes sure to handle MEM[p + 4] and MEM[p].j with j at offset 4 as the same ref in store motion. For hashing we need to be more restrictive in what we handle since there's no poly-int handlers for inchash. For comparison we can compare poly_offsets directly. 2021-07-02 Richard Biener PR tree-optimization/101293 * tree-ssa-loop-im.c (mem_ref_hasher::equal): Compare MEM_REF bases with combined offsets. (gather_mem_refs_stmt): Hash MEM_REFs as if their offset were combined with the rest of the offset. * gcc.dg/tree-ssa/ssa-lim-15.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c new file mode 100644 index 0000000..5efb956 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c @@ -0,0 +1,18 @@ +/* PR/101293 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-lim2-details" } */ + +struct X { int i; int j; }; + +void foo(struct X *x, int n) +{ + for (int i = 0; i < n; ++i) + { + int *p = &x->j; + int tem = *p; + x->j += tem * i; + } +} + +/* Make sure LIM can handle unifying MEM[x, 4] and MEM[x].j */ +/* { dg-final { scan-tree-dump "Executing store motion" "lim2" } } */ -- cgit v1.1 From 18d0fad77b580d1ac64ed04d94fd3c9795687b91 Mon Sep 17 00:00:00 2001 From: David Faust Date: Tue, 1 Jun 2021 09:22:59 -0700 Subject: BTF: Support for BTF_KIND_FLOAT Add BTF_KIND_FLOAT, a new BTF type kind which has recently stabilized in the linux kernel [1]. This kind is used for encoding floating point types, and is of particular use when generating BTF for some s390 arch-specific kernel headers. Also update some BTF tests which previously used floating point types to check correct behavior for types with no BTF representation. [1]: https://github.com/torvalds/linux/commit/b1828f0b04828aa8cccadf00a702f459caefeed9 include/ChangeLog: * btf.h (struct btf_type): Update bit usage comment. (BTF_INFO_KIND): Update bit mask. (BTF_KIND_FLOAT): New define. (BTF_KIND_MAX): Update. gcc/ChangeLog: * btfout.c (get_btf_kind): Support BTF_KIND_FLOAT. (btf_asm_type): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-float-1.c: New test. * gcc.dg/debug/btf/btf-function-3.c: Use different unrepresentable type. * gcc.dg/debug/btf/btf-struct-2.c: Likewise. * gcc.dg/debug/btf/btf-variables-2.c: Likewise. --- gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c new file mode 100644 index 0000000..6876df0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-float-1.c @@ -0,0 +1,20 @@ +/* Tests for BTF floating point type kinds. We expect a single record for each + of the base types: float, double and long double. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x10000000\[\t \]+\[^\n\]*btt_info" 3 } } */ + +/* { dg-final { scan-assembler-times "ascii \"float.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"double.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"long double.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +float a; +float b = 1.5f; + +double c; +double d = -99.9; + +long double e; +long double f = 1000.01; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c index 35f96a2..c83b823 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-3.c @@ -16,7 +16,7 @@ /* Exactly one function parameter should have type_id=0. */ /* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*farg_type" 1 } } */ -int foo (int a, float f, long b) +int foo (int a, float __attribute__((__vector_size__(16))) f, long b) { return 0; } diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c index 24514fc..c3aff09 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c @@ -14,6 +14,6 @@ struct with_float { int a; - float f; + float __attribute__((__vector_size__(16))) f; char c; } instance; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c index 0f9742e..db0bdd7 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-2.c @@ -16,7 +16,7 @@ /* { dg-final { scan-assembler-times "ascii \"myst.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ int foo; -float bar; +float __attribute__((__vector_size__(16))) bar; int baz[10]; struct st -- cgit v1.1 From 84f7bab89279ca1234fef88929c74caeda8cb55e Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 30 Jun 2021 14:15:53 -0400 Subject: Fix build_gt and build_lt for signed 1 bit values. Signed 1 bit values have a range of [-1, 0] but neither (0 - 1) nor (-1 + 1) can be represented. For signed values, add or subtract -1 as appropriate. PR tree-optimization/101223 gcc/ * range-op.cc (build_lt): Add -1 for signed values. (built_gt): Subtract -1 for signed values. gcc/testsuite/ * gcc.dg/pr101223.c: New. --- gcc/testsuite/gcc.dg/pr101223.c | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101223.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101223.c b/gcc/testsuite/gcc.dg/pr101223.c new file mode 100644 index 0000000..6d5a247 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101223.c @@ -0,0 +1,44 @@ +/* PR tree-optimization/101223 */ +/* { dg-do run } */ +/* { dg-options "-O2 " } */ + +struct { + int a : 1; +} b; +int c = 1, d; +int foo1() { + for (; d < 2; d++) { + int e = ~c, f = 0, g; + if (e) { + f = c; + g = b.a; + b.a = f; + if (b.a >= g) + __builtin_abort(); + } + c = f; + b.a = g; + } + return 0; +} + +int foo2() { + for (; d < 2; d++) { + int e = ~c, f = 0, g; + if (e) { + f = c; + g = b.a; + b.a = f; + if (g <= b.a) + __builtin_abort(); + } + c = f; + b.a = g; + } + return 0; +} +int main () +{ + return foo1() + foo2(); +} + -- cgit v1.1 From 52c3fdf3e4780f75297515d3c2a3dae9b36586ba Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 2 Jul 2021 10:03:48 -0700 Subject: Don't use vec_duplicate on vector in CTOR expansion Since vec_duplicate only works on scalar, don't use it on vector in store constructor expansion. gcc/ PR middle-end/101294 * expr.c (store_constructor): Don't use vec_duplicate on vector. gcc/testsuite/ PR middle-end/101294 * gcc.dg/pr101294.c: New test. --- gcc/testsuite/gcc.dg/pr101294.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101294.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101294.c b/gcc/testsuite/gcc.dg/pr101294.c new file mode 100644 index 0000000..ca59b35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101294.c @@ -0,0 +1,15 @@ +/* PR middle-end/101294 */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-mavx" { target avx } } */ + +typedef __attribute__((__vector_size__ (sizeof (unsigned long long)))) unsigned long long U; +typedef __attribute__((__vector_size__ (4 * sizeof (unsigned long long)))) unsigned long long V; + +extern U x; + +void +foo (void) +{ + x = __builtin_shufflevector ((U){}, (V){}, 3); +} -- cgit v1.1 From 981351e87b7ad7a0660d4f3a34614172f3d8376b Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Thu, 1 Jul 2021 10:49:27 -0400 Subject: testsuite: Disable BTF and CTF testsuite on AIX. CTF utilizes DWARF sections, but it is a distinct debugging format. The CTF support in GCC is not implemented as a separate debugging format. AIX supports DWARF but not CTF section. The GCC testsuite test for target support of a debugging format checks if GCC itself emits an error message, not if the debugging output compiles correctly. Because CTF is not a distinct debugging format, GCC does not distinguish support for targets and does not have the ability to produce an error message. This patch skips the CTF and BTF debug directories, and explicitly reports that AIX doesn't support CTF. Currently the dejagnu code to skip multiple debugging levels for CTF does not ensure that CTF is a supported debugging format. The patch also shifts the CTF options logic to within the test that CTF debug format is supported. Bootstrapped on powerpc-ibm-aix7.2.3.0 and powerpc64le-linux. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf.exp: Skip on AIX. * gcc.dg/debug/ctf/ctf.exp: Skip on AIX. * lib/gcc-dg.exp (gcc-dg-target-supports-debug-format): AIX doesn't support CTF. (gcc-dg-debug-runtest): Move CTF support within target support format test. --- gcc/testsuite/gcc.dg/debug/btf/btf.exp | 5 +++++ gcc/testsuite/gcc.dg/debug/ctf/ctf.exp | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf.exp b/gcc/testsuite/gcc.dg/debug/btf/btf.exp index e72a2be..e173515 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf.exp +++ b/gcc/testsuite/gcc.dg/debug/btf/btf.exp @@ -24,6 +24,11 @@ if { [istarget nvptx-*-*] } { return } +if { [istarget "powerpc-ibm-aix*"] } { + set torture_execute_xfail "powerpc-ibm-aix*" + return +} + # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp index 46055f8..0b650ed 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp @@ -24,6 +24,11 @@ if { [istarget nvptx-*-*] } { return } +if { [istarget "powerpc-ibm-aix*"] } { + set torture_execute_xfail "powerpc-ibm-aix*" + return +} + # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { -- cgit v1.1 From ccb4e0774b3e5859ea1d7f1864b02fa5826c4a79 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 5 Jul 2021 08:38:29 +0200 Subject: testsuite/101299 - add missing vect_double requires to bb-slp-74.c This should fix the FAIL of gcc.dg/vect/bb-slp-74.c on arm. 2021-07-05 Richard Biener PR testsuite/101299 * gcc.dg/vect/bb-slp-74.c: Add vect_double requires. --- gcc/testsuite/gcc.dg/vect/bb-slp-74.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-74.c b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c index d3d5a02..9c1ebb7 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-74.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-require-effective-target vect_double } */ #include "tree-vect.h" -- cgit v1.1 From 0ea47850bbb38ea81a34c503533d4dd0f3391f19 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Mon, 5 Jul 2021 11:33:45 +0000 Subject: testsuite: gcc.dg/debug/btf/btf-bitfields-3.c requires -fno-short-enums PR debug/101321 arm-eabi uses -fshort-enums by default while arm-linux-gnueabi* do not, like most (all?) other targets, but this test relies -fno-short-enums. Fix it by forcing -fno-short-enums. 2021-07-05 Christophe Lyon PR debug/101321 gcc/testsuite/ * gcc.dg/debug/btf/btf-bitfields-3.c: Add -fno-short-enums. --- gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c index 440623c3..5e68416 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c @@ -15,7 +15,7 @@ */ /* { dg-do compile } */ -/* { dg-options "-O0 -gbtf -dA" } */ +/* { dg-options "-O0 -gbtf -dA -fno-short-enums" } */ /* Enum with 4 members. */ /* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */ -- cgit v1.1 From 7d6979197274a662da7bdc564314afe8415865c1 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 12 Jun 2021 19:45:20 -0700 Subject: Port most of the A CMP 0 ? A : -A to match To improve phiopt and be able to remove abs_replacement, this ports most of "A CMP 0 ? A : -A" from fold_cond_expr_with_comparison to match.pd. There is a few extra changes that are needed to remove the "A CMP 0 ? A : -A" part from fold_cond_expr_with_comparison: * Need to handle (A - B) case * Need to handle UN* comparisons. I will handle those in a different patch. Note phi-opt-15.c test needed to be updated as we get ABSU now instead of not getting ABS. When ABSU was added phiopt was not updated even to use ABSU instead of not creating ABS. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: PR tree-optimization/101039 * match.pd (A CMP 0 ? A : -A): New patterns. * tree-ssa-phiopt.c (abs_replacement): Delete function. (tree_ssa_phiopt_worker): Don't call abs_replacement. Update comment about abs_replacement. gcc/testsuite/ChangeLog: PR tree-optimization/101039 * gcc.dg/tree-ssa/phi-opt-15.c: Update test to expect ABSU and still not expect ABS_EXPR. * gcc.dg/tree-ssa/phi-opt-23.c: New test. * gcc.dg/tree-ssa/phi-opt-24.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c | 4 ++- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c | 44 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c | 44 ++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c index ac3018e..6aec689 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-15.c @@ -9,4 +9,6 @@ foo (int i) return i; } -/* { dg-final { scan-tree-dump-not "ABS" "optimized" } } */ +/* We should not have ABS_EXPR but ABSU_EXPR instead. */ +/* { dg-final { scan-tree-dump-not "ABS_EXPR" "optimized" } } */ +/* { dg-final { scan-tree-dump "ABSU" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c new file mode 100644 index 0000000..ff658cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-23.c @@ -0,0 +1,44 @@ +/* { dg-options "-O2 -fdump-tree-phiopt" } */ + +int f0(int A) +{ +// A == 0? A : -A same as -A + if (A == 0) return A; + return -A; +} + +int f1(int A) +{ +// A != 0? A : -A same as A + if (A != 0) return A; + return -A; +} +int f2(int A) +{ +// A >= 0? A : -A same as abs (A) + if (A >= 0) return A; + return -A; +} +int f3(int A) +{ +// A > 0? A : -A same as abs (A) + if (A > 0) return A; + return -A; +} +int f4(int A) +{ +// A <= 0? A : -A same as -abs (A) + if (A <= 0) return A; + return -A; +} +int f5(int A) +{ +// A < 0? A : -A same as -abs (A) + if (A < 0) return A; + return -A; +} + +/* These should be optimized in phiopt1 but is confused by predicts. */ +/* { dg-final { scan-tree-dump-not "if" "phiopt1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c new file mode 100644 index 0000000..eb89dec --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-24.c @@ -0,0 +1,44 @@ +/* { dg-options "-O2 -fno-signed-zeros -fdump-tree-phiopt" } */ + +float f0(float A) +{ +// A == 0? A : -A same as -A + if (A == 0) return A; + return -A; +} + +float f1(float A) +{ +// A != 0? A : -A same as A + if (A != 0) return A; + return -A; +} +float f2(float A) +{ +// A >= 0? A : -A same as abs (A) + if (A >= 0) return A; + return -A; +} +float f3(float A) +{ +// A > 0? A : -A same as abs (A) + if (A > 0) return A; + return -A; +} +float f4(float A) +{ +// A <= 0? A : -A same as -abs (A) + if (A <= 0) return A; + return -A; +} +float f5(float A) +{ +// A < 0? A : -A same as -abs (A) + if (A < 0) return A; + return -A; +} + +/* These should be optimized in phiopt1 but is confused by predicts. */ +/* { dg-final { scan-tree-dump-not "if" "phiopt1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */ + -- cgit v1.1 From a3543b5e8002c033b2304d7ac1d1e58218eebb51 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Mon, 5 Jul 2021 17:28:24 -0700 Subject: CTF,BTF testsuite: Use -gdwarf-4 for restrict type qualifier [PR101283] DWARF DIEs do not contain DW_TAG_restrict_type when DWARF version is 2. CTF/BTF generation feeds off DWARF DIEs, and as such, CTF records of kind CTF_K_RESTRICT cease to be generated when DWARF version is 2. This patch fixes the failure of these testcases on Darwin by using an explicit -gdwarf-4 in the dg-options. This keeps the CTF record generation for restrict type qualifier tested. PR debug/101283 - Several tests fail on Darwin with -gctf/gbtf 2021-07-05 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/btf/btf-cvr-quals-1.c: Use -gdwarf-4 on Darwin targets. * gcc.dg/debug/ctf/ctf-cvr-quals-1.c: Likewise. --- gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c | 1 + gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c | 1 + 2 files changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c index 79e9f52..33e2f64 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c @@ -23,6 +23,7 @@ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ +/* { dg-options "-O0 -gbtf -gdwarf-4 -dA" { target { *-*-darwin* } } } */ /* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c index 9368d47..0137e9d 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c @@ -31,6 +31,7 @@ /* { dg-do compile ) */ /* { dg-options "-O0 -gctf -dA" } */ +/* { dg-options "-O0 -gctf -gdwarf-4 -dA" { target { *-*-darwin* } } } */ /* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 7 } } */ -- cgit v1.1 From 6d3bab5d5adb3e28ddb16c97b0831efdea23cf7d Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 6 Jul 2021 13:41:02 -0600 Subject: Improve warning suppression for inlined functions. Resolves: PR middle-end/98871 - Cannot silence -Wmaybe-uninitialized at declaration site PR middle-end/98512 - #pragma GCC diagnostic ignored ineffective in conjunction with alias attribute gcc/ChangeLog: * builtins.c (warn_string_no_nul): Remove %G. (maybe_warn_for_bound): Same. (warn_for_access): Same. (check_access): Same. (check_strncat_sizes): Same. (expand_builtin_strncat): Same. (expand_builtin_strncmp): Same. (expand_builtin): Same. (expand_builtin_object_size): Same. (warn_dealloc_offset): Same. (maybe_emit_free_warning): Same. * calls.c (maybe_warn_alloc_args_overflow): Same. (maybe_warn_nonstring_arg): Same. (maybe_warn_rdwr_sizes): Same. * expr.c (expand_expr_real_1): Remove %K. * gimple-fold.c (gimple_fold_builtin_strncpy): Remove %G. (gimple_fold_builtin_strncat): Same. * gimple-ssa-sprintf.c (format_directive): Same. (handle_printf_call): Same. * gimple-ssa-warn-alloca.c (pass_walloca::execute): Same. * gimple-ssa-warn-restrict.c (maybe_diag_overlap): Same. (maybe_diag_access_bounds): Same. Call gimple_location. (check_bounds_or_overlap): Same. * trans-mem.c (ipa_tm_scan_irr_block): Remove %K. Simplify. * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Remove %G. * tree-ssa-strlen.c (maybe_warn_overflow): Same. (maybe_diag_stxncpy_trunc): Same. (handle_builtin_stxncpy_strncat): Same. (maybe_warn_pointless_strcmp): Same. * tree-ssa-uninit.c (maybe_warn_operand): Same. gcc/testsuite/ChangeLog: * gcc.dg/Wobjsize-1.c: Prune expected output. * gcc.dg/Warray-bounds-71.c: New test. * gcc.dg/Warray-bounds-71.h: New test header. * gcc.dg/Warray-bounds-72.c: New test. * gcc.dg/Warray-bounds-73.c: New test. * gcc.dg/Warray-bounds-74.c: New test. * gcc.dg/Warray-bounds-75.c: New test. * gcc.dg/Wfree-nonheap-object-4.c: Adjust expected output. * gcc.dg/Wfree-nonheap-object-5.c: New test. * gcc.dg/Wfree-nonheap-object-6.c: New test. * gcc.dg/pragma-diag-10.c: New test. * gcc.dg/pragma-diag-9.c: New test. * gcc.dg/uninit-suppress_3.c: New test. * gcc.dg/pr79214.c: Xfail tests. * gcc.dg/tree-ssa/builtin-sprintf-warn-27.c: New test. * gcc.dg/format/c90-printf-1.c: Adjust expected output. --- gcc/testsuite/gcc.dg/Warray-bounds-71.c | 7 + gcc/testsuite/gcc.dg/Warray-bounds-71.h | 46 +++++++ gcc/testsuite/gcc.dg/Warray-bounds-72.c | 7 + gcc/testsuite/gcc.dg/Warray-bounds-73.c | 7 + gcc/testsuite/gcc.dg/Warray-bounds-74.c | 7 + gcc/testsuite/gcc.dg/Warray-bounds-75.c | 12 ++ gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c | 24 ++-- gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c | 46 +++++++ gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c | 49 +++++++ gcc/testsuite/gcc.dg/Wobjsize-1.c | 12 +- gcc/testsuite/gcc.dg/format/c90-printf-1.c | 2 +- gcc/testsuite/gcc.dg/pr79214.c | 22 ++-- gcc/testsuite/gcc.dg/pragma-diag-10.c | 20 +++ gcc/testsuite/gcc.dg/pragma-diag-9.c | 141 +++++++++++++++++++++ .../gcc.dg/tree-ssa/builtin-sprintf-warn-27.c | 20 +++ gcc/testsuite/gcc.dg/uninit-suppress_3.c | 98 ++++++++++++++ 16 files changed, 492 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-71.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-71.h create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-72.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-73.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-74.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-75.c create mode 100644 gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c create mode 100644 gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c create mode 100644 gcc/testsuite/gcc.dg/pragma-diag-10.c create mode 100644 gcc/testsuite/gcc.dg/pragma-diag-9.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c create mode 100644 gcc/testsuite/gcc.dg/uninit-suppress_3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-71.c b/gcc/testsuite/gcc.dg/Warray-bounds-71.c new file mode 100644 index 0000000..425bb12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-71.c @@ -0,0 +1,7 @@ +/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic + works at any call site in an inlining stack + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#define IGNORE '1' +#include "Warray-bounds-71.h" diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-71.h b/gcc/testsuite/gcc.dg/Warray-bounds-71.h new file mode 100644 index 0000000..89d1068 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-71.h @@ -0,0 +1,46 @@ +/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic + works at any call site in an inlining stack + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +int a[4]; + +void f1 (int *p, int i) +{ +#pragma GCC diagnostic push +#if IGNORE == '1' +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + p[i + 1] = 0; +#pragma GCC diagnostic pop +} + +void f2 (int *p, int i) +{ +#pragma GCC diagnostic push +#if IGNORE == '2' +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + f1 (p + 1, i + 1); +#pragma GCC diagnostic pop +} + +void f3 (int *p, int i) +{ +#pragma GCC diagnostic push +#if IGNORE == '3' +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + f2 (p + 1, i + 1); +#pragma GCC diagnostic pop +} + +void f4 (void) +{ +#pragma GCC diagnostic push +#if IGNORE == '4' +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + f3 (a, 1); +#pragma GCC diagnostic pop +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-72.c b/gcc/testsuite/gcc.dg/Warray-bounds-72.c new file mode 100644 index 0000000..eb3f664 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-72.c @@ -0,0 +1,7 @@ +/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic + works at any call site in an inlining stack + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#define IGNORE '2' +#include "Warray-bounds-71.h" diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-73.c b/gcc/testsuite/gcc.dg/Warray-bounds-73.c new file mode 100644 index 0000000..50e2083 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-73.c @@ -0,0 +1,7 @@ +/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic + works at any call site in an inlining stack + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#define IGNORE '3' +#include "Warray-bounds-71.h" diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-74.c b/gcc/testsuite/gcc.dg/Warray-bounds-74.c new file mode 100644 index 0000000..c59a876 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-74.c @@ -0,0 +1,7 @@ +/* Verify that -Warray-bounds suppression via #pragma GCC diagnostic + works at any call site in an inlining stack + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#define IGNORE '4' +#include "Warray-bounds-71.h" diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-75.c b/gcc/testsuite/gcc.dg/Warray-bounds-75.c new file mode 100644 index 0000000..306b176 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-75.c @@ -0,0 +1,12 @@ +/* Sanity test for Warray-bounds-7[1-4].c. Also verify the expected + inlining stack. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#include "Warray-bounds-71.h" + +// { dg-regexp "In function 'f1'," "In function f1" { target *-*-* } 0 } +// { dg-regexp "inlined from 'f2' at \[^\\n\\r\]+\[\\n\\r\]" "inlined from f2" { target *-*-* } 0 } +// { dg-regexp "inlined from 'f3' at \[^\\n\\r\]+\[\\n\\r\]" "inlined from f3" { target *-*-* } 0 } +// { dg-regexp "inlined from 'f4' at \[^\\n\\r\]+\[\\n\\r\]" "inlined from f4" { target *-*-* } 0 } +// { dg-message "Warray-bounds-71.h:\\d+:\\d+: warning: array subscript 6 is outside array bounds of 'int\\\[4]'" "warning" { target *-*-* } 0 } diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c index a7d9212..e459b24 100644 --- a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c +++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-4.c @@ -10,23 +10,23 @@ struct A void *p; }; -void f0 (struct A *p, void *q) { p->p = q; } -void f1 (struct A *p, void *q) { f0 (p, q); } -void f2 (struct A *p, void *q) { f1 (p, q); } +static void f0 (struct A *p, void *q) { p->p = q; } +static void f1 (struct A *p, void *q) { f0 (p, q); } +static void f2 (struct A *p, void *q) { f1 (p, q); } -void g0 (struct A *p) +static void g0 (struct A *p) { __builtin_free (p->p); // { dg-warning "\\\[-Wfree-nonheap-object" } } -void g1 (struct A *p) { g0 (p); } -void g2 (struct A *p) { g1 (p); } +static void g1 (struct A *p) { g0 (p); } +static void g2 (struct A *p) { g1 (p); } # 26 "Wfree-nonheap-object-4.c" #define NOIPA __attribute__ ((noipa)) -extern int array[]; +extern int array[]; // { dg-message "declared here" "note on line 29" } /* Verify the warning is issued even for calls in a system header inlined into a function outside the header. */ @@ -39,7 +39,7 @@ NOIPA void warn_g0 (struct A *p) g0 (p); } -// { dg-message "inlined from 'warn_g0'" "" { target *-*-* } 0 } +// { dg-message "inlined from 'warn_g0'" "note on line 42" { target *-*-* } 0 } /* Also verify the warning can be suppressed. */ @@ -65,8 +65,8 @@ NOIPA void warn_g1 (struct A *p) g1 (p); } -// { dg-message "inlined from 'g1'" "" { target *-*-* } 0 } -// { dg-message "inlined from 'warn_g1'" "" { target *-*-* } 0 } +// { dg-message "inlined from 'g1'" "note on line 68" { target *-*-* } 0 } +// { dg-message "inlined from 'warn_g1'" "note on line 69" { target *-*-* } 0 } NOIPA void nowarn_g1 (struct A *p) @@ -90,8 +90,8 @@ NOIPA void warn_g2 (struct A *p) g2 (p); } -// { dg-message "inlined from 'g2'" "" { target *-*-* } 0 } -// { dg-message "inlined from 'warn_g2'" "" { target *-*-* } 0 } +// { dg-message "inlined from 'g2'" "note on line 93" { target *-*-* } 0 } +// { dg-message "inlined from 'warn_g2'" "note on line 94" { target *-*-* } 0 } NOIPA void nowarn_g2 (struct A *p) diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c new file mode 100644 index 0000000..026cd45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-5.c @@ -0,0 +1,46 @@ +/* Similar to Wfree-nonheap-object-4.c but without system headers: + verify that warnings for the same call site from distinct callers + include the correct function names in the inlining stack. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct A +{ + void *p; +}; + +static void f0 (struct A *p) +{ + __builtin_free (p->p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +// Expect two instances of the text below: +// { dg-regexp "In function 'f0'," "first f0 prefix" { target *-*-* } 0 } +// { dg-regexp "In function 'f0'," "second f0 prefix" { target *-*-* } 0 } + +static void f1 (struct A *p) { f0 (p); } +static void f2 (struct A *p) { f1 (p); } + +extern int array[]; +// Also expect two instances of the note: +// { dg-regexp "declared here" "first note on line 24" { target *-*-* } .-2 } +// { dg-regexp "declared here" "second note on line 24" { target *-*-* } .-3 } + +void foo (struct A *p) +{ + p->p = array + 1; + f0 (p); +} + +// { dg-regexp " +inlined from 'foo' at \[^:\]+Wfree-nonheap-object-5.c:32:\\d+:" "note on line 32" } + + +void bar (struct A *p) +{ + p->p = array + 2; + f2 (p); +} + +// { dg-regexp " +inlined from 'f1' at \[^:\]+Wfree-nonheap-object-5.c:21:\\d+," "inlined from f1" } +// { dg-regexp " +inlined from 'f2' at \[^:\]+Wfree-nonheap-object-5.c:22:\\d+," "inlined from f2" } +// { dg-regexp " +inlined from 'bar' at \[^:\]+Wfree-nonheap-object-5.c:41:\\d+:" "inlined from bar" } diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c new file mode 100644 index 0000000..c109558 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-6.c @@ -0,0 +1,49 @@ +/* Similar to Wfree-nonheap-object-5.c but with attribute artificial: + verify that warnings for the same call site from distinct callers + include the correct function names in the inlining stack. + { dg-do compile } + { dg-options "-O1 -Wall" } */ + +struct A +{ + void *p; +}; + +__attribute__ ((always_inline, artificial)) +inline void f0 (struct A *p) +{ + __builtin_free (p->p); // { dg-warning "\\\[-Wfree-nonheap-object" } +} + +// Expect two instances of the text below: +// { dg-regexp "In function 'f0'," "first f0 prefix" { target *-*-* } 0 } +// { dg-regexp "In function 'f0'," "second f0 prefix" { target *-*-* } 0 } + +__attribute__ ((always_inline, artificial)) +inline void f1 (struct A *p) { f0 (p); } +__attribute__ ((always_inline, artificial)) +inline void f2 (struct A *p) { f1 (p); } + +extern int array[]; +// Also expect two instances of the note: +// { dg-regexp "declared here" "first note for array" { target *-*-* } .-2 } +// { dg-regexp "declared here" "second note for array" { target *-*-* } .-3 } + +void foo (struct A *p) +{ + p->p = array + 1; + f0 (p); +} + +// { dg-regexp " +inlined from 'foo' at \[^:\]+Wfree-nonheap-object-6.c:35:\\d+:" "inlined from foo" } + + +void bar (struct A *p) +{ + p->p = array + 2; + f2 (p); +} + +// { dg-regexp " +inlined from 'f1' at \[^:\]+Wfree-nonheap-object-6.c:23:\\d+," "inlined from f1" } +// { dg-regexp " +inlined from 'f2' at \[^:\]+Wfree-nonheap-object-6.c:25:\\d+," "inlined from f2" } +// { dg-regexp " +inlined from 'bar' at \[^:\]+Wfree-nonheap-object-6.c:44:\\d+:" "inlined from bar" } diff --git a/gcc/testsuite/gcc.dg/Wobjsize-1.c b/gcc/testsuite/gcc.dg/Wobjsize-1.c index e80c8ad..2bd2f93 100644 --- a/gcc/testsuite/gcc.dg/Wobjsize-1.c +++ b/gcc/testsuite/gcc.dg/Wobjsize-1.c @@ -4,13 +4,17 @@ #include "Wobjsize-1.h" char buf[6]; -/* { dg-warning "writing" "" { target *-*-* } .-1 } */ int main(int argc, char **argv) { - strcpy (buf,"hello "); + strcpy (buf,"hello "); /* { dg-warning "\\\[-Wstringop-overflow" } */ return 0; } -/* { dg-message "file included" "included" { target *-*-* } 0 } */ -/* { dg-message "inlined from" "inlined" { target *-*-* } 0 } */ +/* { dg-message "file included" "included" { target *-*-* } 0 } + { dg-message "inlined from" "inlined" { target *-*-* } 0 } + + The test might emit two warnings, one for the strcpy call and + another for the inlined call to __builtin___strcpy_chk() called + from strcpy(). + { dg-prune-output "writing 7 bytes into a region of size 6" } */ diff --git a/gcc/testsuite/gcc.dg/format/c90-printf-1.c b/gcc/testsuite/gcc.dg/format/c90-printf-1.c index c8652fc..8ffd63f 100644 --- a/gcc/testsuite/gcc.dg/format/c90-printf-1.c +++ b/gcc/testsuite/gcc.dg/format/c90-printf-1.c @@ -240,7 +240,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, printf ("%n", cn); /* { dg-warning "3:constant" "%n with const" } */ printf ((const char *)L"foo"); /* { dg-warning "25:wide" "wide string" } */ printf ("%n", (int *)0); /* { dg-warning "3:null" "%n with NULL" } */ - printf ("%s", (char *)0); /* { dg-warning "3:null" "%s with NULL" } */ + printf ("%s", (char *)0); /* { dg-warning "12:'%s' directive argument is null" "%s with NULL" } */ /* Test for correct column locations within strings with embedded escape sequences. */ printf ("\\\a\n \"\t%5n\n", n); /* { dg-warning "25:width" "width with %n" } */ diff --git a/gcc/testsuite/gcc.dg/pr79214.c b/gcc/testsuite/gcc.dg/pr79214.c index 3f5d935..2f93eed 100644 --- a/gcc/testsuite/gcc.dg/pr79214.c +++ b/gcc/testsuite/gcc.dg/pr79214.c @@ -22,67 +22,67 @@ static size_t range (void) void test_bzero (void) { - bzero (d, range ()); /* { dg-warning ".__builtin_(bzero|memset). writing 4 or more bytes into a region of size 3 overflows the destination" } */ + bzero (d, range ()); /* { dg-warning ".__builtin_(bzero|memset). writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } void test_memcpy (void) { - memcpy (d, s, range ()); /* { dg-warning ".__builtin_memcpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */ + memcpy (d, s, range ()); /* { dg-warning ".__builtin_memcpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } void test_memmove (void) { - memmove (d, d + 1, range ()); /* { dg-warning ".__builtin_memmove. writing 4 or more bytes into a region of size 3 overflows the destination" } */ + memmove (d, d + 1, range ()); /* { dg-warning ".__builtin_memmove. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } void test_mempcpy (void) { - mempcpy (d, s, range ()); /* { dg-warning ".__builtin_mempcpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */ + mempcpy (d, s, range ()); /* { dg-warning ".__builtin_mempcpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } void test_memset (int n) { - memset (d, n, range ()); /* { dg-warning ".__builtin_memset. writing 4 or more bytes into a region of size 3 overflows the destination" } */ + memset (d, n, range ()); /* { dg-warning ".__builtin_memset. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } void test_strcat (int i) { const char *s = i < 0 ? "123" : "4567"; - strcat (d, s); /* { dg-warning ".__builtin_strcat. writing between 4 and 5 bytes into a region of size 3 overflows the destination" } */ + strcat (d, s); /* { dg-warning ".__builtin_strcat. writing between 4 and 5 bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } char* test_stpcpy (int i) { const char *s = i < 0 ? "123" : "4567"; - return stpcpy (d, s); /* { dg-warning ".__builtin_stpcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" } */ + return stpcpy (d, s); /* { dg-warning ".__builtin_stpcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } char* test_stpncpy (int i) { const char *s = i < 0 ? "123" : "4567"; - return stpncpy (d, s, range ()); /* { dg-warning ".__builtin_stpncpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */ + return stpncpy (d, s, range ()); /* { dg-warning ".__builtin_stpncpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } char* test_strcpy (int i) { const char *s = i < 0 ? "123" : "4567"; - return strcpy (d, s); /* { dg-warning ".__builtin_strcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" } */ + return strcpy (d, s); /* { dg-warning ".__builtin_strcpy. writing between 4 and 5 bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } char* test_strncpy (int i) { const char *s = i < 0 ? "123" : "4567"; - return strncpy (d, s, range ()); /* { dg-warning ".__builtin_strncpy. writing 4 or more bytes into a region of size 3 overflows the destination" } */ + return strncpy (d, s, range ()); /* { dg-warning ".__builtin_strncpy. writing 4 or more bytes into a region of size 3 overflows the destination" "pr?????" { xfail { *-*-* } } } */ } char* test_strncat (int i) { const char *s = i < 0 ? "123" : "4567"; - return strncat (d, s, range ()); /* { dg-warning ".__builtin_strncat. specified bound \\\[4, \[0-9\]+] exceeds destination size 3" } */ + return strncat (d, s, range ()); /* { dg-warning ".__builtin_strncat. specified bound \\\[4, \[0-9\]+] exceeds destination size 3" "pr?????" { xfail { *-*-* } } } */ } diff --git a/gcc/testsuite/gcc.dg/pragma-diag-10.c b/gcc/testsuite/gcc.dg/pragma-diag-10.c new file mode 100644 index 0000000..127b299 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-diag-10.c @@ -0,0 +1,20 @@ +/* PR middle-end/98512 - #pragma GCC diagnostic ignored ineffective + in conjunction with alias attribute + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void * +__rawmemchr_ppc (const void *s, int c) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#pragma GCC diagnostic ignored "-Wstringop-overread" + if (c != 0) + return __builtin_memchr (s, c, (unsigned long)-1); // { dg-bogus "specified bound \\d+ exceeds maximum object size" } +#pragma GCC diagnostic pop + + return (char *)s + __builtin_strlen (s); +} + +extern __typeof (__rawmemchr_ppc) __EI___rawmemchr_ppc + __attribute__((alias ("__rawmemchr_ppc"))); diff --git a/gcc/testsuite/gcc.dg/pragma-diag-9.c b/gcc/testsuite/gcc.dg/pragma-diag-9.c new file mode 100644 index 0000000..9aac379 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-diag-9.c @@ -0,0 +1,141 @@ +/* Verify that #pragma GCC diagnostic down the inlining stack suppresses + a warning that would otherwise be issued for inlined calls higher up + the inlining stack. + { dg-do compile } + { dg-options "-O2 -Wall -Wno-array-bounds" } */ + +extern void* memset (void*, int, __SIZE_TYPE__); + +static void warn0 (int *p) +{ + memset (p, __LINE__, 3); // { dg-warning "\\\[-Wstringop-overflow" } +} + +static void warn1 (int *p) +{ + warn0 (p + 1); +} + +static void warn2 (int *p) +{ + warn1 (p + 1); +} + +int a2[2]; // { dg-message "at offset 12 into destination object 'a2' of size 8" } + +void warn3 (void) +{ + warn2 (a2 + 1); +} + + +// Verify suppression at the innermost frame of the inlining stack. + +static void ignore0 (int *p) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" + memset (p, __LINE__, 3); +#pragma GCC diagnostic pop +} + +static void nowarn1_ignore0 (int *p) +{ + ignore0 (p + 1); +} + +static void nowarn2_ignore0 (int *p) +{ + nowarn1_ignore0 (p + 1); +} + +int b2[2]; + +void nowarn3_ignore0 (void) +{ + nowarn2_ignore0 (b2 + 1); +} + + +// Verify suppression at the second innermost frame of the inlining stack. + +static void nowarn0_ignore1 (int *p) +{ + memset (p, __LINE__, 3); +} + +static void ignore1 (int *p) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" + nowarn0_ignore1 (p + 1); +#pragma GCC diagnostic pop +} + +void nowarn2_ignore1 (int *p) +{ + ignore1 (p + 1); +} + +int c2[2]; + +void nowarn3_ignore1 (void) +{ + nowarn2_ignore1 (c2 + 1); +} + + +// Verify suppression at the third innermost frame of the inlining stack. + +static void nowarn0_ignore2 (int *p) +{ + memset (p, __LINE__, 3); +} + +static void nowarn1_ignore2 (int *p) +{ + nowarn0_ignore2 (p + 1); +} + +static void ignore2 (int *p) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" + nowarn1_ignore2 (p + 1); +#pragma GCC diagnostic pop +} + +int d2[2]; + +void nowarn3_ignore2 (void) +{ + ignore2 (c2 + 1); +} + + +// Verify suppression at the outermost frame of the inlining stack. + +static void nowarn0_ignore3 (int *p) +{ + memset (p, __LINE__, 3); +} + +static void nowarn1_ignore3 (int *p) +{ + nowarn0_ignore3 (p + 1); +} + +static void nowarn2_ignore3 (int *p) +{ + nowarn1_ignore3 (p + 1); +} + +int e2[2]; + +void ignore3 (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" + nowarn2_ignore3 (e2 + 1); +#pragma GCC diagnostic pop +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c new file mode 100644 index 0000000..8188dd8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-27.c @@ -0,0 +1,20 @@ +/* PR middle-end/100325 - missing warning with -O0 on sprintf overflow with + pointer plus offset + { dg-do compile } + { dg-options "-O0 -Wall" } */ + +#define S(n) (&"0123456789"[10 - n]) + +extern int sprintf (char*, const char*, ...); + +char d[10]; + +void nowarn_d10_s9 () +{ + sprintf (d, "%s", S (9)); // { dg-bogus "-Wformat-overflow" } +} + +void warn_d10_s10 () +{ + sprintf (d, "%s", S (10)); // { dg-warning "-Wformat-overflow" } +} diff --git a/gcc/testsuite/gcc.dg/uninit-suppress_3.c b/gcc/testsuite/gcc.dg/uninit-suppress_3.c new file mode 100644 index 0000000..7bbe9ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-suppress_3.c @@ -0,0 +1,98 @@ +/* PR middle-end/98871 - Cannot silence -Wmaybe-uninitialized at declaration + site + { dg-do compile } + { dg-options "-O1 -Wall" } */ + +struct A +{ + int x; +}; + +// Verify that suppression works at every inlining level. + +static int f0 (int *x) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + + return ++*x; + +#pragma GCC diagnostic pop +} + +static int f1 (int *p, int n) +{ + struct A a; + for (int i = 0; i < n; ++i) { + if (p[i] > 1) { + a = (struct A){p[i]}; + } + } + + return f0 (&a.x); +} + +int f2 (void) +{ + int a[] = { 1, 2, 3, 4 }; + return f1 (a, 4); +} + + +static int g0 (int *x) +{ + return ++*x; +} + +static int g1 (int *p, int n) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + + struct A a; + for (int i = 0; i < n; ++i) { + if (p[i] > 1) { + a = (struct A){p[i]}; + } + } + + return g0 (&a.x); + +#pragma GCC diagnostic pop +} + +int g2 (void) +{ + int a[] = { 1, 2, 3, 4, 5 }; + return g1 (a, 5); +} + + +static int h0 (int *x) +{ + return ++*x; +} + +static int h1 (int *p, int n) +{ + struct A a; + for (int i = 0; i < n; ++i) { + if (p[i] > 1) { + a = (struct A){p[i]}; + } + } + + return h0 (&a.x); +} + +int h2 (void) +{ + int a[] = { 1, 2, 3, 4, 5, 6 }; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + + return h1 (a, 6); + +#pragma GCC diagnostic pop +} -- cgit v1.1 From 4f6e181181a48c341e524653cae0885fd170131e Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 6 Jul 2021 14:13:31 -0600 Subject: Remove support for %G and %K. gcc/c-family/ChangeLog: * c-format.c (gcc_tdiag_char_table): Remove support for %G and %K. (gcc_cdiag_char_table): Same. (gcc_cxxdiag_char_table): Same. gcc/c/ChangeLog: * c-objc-common.c (c_tree_printer): Remove support for %G and %K. gcc/cp/ChangeLog: * error.c (cp_printer): Remove support for %G and %K. gcc/ChangeLog: * gimple-pretty-print.c (percent_G_format): Remove. * tree-diagnostic.c (default_tree_printer): Remove calls. * tree-pretty-print.c (percent_K_format): Remove. * tree-pretty-print.h (percent_K_format): Remove. gcc/testsuite/ChangeLog: * gcc.dg/format/gcc_diag-10.c: Update expected warnings. * gcc.dg/plugin/diagnostic_plugin_test_inlining.c: Remove %G. --- gcc/testsuite/gcc.dg/format/gcc_diag-10.c | 20 ++++++++++---------- .../gcc.dg/plugin/diagnostic_plugin_test_inlining.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/format/gcc_diag-10.c b/gcc/testsuite/gcc.dg/format/gcc_diag-10.c index a2f99fe..dd930f9 100644 --- a/gcc/testsuite/gcc.dg/format/gcc_diag-10.c +++ b/gcc/testsuite/gcc.dg/format/gcc_diag-10.c @@ -64,8 +64,8 @@ void test_cdiag (tree t, gimple *gc) cdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */ cdiag ("%E", t); cdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */ - cdiag ("%G", gc); - cdiag ("%K", t); + cdiag ("%G", gc); /* { dg-warning "format" } */ + cdiag ("%K", t); /* { dg-warning "format" } */ cdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */ cdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */ @@ -80,8 +80,8 @@ void test_cdiag (tree t, gimple *gc) cdiag ("%<%D%>", t); cdiag ("%<%E%>", t); cdiag ("%<%F%>", t); - cdiag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */ - cdiag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */ + cdiag ("%<%G%>", gc); /* { dg-warning "format" } */ + cdiag ("%<%K%>", t); /* { dg-warning "format" } */ cdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */ cdiag ("%<%r%>", ""); /* { dg-warning "unterminated color directive" } */ @@ -103,8 +103,8 @@ void test_tdiag (tree t, gimple *gc) tdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */ tdiag ("%E", t); - tdiag ("%G", gc); - tdiag ("%K", t); + tdiag ("%G", gc); /* { dg-warning "format" } */ + tdiag ("%K", t); /* { dg-warning "format" } */ tdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */ tdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */ @@ -118,8 +118,8 @@ void test_tdiag (tree t, gimple *gc) tdiag ("%<%D%>", t); tdiag ("%<%E%>", t); - tdiag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */ - tdiag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */ + tdiag ("%<%G%>", gc); /* { dg-warning "format" } */ + tdiag ("%<%K%>", t); /* { dg-warning "format" } */ tdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */ tdiag ("%<%r%>", ""); /* { dg-warning "unterminated color directive" } */ @@ -138,8 +138,8 @@ void test_cxxdiag (tree t, gimple *gc) cxxdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */ cxxdiag ("%E", t); cxxdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */ - cxxdiag ("%G", gc); - cxxdiag ("%K", t); + cxxdiag ("%G", gc); /* { dg-warning "format" } */ + cxxdiag ("%K", t); /* { dg-warning "format" } */ cxxdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */ cxxdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c index 02c4629..d2bfca0 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c @@ -133,7 +133,7 @@ test_inlining (gimple *stmt) return; } - warning_at (call->location, 0, "%G%s", call, + warning_at (call->location, 0, "%s", TREE_STRING_POINTER (t_string)); } -- cgit v1.1 From 151b423a82f4bf15e3225833028f5258ea254cb9 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Tue, 6 Jul 2021 13:53:58 -0700 Subject: dwarf2ctf: the unit of sou field location is bits [PR101283] If the value of the DW_AT_data_member_location attribute is constant, the associated unit is bytes. This patch amends incorrect behaviour which was being exercised with -gdwarf-2. This caused some of the failures as noted in PR debug/101283 (specifically the BTF tests involving btm_offset). The testcase ctf-struct-array-2.c was erroneously checking for the value of ctm_offset in number of bytes. The patch fixes the calculation of the field location value for a struct member in dwarf2ctf and adjusts the testcase. This patch also fixes some of the failing tests as noted in PR debug/101283. 2021-07-06 Indu Bhagat gcc/ChangeLog: PR debug/101283 * dwarf2ctf.c (ctf_get_AT_data_member_location): Multiply by 8 to get number of bits. gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/ctf/ctf-struct-array-2.c: Adjust the value in the testcase. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c index 9e698fd..37094b5d 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c @@ -10,6 +10,6 @@ /* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*cta_nelems" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctm_offset" 1 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*ctm_offset" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x20\[\t \]+\[^\n\]*ctm_offset" 1 } } */ static struct ranges {int from, to;} lim_regs[] = {{ 16, 7}, { 16, 6}, { 20, 7},{ 20, 6}}; -- cgit v1.1 From ee9a0e93156ff3d41450db74172abc8ae2471d1f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 6 Jul 2021 15:15:53 -0600 Subject: Add test for [PR86650]. PR tree-optimization/86650 - -Warray-bounds missing inlining context gcc/testsuite/ChangeLog: PR tree-optimization/86650 * gcc.dg/Warray-bounds-76.c: New test. --- gcc/testsuite/gcc.dg/Warray-bounds-76.c | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-76.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-76.c b/gcc/testsuite/gcc.dg/Warray-bounds-76.c new file mode 100644 index 0000000..6711dc4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-76.c @@ -0,0 +1,35 @@ +/* PR tree-optimization/86650 - -Warray-bounds missing inlining context + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +static void f0 (int *p, int i) +{ + p[i] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Expect two instances of the text below: +// { dg-regexp "In function 'f0'," "first f0 prefix" { target *-*-* } 0 } +// { dg-regexp "In function 'f0'," "second f0 prefix" { target *-*-* } 0 } + +static void f1 (int *p, int i) { f0 (p + 1, i + 1); } +static void f2 (int *p, int i) { f1 (p + 1, i + 1); } + +extern int a2[2]; // { dg-note "'a2'" } + +void foo (void) +{ + f1 (a2 + 1, 1); +} + +// { dg-regexp " +inlined from 'foo' at \[^:\]+Warray-bounds-76.c:21:\\d+:" "inlined from foo" } + +extern int a3[3]; // { dg-note "'a3'" } + +void bar (void) +{ + f2 (a3 + 1, 1); +} + +// { dg-regexp " +inlined from 'f1' at \[^:\]+Warray-bounds-76.c:14:\\d+," "inlined from f1" } +// { dg-regexp " +inlined from 'f2' at \[^:\]+Warray-bounds-76.c:15:\\d+," "inlined from f2" } +// { dg-regexp " +inlined from 'bar' at \[^:\]+Warray-bounds-76.c:30:\\d+:" "inlined from bar" } -- cgit v1.1 From 97bcacfb5ac49afa4e305489dd110cc446451549 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Tue, 6 Jul 2021 16:02:38 -0700 Subject: CTF testsuite: Remove explicit check on ctv_typeidx The value of ctv_typeidx is the CTF type ID of the data type of the associated variable. The order in which the CTF types are added can change across platforms and also as the code evolves, hence changing the CTF type ID. As there is no direct and portable method of testing that the data type of a CTF variable is of a specific kind, remove the check on ctv_typeidx. This also fixes a subset of failures as seen on Darwin. 2021-07-06 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/ctf/ctf-attr-mode-1.c: Remove the check for ctv_typeidx. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c index fc3af03..c4801a7 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c @@ -1,7 +1,10 @@ /* Test CTF generation works well with ((mode)) attribute. In this testcase, CTF should report type of bqi to be an enum and - not an int. */ + not an int. Also, CTF for typedef of enum should exist. However, there + are no direct and portable methods of checking that a CTF type / CTF + variable refers to a specific CTF type, so this testcase merely asserts + for existence of individual CTF records. */ /* { dg-do compile ) */ /* { dg-options "-O0 -gctf -dA" } */ @@ -16,7 +19,5 @@ /* { dg-final { scan-assembler-times "\[\t \]0x22000003\[\t \]+\[^\n\]*ctt_info" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0x2a000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*ctv_typeidx" 1} } */ - typedef enum { B1 = 1, B2 = 2, B3 = 3 } B; B __attribute__ ((mode (QI))) bqi; -- cgit v1.1 From d9e9532bb3bf5db4cd6afd49d343ede5b27c3c9f Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Tue, 6 Jul 2021 16:11:47 -0700 Subject: BTF testsuite: Remove explicit check on btm_type The value of btm_type is the BTF type ID of the referred type. The order in which the BTF types are added can change across platforms and also as the code evolves, hence changing the BTF type ID. As there is no direct and portable method of testing that a BTF type refers to another BTF type of a specific kind, remove the explicit check on btm_type. This patch adjusts the testcase without affecting the test coverage as other testcases already have similar constructs. It also fixes a subset of failures as seen on Darwin. 2021-07-06 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/btf/btf-bitfields-3.c: Remove the check on btm_type. --- gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c index 5e68416..0e00f2b 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c @@ -11,7 +11,6 @@ [2] int 'unsigned int' size=4 offset=0 bits=32 [3] struct 'bitt' size=4 member 'f' type=1 bitfield_size=2 bit_offset=0 - member 'data' type=2 bitfield_size=14 bit_offset=2 */ /* { dg-do compile } */ @@ -19,15 +18,12 @@ /* Enum with 4 members. */ /* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */ -/* Struct with bitfield members, and 2 members. */ -/* { dg-final { scan-assembler-times "\[\t \]0x84000002\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Struct with 1 bitfield member. */ +/* { dg-final { scan-assembler-times "\[\t \]0x84000001\[\t \]+\[^\n\]*btt_info" 1 } } */ /* Bitfield "f" points to type ID 1. */ /* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btm_type" 1 } } */ -/* Bitfield "data" points to type ID 2. */ -/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btm_type" 1 } } */ - enum foo { BAR = 0, @@ -39,5 +35,4 @@ enum foo struct bitt { enum foo f : 2; - unsigned data : 14; } bitty; -- cgit v1.1 From 005f31a0370cf35e332db9415a0ff538320bcddc Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 7 Jul 2021 13:46:48 +0200 Subject: tree-optimization/34195 - testcase for fixed vectorization This adds a testcase for an old fixed PR. 2021-07-07 Richard Biener PR tree-optimization/34195 * gcc.dg/vect/pr34195.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr34195.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr34195.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr34195.c b/gcc/testsuite/gcc.dg/vect/pr34195.c new file mode 100644 index 0000000..e36950b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr34195.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +#define M 11 + +struct S +{ + float x; + float y; +} pS[100]; + +float a[1000]; +float b[1000]; + +void +foo (int n) +{ + int i, j; + + for (i = 0; i < n; i++) + { + pS[i].x = 0; + pS[i].y = 0; + + for (j = 0; j < M; j++) + { + pS[i].x += (a[i]+b[i]); + pS[i].y += (a[i]-b[i]); + } + } +} + +/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" } } */ -- cgit v1.1 From e8073c04536214c856a6340fea23d676cd7436af Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 7 Jul 2021 12:42:34 +0000 Subject: testsuite: gcc.dg/debug/btf/btf-bitfields-3.c remove -fno-short-enums PR debug/101321 After r12-2094, -fno-short-enums is non longer necessary. 2021-07-07 Christophe Lyon PR debug/101321 gcc/testsuite/ * gcc.dg/debug/btf/btf-bitfields-3.c: Remove -fno-short-enums. --- gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c index 0e00f2b..2984a33 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c @@ -14,7 +14,7 @@ */ /* { dg-do compile } */ -/* { dg-options "-O0 -gbtf -dA -fno-short-enums" } */ +/* { dg-options "-O0 -gbtf -dA" } */ /* Enum with 4 members. */ /* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */ -- cgit v1.1 From a110855667782dac7b674d3e328b253b3b3c919b Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 7 Jul 2021 14:05:25 -0600 Subject: Correct handling of variable offset minus constant in -Warray-bounds [PR100137] Resolves: PR tree-optimization/100137 - -Warray-bounds false positive on varying offset plus negative PR tree-optimization/99121 - ICE in -Warray-bounds on a multidimensional PR tree-optimization/97027 - missing warning on buffer overflow storing a larger scalar into a smaller array gcc/ChangeLog: PR tree-optimization/100137 PR tree-optimization/99121 PR tree-optimization/97027 * builtins.c (access_ref::access_ref): Also set offmax. (access_ref::offset_in_range): Define new function. (access_ref::add_offset): Set offmax. (access_ref::inform_access): Handle access_none. (handle_mem_ref): Clear ostype. (compute_objsize_r): Handle ASSERT_EXPR. * builtins.h (struct access_ref): Add offmax member. * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref): Use compute_objsize() and simplify. gcc/testsuite/ChangeLog: PR tree-optimization/100137 PR tree-optimization/99121 PR tree-optimization/97027 * c-c++-common/Warray-bounds-3.c: Remove xfail * c-c++-common/Warray-bounds-4.c: Add an expected warning. * c-c++-common/Warray-bounds-9.c: New test. * c-c++-common/Warray-bounds-10.c: New test. * g++.dg/asan/asan_test.C: Suppress expected warnings. * g++.dg/pr95768.C: Same. * g++.dg/warn/Warray-bounds-10.C: Adjust text of expected messages. * g++.dg/warn/Warray-bounds-11.C: Same. * g++.dg/warn/Warray-bounds-12.C: Same. * g++.dg/warn/Warray-bounds-13.C: Same. * g++.dg/warn/Warray-bounds-17.C: Same. * g++.dg/warn/Warray-bounds-20.C: Same. * gcc.dg/Warray-bounds-29.c: Same. * gcc.dg/Warray-bounds-30.c: Add xfail. * gcc.dg/Warray-bounds-31.c: Adjust text of expected messages. * gcc.dg/Warray-bounds-32.c: Same. * gcc.dg/Warray-bounds-52.c: Same. * gcc.dg/Warray-bounds-53.c: Same. * gcc.dg/Warray-bounds-58.c: Remove xfail. * gcc.dg/Warray-bounds-63.c: Adjust text of expected messages. * gcc.dg/Warray-bounds-66.c: Same. * gcc.dg/Warray-bounds-69.c: Same. * gcc.dg/Wstringop-overflow-34.c: Same. * gcc.dg/Wstringop-overflow-47.c: Same. * gcc.dg/Wstringop-overflow-61.c: Same. * gcc.dg/Warray-bounds-77.c: New test. * gcc.dg/Warray-bounds-78.c: New test. * gcc.dg/Warray-bounds-79.c: New test. --- gcc/testsuite/gcc.dg/Warray-bounds-29.c | 22 ++--- gcc/testsuite/gcc.dg/Warray-bounds-30.c | 2 +- gcc/testsuite/gcc.dg/Warray-bounds-31.c | 8 +- gcc/testsuite/gcc.dg/Warray-bounds-32.c | 26 +++--- gcc/testsuite/gcc.dg/Warray-bounds-52.c | 6 +- gcc/testsuite/gcc.dg/Warray-bounds-53.c | 6 +- gcc/testsuite/gcc.dg/Warray-bounds-58.c | 2 +- gcc/testsuite/gcc.dg/Warray-bounds-63.c | 6 +- gcc/testsuite/gcc.dg/Warray-bounds-66.c | 12 +-- gcc/testsuite/gcc.dg/Warray-bounds-69.c | 2 +- gcc/testsuite/gcc.dg/Warray-bounds-77.c | 135 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-78.c | 109 +++++++++++++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-79.c | 112 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-34.c | 8 +- gcc/testsuite/gcc.dg/Wstringop-overflow-47.c | 14 +-- gcc/testsuite/gcc.dg/Wstringop-overflow-61.c | 4 +- 16 files changed, 415 insertions(+), 59 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-77.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-78.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-79.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-29.c b/gcc/testsuite/gcc.dg/Warray-bounds-29.c index 72c5d1c..44e5bd3 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-29.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-29.c @@ -44,7 +44,7 @@ void test_narrow (void) T (p1[-1]); T (p1[ 0]); T (p1[ 1]); - T (p1[ 2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .char\\\[3]." } */ + T (p1[ 2]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */ T (p1[ 3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */ T (&p1[-3]); /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */ @@ -55,7 +55,7 @@ void test_narrow (void) T (&p1[ 2]); T (&p1[ 3]); /* { dg-warning "array subscript \\\[4, 6] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */ - T (p2[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */ + T (p2[-4]); /* { dg-warning "subscript \\\[-2, -1\\\] is outside array bounds of .char\\\[3]." } */ T (p2[-3]); T (p2[-2]); T (p2[-1]); @@ -64,19 +64,19 @@ void test_narrow (void) /* Even though the lower bound of p3's offsets is in bounds, in order to subtract 4 from p3 and get a dereferenceable pointer its value would have to be out-of-bounds. */ - T (p3[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */ + T (p3[-4]); /* { dg-warning "array subscript -1 is outside array bounds of .char\\\[3]." } */ T (p3[-3]); T (p3[-2]); T (p3[-1]); - T (p3[ 0]); /* { dg-warning "array subscript \\\[3, 6] is outside array bounds of .char\\\[3]." } */ + T (p3[ 0]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */ T (p4[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */ T (p4[-3]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */ T (p4[-2]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */ /* The final subscripts below are invalid. */ - T (p4[-1]); /* { dg-warning "array subscript \\\[3, 7] is outside array bounds of .char\\\[3]." } */ - T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 8] is outside array bounds of .char\\\[3]." } */ + T (p4[-1]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */ + T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */ } @@ -114,7 +114,7 @@ void test_wide (void) T (p1[ 0]); T (p1[ 1]); T (p1[ 2]); - T (p1[ 3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p1[ 3]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */ T (&p1[-1]); T (&p1[ 0]); @@ -133,18 +133,18 @@ void test_wide (void) /* Even though the lower bound of p3's offsets is in bounds, in order to subtract 5 from p3 and get a dereferenceable pointer its value would have to be out-of-bounds. */ - T (p3[-5]); /* { dg-warning "intermediate array offset 5 is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p3[-5]); /* { dg-warning "array subscript \\\[-2, -1\\\] is outside array bounds of .\[a-z \]+\\\[4]." } */ T (p3[-4]); T (p3[-3]); T (p3[-2]); T (p3[-1]); T (p3[ 0]); - T (p3[ 1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p3[ 1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */ - T (p4[-5]); /* { dg-warning "intermediate array offset 5 is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p4[-5]); /* { dg-warning "array subscript -1 is outside array bounds of .\[a-z \]+\\\[4]." } */ T (p4[-4]); T (p4[-3]); T (p4[-2]); T (p4[-1]); - T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 8] is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p4[ 0]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c index 048a95d..b837ad0 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c @@ -120,7 +120,7 @@ void test_global_short_2dim_array (void) T (&p[1]); T (&p[2]); T (&p[3]); - T (&p[16]); /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" } */ + T (&p[16]); /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" "pr??????" { xfail *-*-* } } */ T (&p[MAX]); /* { dg-warning "subscript -?\[0-9\]+ is \(above|outside\) array bounds of .short int\\\[3]" } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-31.c b/gcc/testsuite/gcc.dg/Warray-bounds-31.c index 389afaf..921461a 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-31.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-31.c @@ -174,7 +174,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j) T (*p); p = S1 + SR (2, 3); - T (*p); /* { dg-warning "array subscript \\\[2, 3] is outside array bounds of .char\\\[2]." } */ + T (*p); /* { dg-warning "array subscript 2 is outside array bounds of .char\\\[2]." } */ p = S1 + SR (9, 99); T (*p); /* { dg-warning "array subscript \\\[9, 99] is outside array bounds of .char\\\[2]." } */ @@ -198,7 +198,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j) T (*p); p = S8 + SR (9, 123); - T (*p); /* { dg-warning "array subscript \\\[9, 123] is outside array bounds of .char\\\[9]." } */ + T (*p); /* { dg-warning "array subscript 9 is outside array bounds of .char\\\[9]." } */ { const char *p1 = S3 + i; @@ -226,7 +226,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j) T (*p1); T (*p2); T (*p3); - T (*p4); /* { dg-warning "array subscript \\\[4, \[0-9\]+] is outside array bounds of .char\\\[4]." } */ + T (*p4); /* { dg-warning "array subscript 4 is outside array bounds of .char\\\[4]." } */ T (*p5); /* { dg-warning "array subscript \\\[5, \[0-9\]+] is outside array bounds of .char\\\[4]." } */ } } @@ -241,7 +241,7 @@ void narrow_ptr_index_range (void) T (p[SR (-8, 0)]); T (p[SR (0, MAX)]); T (p[SR (1, 9)]); - T (p[SR (8, 9)]); /* { dg-warning "array subscript \\\[8, 9] is outside array bounds of .char\\\[8]." } */ + T (p[SR (8, 9)]); /* { dg-warning "array subscript 8 is outside array bounds of .char\\\[8]." } */ p = S7 + SR (4, 6); T (p[5]); /* { dg-warning "array subscript \\\[9, 11] is outside array bounds of .char\\\[8]." } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-32.c b/gcc/testsuite/gcc.dg/Warray-bounds-32.c index 9b5f333..02dac65 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-32.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-32.c @@ -87,7 +87,7 @@ void wide_ptr_deref_range (ptrdiff_t i, size_t j) T (*p); p = W8 + SR (9, 123); - T (*p); /* { dg-warning "array subscript \\\[9, 123] is outside array bounds of .\[a-z \]+\\\[9]." } */ + T (*p); /* { dg-warning "array subscript 9 is outside array bounds of .\[a-z \]+\\\[9]." } */ } void wide_ptr_index_range (void) @@ -99,7 +99,7 @@ void wide_ptr_index_range (void) T (p[SR (-8, 0)]); T (p[SR (0, MAX)]); T (p[SR (1, 9)]); - T (p[SR (8, 9)]); /* { dg-warning "array subscript \\\[8, 9] is outside array bounds of .\[a-z \]+\\\[8]." } */ + T (p[SR (8, 9)]); /* { dg-warning "array subscript 8 is outside array bounds of .\[a-z \]+\\\[8]." } */ p = W7 + SR (4, 6); T (p[5]); /* { dg-warning "array subscript \\\[9, 11] is outside array bounds of .\[a-z \]+\\\[8]." } */ @@ -123,7 +123,7 @@ void wide_ptr_index_range_1 (void) int i = SR (1, 2); const wchar_t *p1 = W2 + i; - T (p1[2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .\[a-z \]+\\\[3]." } */ + T (p1[2]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */ } } @@ -140,17 +140,17 @@ void wide_ptr_index_range_chain (void) T (p1[-1]); T (p1[0]); T (p1[1]); - T (p1[2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .\[a-z \]+\\\[3]." } */ + T (p1[2]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */ - T (p2[-5]); /* { dg-warning "array subscript \\\[-3, -1] is outside array bounds of .\[a-z \]+\\\[3]." } */ - T (p2[-4]); + T (p2[-5]); /* { dg-warning "array subscript \\\[-3, -2] is outside array bounds of .\[a-z \]+\\\[3]." } */ + T (p2[-4]); /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .\[a-z \]+\\\[3]." } */ T (p2[-1]); T (p2[0]); - T (p2[1]); /* { dg-warning "array subscript \\\[3, 5] is outside array bounds of .\[a-z \]+\\\[3]." } */ + T (p2[1]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */ - T (p3[0]); /* { dg-warning "array subscript \\\[3, 6] is outside array bounds of .\[a-z \]+\\\[3]." } */ - T (p3[1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[3]." } */ - T (p3[9999]); /* { dg-warning "array subscript \\\[10002, 10005] is outside array bounds of .\[a-z \]+\\\[3]." "" { target size20plus} } */ + T (p3[0]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */ + T (p3[1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[3]." } */ + T (p3[9999]); /* { dg-warning "array subscript 10002 is outside array bounds of .\[a-z \]+\\\[3]." "" { target size20plus} } */ /* { dg-warning "array subscript \\\[-6382, -6379] is outside array bounds of .\[a-z \]+\\\[3]." "" { target { ! size20plus } } .-1 } */ /* Large offsets are indistinguishable from negative values. */ T (p3[DIFF_MAX]); /* { dg-warning "array subscript" "bug" { xfail *-*-* } } */ @@ -166,9 +166,9 @@ void wide_ptr_index_range_chain (void) T (p1[-2]); T (p1[1]); T (p1[2]); - T (p1[3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p1[3]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */ - T (p3[1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[4]." } */ + T (p3[1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */ } } @@ -180,5 +180,5 @@ void wide_ptr_index_range_4 (void) const wchar_t *p3 = p2 + i; const wchar_t *p4 = p3 + i; - T (p4[1]); /* { dg-warning "array subscript \\\[5, 9] is outside array bounds of .\[a-z \]+\\\[5]." } */ + T (p4[1]); /* { dg-warning "array subscript 5 is outside array bounds of .\[a-z \]+\\\[5]." } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-52.c b/gcc/testsuite/gcc.dg/Warray-bounds-52.c index 729ad45..c7217ad 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-52.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-52.c @@ -83,17 +83,17 @@ void ptr_idx_range (void) i = SR (0, 1); - T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" } + T (i, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" } T (i, (int[]){ 1 }); i = SR (1, 2); - T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" } + T (i, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" } i = SR (2, 3); T (i, (int[]){ 1, 2, 3 }); i = SR (3, 4); - T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" } + T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript 3 is outside array bounds of 'int\\\[3]'" } } /* Some of the invalid accesses above also trigger -Wuninitialized. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-53.c b/gcc/testsuite/gcc.dg/Warray-bounds-53.c index 80db314..591cca2 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-53.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-53.c @@ -83,17 +83,17 @@ void ptr_idx_range (void) i = SR (0, 1); - T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" } + T (i, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" } T (i, (int[]){ 1 }); i = SR (1, 2); - T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" } + T (i, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" } i = SR (2, 3); T (i, (int[]){ 1, 2, 3 }); i = SR (3, 4); - T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" } + T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript 3 is outside array bounds of 'int\\\[3]'" } } /* Some of the invalid accesses above also trigger -Wuninitialized. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-58.c b/gcc/testsuite/gcc.dg/Warray-bounds-58.c index 849457e5..616145b 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-58.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-58.c @@ -36,7 +36,7 @@ extern struct Ax ax; void fax_extern (void) { - sink (strlen (ax.a - 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } } + sink (strlen (ax.a - 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" } sink (strlen (ax.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } } sink (strlen (ax.a)); sink (strlen (ax.a + 123)); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-63.c b/gcc/testsuite/gcc.dg/Warray-bounds-63.c index a3fc918..530e2c5 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-63.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-63.c @@ -14,7 +14,7 @@ void sink (void*); void byte_store_to_decl (void) { - struct S6 { char a[6]; } s; // { dg-message "referencing 's'" } + struct S6 { char a[6]; } s; // { dg-message "at offset 6 into object 's' of size 6" "note" } char *p = (char*)&s; @@ -27,7 +27,7 @@ void byte_store_to_decl (void) void word_store_to_decl (void) { - struct S6 { char a[6]; } s; // { dg-message "referencing 's'" } + struct S6 { char a[6]; } s; // { dg-message "at offset 5 into object 's' of size 6" "note" } char *p = (char*)&s; @@ -43,7 +43,7 @@ void word_store_to_decl (void) void word_store_to_alloc (void) { struct S6 { char a[6]; } *p; - p = alloca (sizeof *p); // { dg-message "referencing an object of size 6 allocated by 'alloca'" } + p = alloca (sizeof *p); // { dg-message "at offset 5 into object of size 6 allocated by 'alloca'" "note" } int16_t *q = (int16_t*)((char*)p + 1); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-66.c b/gcc/testsuite/gcc.dg/Warray-bounds-66.c index c61891f..6ab3398 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-66.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-66.c @@ -117,14 +117,14 @@ void test_alloca_int16_range (unsigned n) } { - p = alloca (UR (0, 1)); // { dg-message "object of size between 0 and 1 allocated by '__builtin_alloca'" } + p = alloca (UR (0, 1)); // { dg-message "at offset \\d+ into object of size \\\[0, 1] allocated by '__builtin_alloca'" "note" } sink (p); T (p[0]); // { dg-warning "subscript 'int16_t {aka short int}\\\[0\\\]' is partly outside array bounds of 'unsigned char\\\[1]'" } T (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[0]'" } } { - p = alloca (UR (0, 2)); // { dg-message "object of size between 0 and 2 allocated by '__builtin_alloca'" } + p = alloca (UR (0, 2)); // { dg-message "at offset \\d+ into object of size \\\[0, 2] allocated by '__builtin_alloca'" "note" } sink (p); sink (p[0]); sink (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[1]'" } @@ -132,7 +132,7 @@ void test_alloca_int16_range (unsigned n) } { - p = alloca (UR (0, 3)); // { dg-message "object of size between 0 and 3 allocated by '__builtin_alloca'" } + p = alloca (UR (0, 3)); // { dg-message "at offset \\d+ into object of size \\\[0, 3] allocated by '__builtin_alloca'" "note" } sink (p); T (p[0]); T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" } @@ -141,7 +141,7 @@ void test_alloca_int16_range (unsigned n) } { - p = alloca (UR (1, 3)); // { dg-message "object of size between 1 and 3 allocated by '__builtin_alloca'" } + p = alloca (UR (1, 3)); // { dg-message "at offset 1|2|3 into object of size \\\[1, 3] allocated by '__builtin_alloca'" "note" } sink (p); T (p[0]); T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" } @@ -150,7 +150,7 @@ void test_alloca_int16_range (unsigned n) } { - p = alloca (UR (2, 3)); // { dg-message "object of size between 2 and 3 allocated by '__builtin_alloca'" } + p = alloca (UR (2, 3)); // { dg-message "at offset 2|4 into object of size \\\[2, 3] allocated by '__builtin_alloca'" "note" } sink (p); T (p[0]); T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" } @@ -159,7 +159,7 @@ void test_alloca_int16_range (unsigned n) } { - p = alloca (UR (3, 4)); // { dg-message "object of size between 3 and 4 allocated by '__builtin_alloca'" } + p = alloca (UR (3, 4)); // { dg-message "at offset 4|6 into object of size \\\[3, 4] allocated by '__builtin_alloca'" "note" } sink (p); T (p[0]); T (p[1]); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-69.c b/gcc/testsuite/gcc.dg/Warray-bounds-69.c index 5a95577..80503f8 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-69.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-69.c @@ -1,6 +1,6 @@ /* Verify that storing a bigger vector into smaller space is diagnosed. { dg-do compile } - { dg-options "-O2 -Warray-bounds" } */ + { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */ typedef __INT16_TYPE__ int16_t; typedef __attribute__ ((__vector_size__ (32))) char C32; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-77.c b/gcc/testsuite/gcc.dg/Warray-bounds-77.c new file mode 100644 index 0000000..6487613 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-77.c @@ -0,0 +1,135 @@ +/* PR middle-end/100137 - -Warray-bounds false positive on varying offset + plus negative + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +extern char ax[], a1[1], a2[2], a3[3], a4[4], a5[5]; + +int* ptr; +#define X (*ptr++) + + +__attribute__ ((noipa)) void +array_plus_var_minus_cstint (int i, int j) +{ + { + const char *p = ax; + p += i; + X = p[-1]; + X = p[-123]; + } + + { + const char *p = a1; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a2; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a3; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a4; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a5; + p += i; + p += j; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-5]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + } +} + + +__attribute__ ((noipa)) void +array_plus_var_minus_cstlong (long i, long j) +{ + { + const char *p = ax; + p += i; + X = p[-1]; + X = p[-123]; + } + + { + const char *p = a1; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a2; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a3; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a4; + p += i; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + X = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = a5; + p += i; + p += j; + X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-5]; // { dg-bogus "\\\[-Warray-bounds" } + X = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + } +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-78.c b/gcc/testsuite/gcc.dg/Warray-bounds-78.c new file mode 100644 index 0000000..73c335f --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-78.c @@ -0,0 +1,109 @@ +/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array + element of empty structs + { dg-do compile } + { dg-options "-O2 -Wall -Wno-strict-aliasing" } */ + +typedef _Bool bool; + +#define NOIPA __attribute__ ((noipa)) + +struct S { }; + +extern struct S sa3[3]; +extern struct S sa2_3[2][3]; +extern struct S sa3_4_5[3][4][5]; + +void sink (void*); + + +NOIPA void access_sa3 (void) +{ + ((bool*)sa3)[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + ((bool*)sa3)[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + ((bool*)sa3)[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + ((bool*)sa3)[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } +} + +NOIPA void access_sa3_ptr (void) +{ + bool *p = (bool*)&sa3[0]; + + p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } +} + +NOIPA void access_sa2_3_ptr (void) +{ + bool *p = (bool*)&sa2_3[0][0]; + + p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[6] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } +} + +NOIPA void access_sa3_4_5_ptr (struct S s, int i) +{ + bool *p = (bool*)&sa3_4_5[0][0][0]; + + p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[60] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } +} + + +NOIPA void access_vla3 (struct S s, unsigned n) +{ + struct S vla3[3 < n ? 3 : n]; + + ((bool*)vla3)[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + ((bool*)vla3)[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + ((bool*)vla3)[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + ((bool*)vla3)[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla3); +} + +NOIPA void access_vla3_ptr (struct S s, unsigned n) +{ + struct S vla3[3 < n ? 3 : n]; + bool *p = (bool*)&vla3[0]; + + p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla3); +} + +NOIPA void access_vla2_3_ptr (struct S s, unsigned n) +{ + struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n]; + bool *p = (bool*)&vla2_3[0][0]; + + p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[6] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla2_3); +} + +NOIPA void access_vla3_4_5_ptr (struct S s, unsigned n) +{ + struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n]; + bool *p = (bool*)&vla3_4_5[0][0][0]; + + p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + p[60] = __LINE__; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla3_4_5); +} + +// { dg-prune-output "empty struct has size 0 in C" } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-79.c b/gcc/testsuite/gcc.dg/Warray-bounds-79.c new file mode 100644 index 0000000..b44ac9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-79.c @@ -0,0 +1,112 @@ +/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array + element of empty structs + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct S +{ +#if SOME_CONFIG_MACRO + /* Suppose the contents are empty in the development configuration + but non-empty in others. Out of bounds accesses to elements of + the arrays below should be diagnosed in all configurations, + including when S is empty, even if they are folded away. */ + int member; +#endif +}; + +extern struct S sa3[3]; +extern struct S sa2_3[2][3]; +extern struct S sa3_4_5[3][4][5]; + +void sink (void*); + + +void access_sa3 (void) +{ + sa3[0] = (struct S){ }; + sa3[1] = (struct S){ }; + sa3[2] = (struct S){ }; + sa3[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } +} + +void access_sa3_ptr (void) +{ + struct S *p = &sa3[0]; + + p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } +} + +void access_sa2_3_ptr (void) +{ + struct S *p = &sa2_3[0][0]; + + p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[6] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } +} + +void access_sa3_4_5_ptr (struct S s, int i) +{ + struct S *p = &sa3_4_5[0][0][0]; + + p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[60] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } +} + + +void access_vla3 (struct S s, unsigned n) +{ + struct S vla3[3 < n ? 3 : n]; + + vla3[0] = (struct S){ }; + vla3[1] = (struct S){ }; + vla3[2] = (struct S){ }; + vla3[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } + + sink (vla3); +} + +void access_vla3_ptr (struct S s, unsigned n) +{ + struct S vla3[3 < n ? 3 : n]; + struct S *p = &vla3[0]; + + p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } + + sink (vla3); +} + +void access_vla2_3_ptr (struct S s, unsigned n) +{ + struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n]; + struct S *p = &vla2_3[0][0]; + + p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[6] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } + + sink (vla2_3); +} + +void access_vla3_4_5_ptr (struct S s, unsigned n) +{ + struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n]; + struct S *p = &vla3_4_5[0][0][0]; + + p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" } + p[60] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } } + + sink (vla3_4_5); +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c index a1b1039..d9ca344 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c @@ -112,7 +112,7 @@ void s2_warn_cstoff_cstidx (struct S2 *p) void s2_warn_varoff_cstdix (struct S2 *p, int i) { char *q = p->a + i; - q[2] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" } + q[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } } void s2_warn_cstoff_varidx (struct S2 *p, int i) @@ -235,8 +235,8 @@ void si0_warn_cstoff_cstidx (struct Si0 *p) void si0_warn_varoff_cstdix (struct Si0 *p, int i) { char *q = p->a + i; - q[1] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" } - q[9] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" } + q[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } + q[9] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } } void si0_warn_cstoff_varidx (struct Si0 *p, int i) @@ -248,5 +248,5 @@ void si0_warn_cstoff_varidx (struct Si0 *p, int i) void si0_warn_varoff_varidx (struct Si0 *p, int i, int j) { char *q = p->a + i; - q[j] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" } + q[j] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c index 9bfc84a..6412874 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c @@ -24,22 +24,22 @@ void nowarn_c32 (char c) sink (p); } -/* The tests below fail as a result of the hack for PR 96963. However, - with -Wall, the invalid stores are diagnosed by -Warray-bounds which - runs before vectorization and so doesn't need the hack. If/when - -Warray changes to use compute_objsize() this will need adjusting. */ +/* The tests below failed as a result of the hack for PR 96963. However, + with -Wall, the invalid stores were diagnosed by -Warray-bounds which + runs before vectorization and so doesn't need the hack. Now that + -Warray-bounds has changed to use compute_objsize() the tests pass. */ void warn_c32 (char c) { - extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" { xfail *-*-* } } + extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" } void *p = warn_a32 + 1; - *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } } + *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" } /* Verify a local variable too. */ char a32[32]; p = a32 + 1; - *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } } + *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" } sink (p); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c index 7601679..93c54c6 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c @@ -65,7 +65,7 @@ void nowarn_cond_escape (int c, int *x) void warn_cond_escape (int c, int *x) { extern char a3_2[3]; - extern char a5_2[5]; // { dg-message "at offset 5 into destination object 'a5_2'" } + extern char a5_2[5]; // { dg-message "at offset 5 into object 'a5_2'" } char *p; if (c) @@ -84,5 +84,5 @@ void warn_cond_escape (int c, int *x) if (*x == 2) p[2] = 0; else if (*x == 5) - p[5] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + p[5] = 0; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } } -- cgit v1.1 From 48e8a7a677b8356df946cd12fbb215538828e747 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 7 Jul 2021 19:29:30 -0400 Subject: analyzer: remove add_any_constraints_from_ssa_def_stmt I'm working on reimplementing -Wanalyzer-use-of-uninitialized-value, but I ran into issues with region_model::add_any_constraints_from_ssa_def_stmt. This function is from the initial commit of the analyzer and walks the SSA names finding conditions that were missed due to the GCC 10 era region_model not retaining useful information on how values were created; as of GCC 11 the symbolic values contain this information, and so the conditions can be reconstructed from them instead. region_model::add_any_constraints_from_ssa_def_stmt is a liability when tracking uninitialized values as it requires looking up SSA values when those values may have been purged, thus greatly complicating detection of uses of uninitialized values. It's simplest to eliminate it and reimplement the condition-finding via the makeup of the svalues, which this patch does. Doing so requires supporting add_condition on svalues rather than just on trees, which requires some changes to ana::state_machine and its subclasses. gcc/analyzer/ChangeLog: * diagnostic-manager.cc (null_assignment_sm_context::get_state): New overload. (null_assignment_sm_context::set_next_state): New overload. (null_assignment_sm_context::get_diagnostic_tree): New. * engine.cc (impl_sm_context::get_state): New overload. (impl_sm_context::set_next_state): New overload. (impl_sm_context::get_diagnostic_tree): New overload. (impl_region_model_context::on_condition): Convert params from tree to const svalue *. * exploded-graph.h (impl_region_model_context::on_condition): Likewise. * region-model.cc (region_model::on_call_pre): Move handling of internal calls to before checking for get_fndecl_for_call. (region_model::add_constraints_from_binop): New. (region_model::add_constraint): Split out into a new overload working on const svalue * rather than tree. Call add_constraints_from_binop. Drop call to add_any_constraints_from_ssa_def_stmt. (region_model::add_any_constraints_from_ssa_def_stmt): Delete. (region_model::add_any_constraints_from_gassign): Delete. (region_model::add_any_constraints_from_gcall): Delete. * region-model.h (region_model::add_any_constraints_from_ssa_def_stmt): Delete. (region_model::add_any_constraints_from_gassign): Delete. (region_model::add_any_constraints_from_gcall): Delete. (region_model::add_constraint): Add overload decl. (region_model::add_constraints_from_binop): New decl. (region_model_context::on_condition): Convert params from tree to const svalue *. (noop_region_model_context::on_condition): Likewise. * sm-file.cc (fileptr_state_machine::condition): Likewise. * sm-malloc.cc (malloc_state_machine::on_condition): Likewise. * sm-pattern-test.cc: Include tristate.h, selftest.h, analyzer/call-string.h, analyzer/program-point.h, analyzer/store.h, and analyzer/region-model.h. (pattern_test_state_machine::on_condition): Convert params from tree to const svalue *. * sm-sensitive.cc (sensitive_state_machine::on_condition): Delete. * sm-signal.cc (signal_state_machine::on_condition): Delete. * sm-taint.cc (taint_state_machine::on_condition): Convert params from tree to const svalue *. * sm.cc: Include tristate.h, selftest.h, analyzer/call-string.h, analyzer/program-point.h, analyzer/store.h, and analyzer/region-model.h. (any_pointer_p): Add overload taking const svalue *sval. * sm.h (any_pointer_p): Add overload taking const svalue *sval. (state_machine::on_condition): Convert params from tree to const svalue *. Provide no-op default implementation. (sm_context::get_state): Add overload taking const svalue *sval. (sm_context::set_next_state): Likewise. (sm_context::on_transition): Likewise. (sm_context::get_diagnostic_tree): Likewise. * svalue.cc (svalue::all_zeroes_p): New. (constant_svalue::all_zeroes_p): New. (repeated_svalue::all_zeroes_p): Convert to vfunc. * svalue.h (svalue::all_zeroes_p): New decl. (constant_svalue::all_zeroes_p): New decl. (repeated_svalue::all_zeroes_p): Convert decl to vfunc. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/pattern-test-2.c: Update expected results. * gcc.dg/plugin/analyzer_gil_plugin.c (gil_state_machine::on_condition): Remove. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c | 10 ++-------- gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c | 21 --------------------- 2 files changed, 2 insertions(+), 29 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c b/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c index f5424f5..7c8d1b3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/pattern-test-2.c @@ -25,11 +25,8 @@ void test_2 (void *p, void *q) return; foo(p); - /* { dg-warning "pattern match on 'tmp1 == 0'" "tmp1 == 0" { target *-*-* } cond_2 } */ - /* { dg-warning "pattern match on 'tmp2 == 0'" "tmp2 == 0" { target *-*-* } cond_2 } */ - /* { dg-warning "pattern match on ' == 0'" " == 0" { target *-*-* } cond_2 } */ - /* { dg-warning "pattern match on ' != 0'" " != 0" { target *-*-* } cond_2 } */ /* { dg-warning "pattern match on 'p != 0'" "p != 0" { target *-*-* } cond_2 } */ + /* { dg-warning "pattern match on 'tmp1 | tmp2 != 0'" "tmp1 | tmp2 != 0" { target *-*-* } cond_2 } */ /* { dg-warning "pattern match on 'q != 0'" "q != 0" { target *-*-* } cond_2 } */ } @@ -44,10 +41,7 @@ void test_3 (void *p, void *q) return; foo(p); - /* { dg-warning "pattern match on 'tmp1 != 0'" "tmp1 != 0" { target *-*-* } cond_3 } */ - /* { dg-warning "pattern match on 'tmp2 != 0'" "tmp2 != 0" { target *-*-* } cond_3 } */ - /* { dg-warning "pattern match on ' == 0'" " == 0" { target *-*-* } cond_3 } */ - /* { dg-warning "pattern match on ' != 0'" " != 0" { target *-*-* } cond_3 } */ /* { dg-warning "pattern match on 'p == 0'" "p == 0" { target *-*-* } cond_3 } */ + /* { dg-warning "pattern match on 'tmp1 & tmp2 == 0'" "tmp1 & tmp2 == 0" { target *-*-* } cond_3 } */ /* { dg-warning "pattern match on 'q == 0'" "q == 0" { target *-*-* } cond_3 } */ } diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c index 05133d5..61dd490 100644 --- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c @@ -53,13 +53,6 @@ public: const supernode *node, const gimple *stmt) const FINAL OVERRIDE; - void on_condition (sm_context *sm_ctxt, - const supernode *node, - const gimple *stmt, - tree lhs, - enum tree_code op, - tree rhs) const FINAL OVERRIDE; - bool can_purge_p (state_t s) const FINAL OVERRIDE; void check_for_pyobject_usage_without_gil (sm_context *sm_ctxt, @@ -365,20 +358,6 @@ gil_state_machine::on_stmt (sm_context *sm_ctxt, return false; } -/* Implementation of state_machine::on_condition vfunc for - gil_state_machine. */ - -void -gil_state_machine::on_condition (sm_context *sm_ctxt ATTRIBUTE_UNUSED, - const supernode *node ATTRIBUTE_UNUSED, - const gimple *stmt ATTRIBUTE_UNUSED, - tree lhs ATTRIBUTE_UNUSED, - enum tree_code op ATTRIBUTE_UNUSED, - tree rhs ATTRIBUTE_UNUSED) const -{ - // Empty -} - bool gil_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const { -- cgit v1.1 From 4c619132b3f14dc5e672a7f2f0e09cb784193559 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Thu, 8 Jul 2021 11:46:14 +0100 Subject: PR tree-optimization/40210: Fold (bswap(X)>>C1)&C2 to (X>>C3)&C2 in match.pd All of the optimizations/transformations mentioned in bugzilla for PR tree-optimization/40210 are already implemented in mainline GCC, with one exception. In comment #5, there's a suggestion that (bswap64(x)>>56)&0xff can be implemented without the bswap as (unsigned char)x, or equivalently x&0xff. This patch implements the above optimization, and closely related variants. For any single bit, (bswap(X)>>C1)&1 can be simplified to (X>>C2)&1, where bit position C2 is the appropriate permutation of C1. Similarly, the bswap can eliminated if the desired set of bits all lie within the same byte, hence (bswap(x)>>8)&255 can always be optimized, as can (bswap(x)>>8)&123. Previously, int foo(long long x) { return (__builtin_bswap64(x) >> 56) & 0xff; } compiled with -O2 to foo: movq %rdi, %rax bswap %rax shrq $56, %rax ret with this patch, it now compiles to foo: movzbl %dil, %eax ret 2021-07-08 Roger Sayle Richard Biener gcc/ChangeLog PR tree-optimization/40210 * match.pd (bswap optimizations): Simplify (bswap(x)>>C1)&C2 as (x>>C3)&C2 when possible. Simplify bswap(x)>>C1 as ((T)x)>>C2 when possible. Simplify bswap(x)&C1 as (x>>C2)&C1 when 0<=C1<=255. gcc/testsuite/ChangeLog PR tree-optimization/40210 * gcc.dg/builtin-bswap-13.c: New test. * gcc.dg/builtin-bswap-14.c: New test. --- gcc/testsuite/gcc.dg/builtin-bswap-13.c | 329 ++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/builtin-bswap-14.c | 302 +++++++++++++++++++++++++++++ 2 files changed, 631 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/builtin-bswap-13.c create mode 100644 gcc/testsuite/gcc.dg/builtin-bswap-14.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-13.c b/gcc/testsuite/gcc.dg/builtin-bswap-13.c new file mode 100644 index 0000000..6dc4c15 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-bswap-13.c @@ -0,0 +1,329 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int test_s32_0_1(int x) { return __builtin_bswap32(x) & 1; } +int test_s32_0_2(int x) { return __builtin_bswap32(x) & 2; } +int test_s32_0_240(int x) { return __builtin_bswap32(x) & 240; } +int test_s32_0_255(int x) { return __builtin_bswap32(x) & 255; } +int test_s32_1_1(int x) { return (__builtin_bswap32(x) >> 1) & 1; } +int test_s32_7_1(int x) { return (__builtin_bswap32(x) >> 7) & 1; } +int test_s32_8_1(int x) { return (__builtin_bswap32(x) >> 8) & 1; } +int test_s32_8_240(int x) { return (__builtin_bswap32(x) >> 8) & 240; } +int test_s32_8_255(int x) { return (__builtin_bswap32(x) >> 8) & 255; } +int test_s32_15_1(int x) { return (__builtin_bswap32(x) >> 15) & 1; } +int test_s32_16_1(int x) { return (__builtin_bswap32(x) >> 16) & 1; } +int test_s32_16_240(int x) { return (__builtin_bswap32(x) >> 16) & 240; } +int test_s32_16_255(int x) { return (__builtin_bswap32(x) >> 16) & 255; } +int test_s32_24_1(int x) { return (__builtin_bswap32(x) >> 24) & 1; } +int test_s32_24_240(int x) { return (__builtin_bswap32(x) >> 24) & 240; } +int test_s32_24_255(int x) { return (__builtin_bswap32(x) >> 24) & 255; } +int test_s32_31_1(int x) { return (__builtin_bswap32(x) >> 31) & 1; } + +int test_S32_0_1(int x) { return (int)__builtin_bswap32(x) & 1; } +int test_S32_0_2(int x) { return (int)__builtin_bswap32(x) & 2; } +int test_S32_0_240(int x) { return (int)__builtin_bswap32(x) & 240; } +int test_S32_0_255(int x) { return (int)__builtin_bswap32(x) & 255; } +int test_S32_1_1(int x) { return ((int)__builtin_bswap32(x) >> 1) & 1; } +int test_S32_7_1(int x) { return ((int)__builtin_bswap32(x) >> 7) & 1; } +int test_S32_8_1(int x) { return ((int)__builtin_bswap32(x) >> 8) & 1; } +int test_S32_8_240(int x) { return ((int)__builtin_bswap32(x) >> 8) & 240; } +int test_S32_8_255(int x) { return ((int)__builtin_bswap32(x) >> 8) & 255; } +int test_S32_15_1(int x) { return ((int)__builtin_bswap32(x) >> 15) & 1; } +int test_S32_16_1(int x) { return ((int)__builtin_bswap32(x) >> 16) & 1; } +int test_S32_16_240(int x) { return ((int)__builtin_bswap32(x) >> 16) & 240; } +int test_S32_16_255(int x) { return ((int)__builtin_bswap32(x) >> 16) & 255; } +int test_S32_24_1(int x) { return ((int)__builtin_bswap32(x) >> 24) & 1; } +int test_S32_24_240(int x) { return ((int)__builtin_bswap32(x) >> 24) & 240; } +int test_S32_24_255(int x) { return ((int)__builtin_bswap32(x) >> 24) & 255; } +int test_S32_31_1(int x) { return ((int)__builtin_bswap32(x) >> 31) & 1; } + +unsigned int test_u32_24_255(unsigned int x) { + return (__builtin_bswap32(x) >> 24) & 255; +} + +long long test_s64_0_1(long long x) { + return __builtin_bswap64(x) & 1; +} +long long test_s64_0_2(long long x) { + return __builtin_bswap64(x) & 2; +} +long long test_s64_0_240(long long x) { + return __builtin_bswap64(x) & 240; +} +long long test_s64_0_255(long long x) { + return __builtin_bswap64(x) & 255; +} +long long test_s64_7_1(long long x) { + return (__builtin_bswap64(x) >> 7) & 1; +} +long long test_s64_8_1(long long x) { + return (__builtin_bswap64(x) >> 8) & 1; +} +long long test_s64_8_240(long long x) { + return (__builtin_bswap64(x) >> 56) & 240; +} +long long test_s64_8_255(long long x) { + return (__builtin_bswap64(x) >> 8) & 255; +} +long long test_s64_9_1(long long x) { + return (__builtin_bswap64(x) >> 9) & 1; +} +long long test_s64_31_1(long long x) { + return (__builtin_bswap64(x) >> 31) & 1; +} +long long test_s64_32_1(long long x) { + return (__builtin_bswap64(x) >> 32) & 1; +} +long long test_s64_32_240(long long x) { + return (__builtin_bswap64(x) >> 32) & 240; +} +long long test_s64_32_255(long long x) { + return (__builtin_bswap64(x) >> 32) & 255; +} +long long test_s64_33_1(long long x) { + return (__builtin_bswap64(x) >> 33) & 1; +} +long long test_s64_48_1(long long x) { + return (__builtin_bswap64(x) >> 48) & 1; +} +long long test_s64_48_240(long long x) { + return (__builtin_bswap64(x) >> 48) & 240; +} +long long test_s64_48_255(long long x) { + return (__builtin_bswap64(x) >> 48) & 255; +} +long long test_s64_56_1(long long x) { + return (__builtin_bswap64(x) >> 56) & 1; +} +long long test_s64_56_240(long long x) { + return (__builtin_bswap64(x) >> 56) & 240; +} +long long test_s64_56_255(long long x) { + return (__builtin_bswap64(x) >> 56) & 255; +} +long long test_s64_57_1(long long x) { + return (__builtin_bswap64(x) >> 57) & 1; +} +long long test_s64_63_1(long long x) { + return (__builtin_bswap64(x) >> 63) & 1; +} + +long long test_S64_0_1(long long x) { + return (long long)__builtin_bswap64(x) & 1; +} +long long test_S64_0_2(long long x) { + return (long long)__builtin_bswap64(x) & 2; +} +long long test_S64_0_240(long long x) { + return (long long)__builtin_bswap64(x) & 240; +} +long long test_S64_0_255(long long x) { + return (long long)__builtin_bswap64(x) & 255; +} +long long test_S64_7_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 7) & 1; +} +long long test_S64_8_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 8) & 1; +} +long long test_S64_8_240(long long x) { + return ((long long)__builtin_bswap64(x) >> 56) & 240; +} +long long test_S64_8_255(long long x) { + return ((long long)__builtin_bswap64(x) >> 8) & 255; +} +long long test_S64_9_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 9) & 1; +} +long long test_S64_31_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 31) & 1; +} +long long test_S64_32_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 32) & 1; +} +long long test_S64_32_240(long long x) { + return ((long long)__builtin_bswap64(x) >> 32) & 240; +} +long long test_S64_32_255(long long x) { + return ((long long)__builtin_bswap64(x) >> 32) & 255; +} +long long test_S64_33_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 33) & 1; +} +long long test_S64_48_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 48) & 1; +} +long long test_S64_48_240(long long x) { + return ((long long)__builtin_bswap64(x) >> 48) & 240; +} +long long test_S64_48_255(long long x) { + return ((long long)__builtin_bswap64(x) >> 48) & 255; +} +long long test_S64_56_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 56) & 1; +} +long long test_S64_56_240(long long x) { + return ((long long)__builtin_bswap64(x) >> 56) & 240; +} +long long test_S64_56_255(long long x) { + return ((long long)__builtin_bswap64(x) >> 56) & 255; +} +long long test_S64_57_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 57) & 1; +} +long long test_S64_63_1(long long x) { + return ((long long)__builtin_bswap64(x) >> 63) & 1; +} + +unsigned long long test_u64_56_255(unsigned long long x) { + return (__builtin_bswap64(x) >> 56) & 255; +} + +short test_s16_0_1(short x) { + return __builtin_bswap16(x) & 1; +} +short test_s16_0_240(short x) { + return __builtin_bswap16(x) & 240; +} +short test_s16_0_255(short x) { + return __builtin_bswap16(x) & 255; +} +short test_s16_1_1(short x) { + return (__builtin_bswap16(x) >> 1) & 1; +} +short test_s16_7_1(short x) { + return (__builtin_bswap16(x) >> 7) & 1; +} +short test_s16_8_1(short x) { + return (__builtin_bswap16(x) >> 8) & 1; +} +short test_s16_8_240(short x) { + return (__builtin_bswap16(x) >> 8) & 240; +} +short test_s16_8_255(short x) { + return (__builtin_bswap16(x) >> 8) & 255; +} +short test_s16_9_1(short x) { + return (__builtin_bswap16(x) >> 9) & 1; +} +short test_s16_15_1(short x) { + return (__builtin_bswap16(x) >> 15) & 1; +} + +short test_S16_0_1(short x) { + return (short)__builtin_bswap16(x) & 1; +} +short test_S16_0_240(short x) { + return (short)__builtin_bswap16(x) & 240; +} +short test_S16_0_255(short x) { + return (short)__builtin_bswap16(x) & 255; +} +short test_S16_1_1(short x) { + return ((short)__builtin_bswap16(x) >> 1) & 1; +} +short test_S16_7_1(short x) { + return ((short)__builtin_bswap16(x) >> 7) & 1; +} +short test_S16_8_1(short x) { + return ((short)__builtin_bswap16(x) >> 8) & 1; +} +short test_S16_8_240(short x) { + return ((short)__builtin_bswap16(x) >> 8) & 240; +} +short test_S16_8_255(short x) { + return ((short)__builtin_bswap16(x) >> 8) & 255; +} +short test_S16_9_1(short x) { + return ((short)__builtin_bswap16(x) >> 9) & 1; +} +short test_S16_15_1(short x) { + return ((short)__builtin_bswap16(x) >> 15) & 1; +} + +unsigned short test_u16_8_255(unsigned short x) { + return (__builtin_bswap16(x) >> 8) & 255; +} + + +/* Shifts only */ +int test_s32_24(int x) { + return __builtin_bswap32(x) >> 24; +} +int test_s32_25(int x) { + return __builtin_bswap32(x) >> 25; +} +int test_s32_30(int x) { + return __builtin_bswap32(x) >> 30; +} +int test_s32_31(int x) { + return __builtin_bswap32(x) >> 31; +} + +unsigned int test_u32_24(unsigned int x) { + return __builtin_bswap32(x) >> 24; +} +unsigned int test_u32_25(unsigned int x) { + return __builtin_bswap32(x) >> 25; +} +unsigned int test_u32_30(unsigned int x) { + return __builtin_bswap32(x) >> 30; +} +unsigned int test_u32_31(unsigned int x) { + return __builtin_bswap32(x) >> 31; +} + +long long test_s64_56(long long x) { + return __builtin_bswap64(x) >> 56; +} +long long test_s64_57(long long x) { + return __builtin_bswap64(x) >> 57; +} +long long test_s64_62(long long x) { + return __builtin_bswap64(x) >> 62; +} +long long test_s64_63(long long x) { + return __builtin_bswap64(x) >> 63; +} + +unsigned long long test_u64_56(unsigned long long x) { + return __builtin_bswap64(x) >> 56; +} +unsigned long long test_u64_57(unsigned long long x) { + return __builtin_bswap64(x) >> 57; +} +unsigned long long test_u64_62(unsigned long long x) { + return __builtin_bswap64(x) >> 62; +} +unsigned long long test_u64_63(unsigned long long x) { + return __builtin_bswap64(x) >> 63; +} + +short test_s16_8(short x) { + return __builtin_bswap16(x) >> 8; +} +short test_s16_9(short x) { + return __builtin_bswap16(x) >> 9; +} +short test_s16_14(short x) { + return __builtin_bswap16(x) >> 14; +} +short test_s16_15(short x) { + return __builtin_bswap16(x) >> 15; +} + +unsigned short test_u16_8(unsigned short x) { + return __builtin_bswap16(x) >> 8; +} +unsigned short test_u16_9(unsigned short x) { + return __builtin_bswap16(x) >> 9; +} +unsigned short test_u16_14(unsigned short x) { + return __builtin_bswap16(x) >> 14; +} +unsigned short test_u16_15(unsigned short x) { + return __builtin_bswap16(x) >> 15; +} + +/* { dg-final { scan-tree-dump-not "__builtin_bswap" "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-14.c b/gcc/testsuite/gcc.dg/builtin-bswap-14.c new file mode 100644 index 0000000..62711d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-bswap-14.c @@ -0,0 +1,302 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + + +__attribute__ ((noinline, noclone)) +static int rt32 (int x, int y, int z) { + return (__builtin_bswap32(x) >> y) & z; +} +#define TEST32(X,Y,Z) if(((__builtin_bswap32(X)>>Y)&Z)!=rt32(X,Y,Z)) abort() +void test32(int x) +{ + TEST32(x,0,1); + TEST32(x,0,255); + TEST32(x,1,1); + TEST32(x,2,1); + TEST32(x,3,1); + TEST32(x,4,1); + TEST32(x,5,1); + TEST32(x,6,1); + TEST32(x,7,1); + TEST32(x,8,1); + TEST32(x,8,255); + TEST32(x,9,1); + TEST32(x,10,1); + TEST32(x,11,1); + TEST32(x,12,1); + TEST32(x,13,1); + TEST32(x,14,1); + TEST32(x,15,1); + TEST32(x,16,1); + TEST32(x,16,255); + TEST32(x,17,1); + TEST32(x,18,1); + TEST32(x,19,1); + TEST32(x,20,1); + TEST32(x,21,1); + TEST32(x,22,1); + TEST32(x,23,1); + TEST32(x,24,1); + TEST32(x,24,255); + TEST32(x,25,1); + TEST32(x,26,1); + TEST32(x,27,1); + TEST32(x,28,1); + TEST32(x,29,1); + TEST32(x,30,1); + TEST32(x,31,1); +} + +#if __SIZEOF_LONG_LONG__ == 8 +__attribute__ ((noinline, noclone)) +static long long rt64 (long long x, int y, long long z) { + return (__builtin_bswap64(x) >> y) & z; +} +#define TEST64(X,Y,Z) if(((__builtin_bswap64(X)>>Y)&Z)!=rt64(X,Y,Z)) abort() +void test64(long long x) +{ + TEST64(x,0,1); + TEST64(x,0,255); + TEST64(x,1,1); + TEST64(x,2,1); + TEST64(x,3,1); + TEST64(x,4,1); + TEST64(x,5,1); + TEST64(x,6,1); + TEST64(x,7,1); + TEST64(x,8,1); + TEST64(x,8,255); + TEST64(x,9,1); + TEST64(x,10,1); + TEST64(x,11,1); + TEST64(x,12,1); + TEST64(x,13,1); + TEST64(x,14,1); + TEST64(x,15,1); + TEST64(x,16,1); + TEST64(x,16,255); + TEST64(x,17,1); + TEST64(x,18,1); + TEST64(x,19,1); + TEST64(x,20,1); + TEST64(x,21,1); + TEST64(x,22,1); + TEST64(x,23,1); + TEST64(x,24,1); + TEST64(x,24,255); + TEST64(x,25,1); + TEST64(x,26,1); + TEST64(x,27,1); + TEST64(x,28,1); + TEST64(x,29,1); + TEST64(x,30,1); + TEST64(x,31,1); + TEST64(x,32,1); + TEST64(x,32,255); + TEST64(x,33,1); + TEST64(x,34,1); + TEST64(x,35,1); + TEST64(x,36,1); + TEST64(x,37,1); + TEST64(x,38,1); + TEST64(x,39,1); + TEST64(x,40,1); + TEST64(x,40,255); + TEST64(x,41,1); + TEST64(x,42,1); + TEST64(x,43,1); + TEST64(x,44,1); + TEST64(x,45,1); + TEST64(x,46,1); + TEST64(x,47,1); + TEST64(x,48,1); + TEST64(x,48,255); + TEST64(x,49,1); + TEST64(x,50,1); + TEST64(x,51,1); + TEST64(x,52,1); + TEST64(x,53,1); + TEST64(x,54,1); + TEST64(x,55,1); + TEST64(x,56,1); + TEST64(x,56,255); + TEST64(x,57,1); + TEST64(x,58,1); + TEST64(x,59,1); + TEST64(x,60,1); + TEST64(x,61,1); + TEST64(x,62,1); + TEST64(x,63,1); +} +#endif + +__attribute__ ((noinline, noclone)) +static int rt16 (int x, int y, int z) { + return (__builtin_bswap16(x) >> y) & z; +} +#define TEST16(X,Y,Z) if(((__builtin_bswap16(X)>>Y)&Z)!=rt16(X,Y,Z)) abort() +void test16(int x) +{ + TEST16(x,0,1); + TEST16(x,0,255); + TEST16(x,1,1); + TEST16(x,2,1); + TEST16(x,3,1); + TEST16(x,4,1); + TEST16(x,5,1); + TEST16(x,6,1); + TEST16(x,7,1); + TEST16(x,8,1); + TEST16(x,8,255); + TEST16(x,9,1); + TEST16(x,10,1); + TEST16(x,11,1); + TEST16(x,12,1); + TEST16(x,13,1); + TEST16(x,14,1); + TEST16(x,15,1); +} + +int main() +{ + test32(0x00000000); + test32(0xffffffff); + test32(0x00000001); + test32(0x00000002); + test32(0x00000004); + test32(0x00000008); + test32(0x00000010); + test32(0x00000020); + test32(0x00000040); + test32(0x00000080); + test32(0x00000100); + test32(0x00000200); + test32(0x00000400); + test32(0x00000800); + test32(0x00001000); + test32(0x00002000); + test32(0x00004000); + test32(0x00008000); + test32(0x00010000); + test32(0x00020000); + test32(0x00040000); + test32(0x00080000); + test32(0x00100000); + test32(0x00200000); + test32(0x00400000); + test32(0x00800000); + test32(0x01000000); + test32(0x02000000); + test32(0x04000000); + test32(0x08000000); + test32(0x10000000); + test32(0x20000000); + test32(0x40000000); + test32(0x80000000); + test32(0x12345678); + test32(0x87654321); + test32(0xdeadbeef); + test32(0xcafebabe); + +#if __SIZEOF_LONG_LONG__ == 8 + test64(0x0000000000000000ll); + test64(0xffffffffffffffffll); + test64(0x0000000000000001ll); + test64(0x0000000000000002ll); + test64(0x0000000000000004ll); + test64(0x0000000000000008ll); + test64(0x0000000000000010ll); + test64(0x0000000000000020ll); + test64(0x0000000000000040ll); + test64(0x0000000000000080ll); + test64(0x0000000000000100ll); + test64(0x0000000000000200ll); + test64(0x0000000000000400ll); + test64(0x0000000000000800ll); + test64(0x0000000000001000ll); + test64(0x0000000000002000ll); + test64(0x0000000000004000ll); + test64(0x0000000000008000ll); + test64(0x0000000000010000ll); + test64(0x0000000000020000ll); + test64(0x0000000000040000ll); + test64(0x0000000000080000ll); + test64(0x0000000000100000ll); + test64(0x0000000000200000ll); + test64(0x0000000000400000ll); + test64(0x0000000000800000ll); + test64(0x0000000001000000ll); + test64(0x0000000002000000ll); + test64(0x0000000004000000ll); + test64(0x0000000008000000ll); + test64(0x0000000010000000ll); + test64(0x0000000020000000ll); + test64(0x0000000040000000ll); + test64(0x0000000080000000ll); + test64(0x0000000100000000ll); + test64(0x0000000200000000ll); + test64(0x0000000400000000ll); + test64(0x0000000800000000ll); + test64(0x0000001000000000ll); + test64(0x0000002000000000ll); + test64(0x0000004000000000ll); + test64(0x0000008000000000ll); + test64(0x0000010000000000ll); + test64(0x0000020000000000ll); + test64(0x0000040000000000ll); + test64(0x0000080000000000ll); + test64(0x0000100000000000ll); + test64(0x0000200000000000ll); + test64(0x0000400000000000ll); + test64(0x0000800000000000ll); + test64(0x0001000000000000ll); + test64(0x0002000000000000ll); + test64(0x0004000000000000ll); + test64(0x0008000000000000ll); + test64(0x0010000000000000ll); + test64(0x0020000000000000ll); + test64(0x0040000000000000ll); + test64(0x0080000000000000ll); + test64(0x0100000000000000ll); + test64(0x0200000000000000ll); + test64(0x0400000000000000ll); + test64(0x0800000000000000ll); + test64(0x1000000000000000ll); + test64(0x2000000000000000ll); + test64(0x4000000000000000ll); + test64(0x8000000000000000ll); + test64(0x0123456789abcdefll); + test64(0xfedcba9876543210ll); + test64(0xdeadbeefdeadbeefll); + test64(0xcafebabecafebabell); +#endif + + test16(0x0000); + test16(0xffff); + test16(0x0001); + test16(0x0002); + test16(0x0004); + test16(0x0008); + test16(0x0010); + test16(0x0020); + test16(0x0040); + test16(0x0080); + test16(0x0100); + test16(0x0200); + test16(0x0400); + test16(0x0800); + test16(0x1000); + test16(0x2000); + test16(0x4000); + test16(0x8000); + test16(0x1234); + test16(0x4321); + test16(0xdead); + test16(0xbeef); + test16(0xcafe); + test16(0xbabe); + + return 0; +} -- cgit v1.1 From 1ca642d785c49e9e0b28651b190720267703f023 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 30 Jun 2021 13:47:07 +0000 Subject: testsuite: Add arm_arch_v7a_ok effective-target to pr57351.c I've noticed that overriding cpu/arch flags when running the testsuite can cause this test to fail rather than being skipped because of incompatible flags combination. Since the test forces -march=armv7-a, make sure it is accepted in combination with the current runtestflags. 2021-07-08 Christophe Lyon gcc/testsuite/ * gcc.dg/debug/pr57351.c: Require arm_arch_v7a_ok effective-target. --- gcc/testsuite/gcc.dg/debug/pr57351.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/pr57351.c b/gcc/testsuite/gcc.dg/debug/pr57351.c index 972f3e9..236d74d 100644 --- a/gcc/testsuite/gcc.dg/debug/pr57351.c +++ b/gcc/testsuite/gcc.dg/debug/pr57351.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_neon } */ +/* { dg-require-effective-target arm_arch_v7a_ok } */ /* { dg-options "-std=c99 -Os -g -march=armv7-a" } */ /* { dg-add-options arm_neon } */ -- cgit v1.1 From 763121ccd908f52bc666f277ea2cf42110b3aad9 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Thu, 8 Jul 2021 19:44:41 +0200 Subject: ipa-sra: Fix thinko when overriding safe_to_import_accesses (PR 101066) The "new" IPA-SRA has a more difficult job than the previous not-truly-IPA version when identifying situations in which a parameter passed by reference can be passed into a third function and only thee converted to one passed by value (and possibly "split" at the same time). In order to allow this, two conditions must be fulfilled. First the call to the third function must happen before any modifications of memory, because it could change the value passed by reference. Second, in order to make sure we do not introduce new (invalid) dereferences, the call must postdominate the entry BB. The second condition is actually not necessary if the caller function is also certain to dereference the pointer but the first one must still hold. Unfortunately, the code making this overriding decision also happen to trigger when the first condition is not fulfilled. This is fixed in the following patch. gcc/ChangeLog: 2021-06-16 Martin Jambor PR ipa/101066 * ipa-sra.c (class isra_call_summary): New member m_before_any_store, initialize it in the constructor. (isra_call_summary::dump): Dump the new field. (ipa_sra_call_summaries::duplicate): Copy it. (process_scan_results): Set it. (isra_write_edge_summary): Stream it. (isra_read_edge_summary): Likewise. (param_splitting_across_edge): Only override safe_to_import_accesses if m_before_any_store is set. gcc/testsuite/ChangeLog: 2021-06-16 Martin Jambor PR ipa/101066 * gcc.dg/ipa/pr101066.c: New test. --- gcc/testsuite/gcc.dg/ipa/pr101066.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr101066.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/pr101066.c b/gcc/testsuite/gcc.dg/ipa/pr101066.c new file mode 100644 index 0000000..1ceb6e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr101066.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-ipa-cp -fno-inline" } */ + +int a = 1, c, d, e; +int *b = &a; +static int g(int *h) { + c = *h; + return d; +} +static void f(int *h) { + e = *h; + *b = 0; + g(h); +} +int main() { + f(b); + if (c) + __builtin_abort(); + return 0; +} -- cgit v1.1 From 68b938fada4c728c0b850b44125d9a173c01c8fb Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 8 Jul 2021 16:22:25 -0600 Subject: testsuite: Remove an xfail. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-43.c: Remove an xfail. --- gcc/testsuite/gcc.dg/Wstringop-overflow-43.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c index 14ab925..6d045c5 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c @@ -167,9 +167,7 @@ void warn_memset_reversed_range (void) /* The following are represented as ordinary ranges with reversed bounds and those are handled. */ T1 (p, SAR (INT_MIN, 11), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } - /* In ILP32 the offset in the following has no range info associated - with it. */ - T1 (p, SAR (INT_MIN, 1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" "pr?????" { xfail ilp32 } } + T1 (p, SAR (INT_MIN, 1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } T1 (p, SAR (INT_MIN, 0), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } /* Also represented as a true anti-range. */ T1 (p, SAR ( -12, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" } -- cgit v1.1 From 37e65643d3e32d33bb6c9d15c678a627d1682626 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Fri, 9 Jul 2021 09:03:08 -0700 Subject: testsuite/101269: fix testcase when used with -m32 PR testsuite/101269 - new test case gcc.dg/debug/btf/btf-datasec-1.c fails with its introduction in r12-1852 BTF datasec records for .rodata/.data are expected for now for all targets. For powerpc based targets, use -msdata=none when ilp32 is enabled. 2021-07-09 Indu Bhagat gcc/testsuite/ChangeLog: PR testsuite/101269 * gcc.dg/debug/btf/btf-datasec-1.c: Force -msdata=none with ilp32 for powerpc based targets. --- gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c index 88ae4c4..f809d93 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c @@ -11,6 +11,7 @@ /* { dg-do compile ) */ /* { dg-options "-O0 -gbtf -dA" } */ +/* { dg-options "-O0 -gbtf -dA -msdata=none" { target { { powerpc*-*-* } && ilp32 } } } */ /* Check for two DATASEC entries with vlen 3, and one with vlen 1. */ /* { dg-final { scan-assembler-times "0xf000003\[\t \]+\[^\n\]*btt_info" 2 } } */ -- cgit v1.1 From 7466a0a5d8d536ab15f9732ec0ca331df972b3ac Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sat, 10 Jul 2021 16:20:32 +0000 Subject: Require target lra for tests using asm goto gcc/testsuite/ChangeLog: * gcc.dg/torture/pr100329.c: Require target lra. * gcc.dg/torture/pr100519.c: Likewise. --- gcc/testsuite/gcc.dg/torture/pr100329.c | 2 +- gcc/testsuite/gcc.dg/torture/pr100519.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr100329.c b/gcc/testsuite/gcc.dg/torture/pr100329.c index b90700d..2a4331b 100644 --- a/gcc/testsuite/gcc.dg/torture/pr100329.c +++ b/gcc/testsuite/gcc.dg/torture/pr100329.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target lra } } */ /* { dg-additional-options "--param tree-reassoc-width=2" } */ unsigned int a0; diff --git a/gcc/testsuite/gcc.dg/torture/pr100519.c b/gcc/testsuite/gcc.dg/torture/pr100519.c index faf6e24..89dff66 100644 --- a/gcc/testsuite/gcc.dg/torture/pr100519.c +++ b/gcc/testsuite/gcc.dg/torture/pr100519.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target lra } } */ /* { dg-additional-options "--param tree-reassoc-width=2" } */ unsigned int foo_a1, foo_a2; -- cgit v1.1 From 5f5fbb550af7d9d6cb56ae8f607fea0eccaa9295 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 12 Jul 2021 08:24:27 +0100 Subject: PR tree-optimization/101403: Incorrect folding of ((T)bswap(x))>>C My sincere apologies for the breakage. My recent patch to fold bswapN(x)>>C where the constant C was large enough that the result only contains bits from the low byte, and can therefore avoid the byte swap contains a minor logic error. The pattern contains a convert? allowing an extension to occur between the bswap and the shift. The logic is correct if there's no extension, or the extension has the same sign as the shift, but I'd mistakenly convinced myself that these couldn't have different signedness. (T)bswap16(x)>>12 is (T)((unsigned char)x>>4) or (T)((signed char)x>>4). The bug is that for zero-extensions to signed type T, we need to use the unsigned char variant [the signedness of the byte shift is not (always) the same as the signedness of T and the original shift]. Then because I'm now paranoid, I've also added a clause to handle the hypothetical (but in practice impossible) sign-extension to an unsigned type T, which can implemented as (T)(x<<8)>>12. 2021-07-12 Roger Sayle gcc/ChangeLog PR tree-optimization/101403 * match.pd ((T)bswap(X)>>C): Correctly handle cases where signedness of the shift is not the same as the signedness of the type extension. gcc/testsuite/ChangeLog PR tree-optimization/101403 * gcc.dg/pr101403.c: New test case. --- gcc/testsuite/gcc.dg/pr101403.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101403.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101403.c b/gcc/testsuite/gcc.dg/pr101403.c new file mode 100644 index 0000000..ac5fa79 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101403.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +unsigned int foo (unsigned int a) +{ + unsigned int u; + unsigned short b = __builtin_bswap16 (a); + return b >> (u, 12); +} + +int main (void) +{ + unsigned int x = foo (0x80); + if (x != 0x0008) + __builtin_abort (); + return 0; +} + -- cgit v1.1 From 0192c3eedbc7e6fe703abd8b321f400ddb02adf7 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 12 Jul 2021 10:59:08 +0100 Subject: Tweak testcase for PR tree-optimization/101403. Initialize unused variable u in compound expression. Committed as obvious. 2021-07-12 Roger Sayle Jakub Jelinek gcc/testsuite/ChangeLog PR tree-optimization/101403 * gcc.dg/pr101403.c: Avoid (unimportant) uninitialized variable. --- gcc/testsuite/gcc.dg/pr101403.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101403.c b/gcc/testsuite/gcc.dg/pr101403.c index ac5fa79..88df112 100644 --- a/gcc/testsuite/gcc.dg/pr101403.c +++ b/gcc/testsuite/gcc.dg/pr101403.c @@ -2,7 +2,7 @@ /* { dg-options "-O2" } */ unsigned int foo (unsigned int a) { - unsigned int u; + unsigned int u = 0; unsigned short b = __builtin_bswap16 (a); return b >> (u, 12); } -- cgit v1.1 From 92343e0ba4d47f21ae20ffcb83d736bdbc15dae0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 12 Jul 2021 10:49:03 +0200 Subject: tree-optimization/101394 - fix PRE full redundancy wrt abnormals This avoids adding a copy from an abnormal picked up from PHI translation much like we'd avoid inserting the translated expression on pred edges. 2021-07-12 Richard Biener PR tree-optimization/101394 * tree-ssa-pre.c (do_pre_regular_insertion): Avoid inserting copies from abnormals for a full redundancy. * gcc.dg/torture/pr101394.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101394.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101394.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101394.c b/gcc/testsuite/gcc.dg/torture/pr101394.c new file mode 100644 index 0000000..87fbdad --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101394.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +int a, b, c, d; +void h(); +int e() __attribute__((returns_twice)); +void f() { + int *g = (int *)(__INTPTR_TYPE__)c; + if (b) { + h(); + g--; + if (a) + if (d) + h(); + } + if (g++) + e(); + c = (__INTPTR_TYPE__)g; +} -- cgit v1.1 From c03cae4e066066278c8435c409829a9bf851e49f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 7 Jul 2021 11:45:43 +0200 Subject: Display the number of components BB vectorized This amends the optimization message printed when a basic-block part is vectorized to mention the number of SLP graph entries. This helps when debugging vectorization differences and we end up merging SLP instances for costing purposes. 2021-07-07 Richard Biener * tree-vect-slp.c (vect_slp_region): Show the number of SLP graph entries in the optimization message. * g++.dg/vect/slp-pr87105.cc: Adjust. * gcc.dg/vect/bb-slp-pr54400.c: Likewise. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c index 6b427aa..7c46fa0 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c @@ -39,5 +39,5 @@ main () } /* We are lacking an effective target for .REDUC_PLUS support. */ -/* { dg-final { scan-tree-dump-times "basic block part vectorized" 3 "slp2" { target x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "optimized: basic block part" 3 "slp2" { target x86_64-*-* } } } */ /* { dg-final { scan-tree-dump-not " = VEC_PERM_EXPR" "slp2" { target x86_64-*-* } } } */ -- cgit v1.1 From 3f2338b4706cdc53ab276b9a5fed7f6927404f07 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Thu, 8 Jul 2021 19:23:35 -0700 Subject: [PHIOPT/MATCH] Remove the statement to move if not used Instead of waiting for DCE to remove the unused statement, and maybe optimize another conditional, it is better if we don't move the statement and have the statement removed. OK? Bootstrapped and tested on x86_64-linux-gnu. Changes from v1: * v2: Change the order of insertation and check to see if the lhs is used rather than see if the lhs was used in the sequence. gcc/ChangeLog: * tree-ssa-phiopt.c (match_simplify_replacement): Move insert of the sequence before the movement of the statement. Check if to see if the statement is used outside of the original phi to see if we should move it. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr96928-1.c: Update to similar as pr96928.c. --- gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c index 2e86620..9e505ac 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c @@ -2,7 +2,10 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */ /* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ -/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ +/* The following check is done at optimized because a ^ (~b) is rewritten as ~(a^b) + and in the case of match.pd optimizing these ?:, the ~ is moved out already + by the time we get to phiopt2. */ +/* { dg-final { scan-tree-dump-times "c_\[0-9]*\\\(D\\\) \\\^" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times " = ~" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ -- cgit v1.1 From a1539b797a06e03b08e1f1de28ad0d19a3956616 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 12 Jul 2021 11:38:17 -0400 Subject: Do not register a cast as an equivalence. Registering an equivalence between objects of the same size in a cast can cause other relations to be incorrect. gcc/ PR tree-optimization/101335 * range-op.cc (operator_cast::lhs_op1_relation): Delete. gcc/testsuite/ * gcc.dg/tree-ssa/pr101335.c: New. --- gcc/testsuite/gcc.dg/tree-ssa/pr101335.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr101335.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101335.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101335.c new file mode 100644 index 0000000..921362c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101335.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +unsigned a = 0xFFFFFFFF; +int b; +int main() +{ + int c = ~a; + unsigned d = c - 10; + if (d > c) + c = 20; + b = -(c | 0); + if (b > -8) + __builtin_abort (); + return 0; +} + -- cgit v1.1 From 063eba7ca73030139a3bf822ed127cf09b2fc226 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Tue, 13 Jul 2021 00:36:43 -0400 Subject: Deal with prefixed loads/stores in tests, PR testsuite/100166 This patch updates the various tests in the testsuite to treat plxv and pstxv as being vector loads/stores. This shows up if you run the testsuite with a compiler configured with the option: --with-cpu=power10. 2021-07-13 Michael Meissner gcc/testsuite/ PR testsuite/100166 * gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a-pr63175.c: Update insn counts to account for power10 prefixed loads and stores. * gcc.target/powerpc/fold-vec-load-builtin_vec_xl-char.c: Likewise. * gcc.target/powerpc/fold-vec-load-builtin_vec_xl-double.c: Likewise. * gcc.target/powerpc/fold-vec-load-builtin_vec_xl-float.c: Likewise. * gcc.target/powerpc/fold-vec-load-builtin_vec_xl-int.c: Likewise. * gcc.target/powerpc/fold-vec-load-builtin_vec_xl-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-load-builtin_vec_xl-short.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_vsx_ld-char.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_vsx_ld-double.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_vsx_ld-float.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_vsx_ld-int.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_vsx_ld-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_vsx_ld-short.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_xl-char.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_xl-double.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_xl-float.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_xl-int.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_xl-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-load-vec_xl-short.c: Likewise. * gcc.target/powerpc/fold-vec-splat-floatdouble.c: Likewise. * gcc.target/powerpc/fold-vec-splat-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-store-builtin_vec_xst-char.c: Likewise. * gcc.target/powerpc/fold-vec-store-builtin_vec_xst-double.c: Likewise. * gcc.target/powerpc/fold-vec-store-builtin_vec_xst-float.c: Likewise. * gcc.target/powerpc/fold-vec-store-builtin_vec_xst-int.c: Likewise. * gcc.target/powerpc/fold-vec-store-builtin_vec_xst-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-store-builtin_vec_xst-short.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_vsx_st-char.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_vsx_st-double.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_vsx_st-float.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_vsx_st-int.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_vsx_st-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_vsx_st-short.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_xst-char.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_xst-double.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_xst-float.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_xst-int.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_xst-longlong.c: Likewise. * gcc.target/powerpc/fold-vec-store-vec_xst-short.c: Likewise. * gcc.target/powerpc/lvsl-lvsr.c: Likewise. * gcc.target/powerpc/pr86731-fwrapv-longlong.c: Likewise. --- gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a-pr63175.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a-pr63175.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a-pr63175.c index 246f38f..d9f173b 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a-pr63175.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a-pr63175.c @@ -25,6 +25,6 @@ main1 (void) with no word loads (lw, lwu, lwz, lwzu, or their indexed forms) or word stores (stw, stwu, stwx, stwux, or their indexed forms). */ -/* { dg-final { scan-assembler "\t(lvx|lxv|lvsr|stxv)" } } */ +/* { dg-final { scan-assembler "\t(lvx|lxv|lvsr|stxv|plxv|pstxv)" } } */ /* { dg-final { scan-assembler-not "\tlwz?u?x? " { xfail { powerpc-ibm-aix* } } } } */ /* { dg-final { scan-assembler-not "\tstwu?x? " } } */ -- cgit v1.1 From f546e2b6cc5c610ae18aac274d0d6493f2da3801 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 13 Jul 2021 08:04:34 +0200 Subject: Revert "Display the number of components BB vectorized" This reverts commit c03cae4e066066278c8435c409829a9bf851e49f. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c index 7c46fa0..6b427aa 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr54400.c @@ -39,5 +39,5 @@ main () } /* We are lacking an effective target for .REDUC_PLUS support. */ -/* { dg-final { scan-tree-dump-times "optimized: basic block part" 3 "slp2" { target x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "basic block part vectorized" 3 "slp2" { target x86_64-*-* } } } */ /* { dg-final { scan-tree-dump-not " = VEC_PERM_EXPR" "slp2" { target x86_64-*-* } } } */ -- cgit v1.1 From dddb6ffdc5c25264dd75ad82dad8e48a0718d2d9 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 13 Jul 2021 11:04:22 +0200 Subject: passes: Fix up subobject __bos [PR101419] The following testcase is miscompiled, because VN during cunrolli changes __bos argument from address of a larger field to address of a smaller field and so __builtin_object_size (, 1) then folds into smaller value than the actually available size. copy_reference_ops_from_ref has a hack for this, but it was using cfun->after_inlining as a check whether the hack can be ignored, and cunrolli is after_inlining. This patch uses a property to make it exact (set at the end of objsz pass that doesn't do insert_min_max_p) and additionally based on discussions in the PR moves the objsz pass earlier after IPA. 2021-07-13 Jakub Jelinek Richard Biener PR tree-optimization/101419 * tree-pass.h (PROP_objsz): Define. (make_pass_early_object_sizes): Declare. * passes.def (pass_all_early_optimizations): Rename pass_object_sizes there to pass_early_object_sizes, drop parameter. (pass_all_optimizations): Move pass_object_sizes right after pass_ccp, drop parameter, move pass_post_ipa_warn right after that. * tree-object-size.c (pass_object_sizes::execute): Rename to... (object_sizes_execute): ... this. Add insert_min_max_p argument. (pass_data_object_sizes): Move after object_sizes_execute. (pass_object_sizes): Likewise. In execute method call object_sizes_execute, drop set_pass_param method and insert_min_max_p non-static data member and its initializer in the ctor. (pass_data_early_object_sizes, pass_early_object_sizes, make_pass_early_object_sizes): New. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Use (cfun->curr_properties & PROP_objsz) instead of cfun->after_inlining. * gcc.dg/builtin-object-size-10.c: Pass -fdump-tree-early_objsz-details instead of -fdump-tree-objsz1-details in dg-options and adjust names of dump file in scan-tree-dump. * gcc.dg/pr101419.c: New test. --- gcc/testsuite/gcc.dg/builtin-object-size-10.c | 6 +-- gcc/testsuite/gcc.dg/pr101419.c | 62 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr101419.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-10.c b/gcc/testsuite/gcc.dg/builtin-object-size-10.c index 2a212fa..bfcdf5c 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-10.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-10.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-objsz1-details" } */ +/* { dg-options "-O2 -fdump-tree-early_objsz-details" } */ // { dg-skip-if "packed attribute missing for drone_source_packet" { "epiphany-*-*" } } typedef struct { @@ -22,5 +22,5 @@ foo(char *x) return dpkt; } -/* { dg-final { scan-tree-dump "maximum object size 21" "objsz1" } } */ -/* { dg-final { scan-tree-dump "maximum subobject size 16" "objsz1" } } */ +/* { dg-final { scan-tree-dump "maximum object size 21" "early_objsz" } } */ +/* { dg-final { scan-tree-dump "maximum subobject size 16" "early_objsz" } } */ diff --git a/gcc/testsuite/gcc.dg/pr101419.c b/gcc/testsuite/gcc.dg/pr101419.c new file mode 100644 index 0000000..2cce383 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101419.c @@ -0,0 +1,62 @@ +/* PR tree-optimization/101419 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef __SIZE_TYPE__ size_t; +void baz (int, int) __attribute__((__warning__("detected overflow"))); + +union U { + int i; + char c; +}; + +static void +foo (union U *u) +{ + if (__builtin_object_size (&u->c, 1) < sizeof (u->c)) + baz (__builtin_object_size (&u->c, 1), sizeof (u->c)); /* { dg-bogus "detected overflow" } */ + __builtin_memset (&u->c, 0, sizeof (u->c)); + + if (__builtin_object_size (&u->i, 1) < sizeof (u->i)) + baz (__builtin_object_size (&u->i, 1), sizeof (u->i)); /* { dg-bogus "detected overflow" } */ + __builtin_memset (&u->i, 0, sizeof (u->i)); +} + +void +bar (union U *u) +{ + int i, j; + for (i = 0; i < 1; i++) + { + foo (u); + for (j = 0; j < 2; j++) + asm volatile (""); + } +} + +static void +qux (void *p, size_t q) +{ + if (__builtin_object_size (p, 1) < q) + baz (__builtin_object_size (p, 1), q); /* { dg-bogus "detected overflow" } */ + __builtin_memset (p, 0, q); +} + +static void +corge (union U *u) +{ + qux (&u->c, sizeof (u->c)); + qux (&u->i, sizeof (u->i)); +} + +void +garply (union U *u) +{ + int i, j; + for (i = 0; i < 1; i++) + { + corge (u); + for (j = 0; j < 2; j++) + asm volatile (""); + } +} -- cgit v1.1 From f75560398af6f1f696c820016f437af4e8b4265c Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 13 Jul 2021 09:41:30 -0400 Subject: Adjust testcase to test the call is removed. Ranger now handles the test. gcc/testsuite PR tree-optimization/93781 * gcc.dg/tree-ssa/pr93781-1.c: Check that call is removed. --- gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c index 5ebd805..b2505f3 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c @@ -12,7 +12,9 @@ void foo (unsigned int arg) if (a < 0) b = x; - /* In the fullness of time, we will delete this call. */ if (b >= 5) kill ();; } + +/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */ + -- cgit v1.1 From a967a3efd39280fe3f5774e45490e991f8e99059 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 14 Jul 2021 11:06:58 +0200 Subject: tree-optimization/101445 - fix negative stride SLP vect with gaps The following fixes the IV adjustment for the gap in a negative stride SLP vectorization. The adjustment was in the wrong direction, now fixes as in the patch. 2021-07-14 Richard Biener PR tree-optimization/101445 * tree-vect-stmts.c (vectorizable_load): Do the gap adjustment of the IV in the correct direction for negative stride accesses. * gcc.dg/vect/pr101445.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr101445.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr101445.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr101445.c b/gcc/testsuite/gcc.dg/vect/pr101445.c new file mode 100644 index 0000000..f8a6e9c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101445.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +int a[35] = { 1, 1, 3 }; + +void __attribute__((noipa)) +foo () +{ + for (int b = 4; b >= 0; b--) + { + int tem = a[b * 5 + 3 + 1]; + a[b * 5 + 3] = tem; + a[b * 5 + 2] = tem; + a[b * 5 + 1] = tem; + a[b * 5 + 0] = tem; + } +} + +int main() +{ + check_vect (); + foo (); + for (int d = 0; d < 25; d++) + if (a[d] != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 1e0ab1c4ba6159ad7ce71c6cddd5e04d2a636742 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Wed, 14 Jul 2021 15:21:40 +0100 Subject: middle-end: Add tests middle end generic tests for sign differing dotproduct. This adds testcases to test for auto-vect detection of the new sign differing dot product. gcc/ChangeLog: * doc/sourcebuild.texi (arm_v8_2a_i8mm_neon_hw): Document. gcc/testsuite/ChangeLog: * lib/target-supports.exp (check_effective_target_arm_v8_2a_imm8_neon_ok_nocache, check_effective_target_arm_v8_2a_i8mm_neon_hw, check_effective_target_vect_usdot_qi): New. * gcc.dg/vect/vect-reduc-dot-9.c: New test. * gcc.dg/vect/vect-reduc-dot-10.c: New test. * gcc.dg/vect/vect-reduc-dot-11.c: New test. * gcc.dg/vect/vect-reduc-dot-12.c: New test. * gcc.dg/vect/vect-reduc-dot-13.c: New test. * gcc.dg/vect/vect-reduc-dot-14.c: New test. * gcc.dg/vect/vect-reduc-dot-15.c: New test. * gcc.dg/vect/vect-reduc-dot-16.c: New test. * gcc.dg/vect/vect-reduc-dot-17.c: New test. * gcc.dg/vect/vect-reduc-dot-18.c: New test. * gcc.dg/vect/vect-reduc-dot-19.c: New test. * gcc.dg/vect/vect-reduc-dot-20.c: New test. * gcc.dg/vect/vect-reduc-dot-21.c: New test. * gcc.dg/vect/vect-reduc-dot-22.c: New test. --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c | 13 +++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c | 52 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c | 52 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c | 52 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c | 52 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c | 52 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c | 52 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c | 52 +++++++++++++++++++++++++++ 14 files changed, 455 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c new file mode 100644 index 0000000..7ce8696 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 unsigned +#define SIGNEDNESS_3 unsigned +#define SIGNEDNESS_4 signed + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c new file mode 100644 index 0000000..5e3cfc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 unsigned +#define SIGNEDNESS_4 signed + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c new file mode 100644 index 0000000..0841261 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c new file mode 100644 index 0000000..7ee0f45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 signed +#define SIGNEDNESS_2 unsigned +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c new file mode 100644 index 0000000..2de1434 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 signed +#define SIGNEDNESS_2 unsigned +#define SIGNEDNESS_3 unsigned +#define SIGNEDNESS_4 signed + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c new file mode 100644 index 0000000..5a6fd19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 signed +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 unsigned +#define SIGNEDNESS_4 signed + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c new file mode 100644 index 0000000..aec6287 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#define SIGNEDNESS_1 signed +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned + +#include "vect-reduc-dot-9.c" + +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c new file mode 100644 index 0000000..aa269c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 unsigned +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 int __attribute__ ((noipa)) +f (SIGNEDNESS_1 int res, SIGNEDNESS_3 char *restrict a, + SIGNEDNESS_4 char *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 int mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 char a[N], b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 int) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c new file mode 100644 index 0000000..2b1cc04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 int __attribute__ ((noipa)) +f (SIGNEDNESS_1 int res, SIGNEDNESS_3 char *restrict a, + SIGNEDNESS_4 char *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 int mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 char a[N], b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 int) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c new file mode 100644 index 0000000..962b24e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long res, SIGNEDNESS_3 char *restrict a, + SIGNEDNESS_4 short *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 long mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 char a[N]; + SIGNEDNESS_4 short b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 int) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c new file mode 100644 index 0000000..d757fb1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long res, SIGNEDNESS_3 short *restrict a, + SIGNEDNESS_4 char *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 long mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 short a[N]; + SIGNEDNESS_4 char b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 int) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c new file mode 100644 index 0000000..b5754bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 signed +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long res, SIGNEDNESS_3 char *restrict a, + SIGNEDNESS_4 short *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 int mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 char a[N]; + SIGNEDNESS_4 short b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 int) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c new file mode 100644 index 0000000..febeb19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 unsigned +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long res, SIGNEDNESS_3 char *restrict a, + SIGNEDNESS_4 short *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 int mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 char a[N]; + SIGNEDNESS_4 short b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 int) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c new file mode 100644 index 0000000..cbbeede --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_i8mm } */ + +#include "tree-vect.h" + +#define N 50 + +#ifndef SIGNEDNESS_1 +#define SIGNEDNESS_1 unsigned +#define SIGNEDNESS_2 unsigned +#define SIGNEDNESS_3 signed +#define SIGNEDNESS_4 unsigned +#endif + +SIGNEDNESS_1 int __attribute__ ((noipa)) +f (SIGNEDNESS_1 int res, SIGNEDNESS_3 char *restrict a, + SIGNEDNESS_4 char *restrict b) +{ + for (__INTPTR_TYPE__ i = 0; i < N; ++i) + { + int av = a[i]; + int bv = b[i]; + SIGNEDNESS_2 short mult = av * bv; + res += mult; + } + return res; +} + +#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4) +#define OFFSET 20 + +int +main (void) +{ + check_vect (); + + SIGNEDNESS_3 char a[N], b[N]; + int expected = 0x12345; + for (int i = 0; i < N; ++i) + { + a[i] = BASE + i * 5; + b[i] = BASE + OFFSET + i * 4; + asm volatile ("" ::: "memory"); + expected += (SIGNEDNESS_2 short) (a[i] * b[i]); + } + if (f (0x12345, a, b) != expected) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ -- cgit v1.1 From 398572c1544d8b7541862401b985ae7e855cb8fb Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 14 Jul 2021 12:47:10 -0400 Subject: Turn hybrid mode off, default to ranger-only mode for EVRP. Change the default EVRP mode to ranger-only. gcc/ * params.opt (param_evrp_mode): Change default. gcc/testsuite/ * gcc.dg/pr80776-1.c: Remove xfail. --- gcc/testsuite/gcc.dg/pr80776-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index eca5e80..b9bce62 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -27,5 +27,5 @@ Foo (void) Setting these ranges at the definition site, causes VRP to remove the unreachable code altogether, leaving the following sprintf unguarded. This causes the bogus warning below. */ - sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ } -- cgit v1.1 From 4940166a15193d6583b320f2957af8720745b76c Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Wed, 14 Jul 2021 19:00:59 +0100 Subject: Vect: correct rebase issue The lines being removed have been updated and merged into a new condition. But when resolving some conflicts I accidentally reintroduced them causing some test failes. This removes them. Committed as the changes were previously approved in https://gcc.gnu.org/pipermail/gcc-patches/2021-July/574977.html but the hunk was misapplied during a rebase. gcc/ChangeLog: * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Remove erroneous line. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-reduc-dot-11.c: Expect pass. * gcc.dg/vect/vect-reduc-dot-15.c: Likewise. * gcc.dg/vect/vect-reduc-dot-19.c: Likewise. * gcc.dg/vect/vect-reduc-dot-21.c: Likewise. --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c | 2 +- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c | 2 +- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c | 2 +- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c index 5e3cfc9..0f7cbbb 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c @@ -9,5 +9,5 @@ #include "vect-reduc-dot-9.c" -/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c index 5a6fd19..dc48f95 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c @@ -9,5 +9,5 @@ #include "vect-reduc-dot-9.c" -/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c index 962b24e..dbeaaec 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c @@ -49,4 +49,4 @@ main (void) __builtin_abort (); } -/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c index b5754bf..6d08bf4 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c @@ -49,4 +49,4 @@ main (void) __builtin_abort (); } -/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -- cgit v1.1 From 98f1f9f38c45218c06200feb1939c9433a2ab6ca Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 15 Jul 2021 10:11:23 -0600 Subject: Avoid -Wvla-parameter for nontrivial bounds [PR97548]. Resolves: PR c/101289 - bogus -Wvla-paramater warning when using const for vla param PR c/97548 - bogus -Wvla-parameter on a bound expression involving a parameter gcc/c-family/ChangeLog: PR c/101289 PR c/97548 * c-warn.c (warn_parm_array_mismatch): Use OEP_DECL_NAME. gcc/c/ChangeLog: PR c/101289 PR c/97548 * c-decl.c (get_parm_array_spec): Strip nops. gcc/ChangeLog: PR c/101289 PR c/97548 * fold-const.c (operand_compare::operand_equal_p): Handle OEP_DECL_NAME. (operand_compare::verify_hash_value): Same. * tree-core.h (OEP_DECL_NAME): New. gcc/testsuite/ChangeLog: * gcc.dg/Wvla-parameter-12.c: New test. --- gcc/testsuite/gcc.dg/Wvla-parameter-12.c | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wvla-parameter-12.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-12.c b/gcc/testsuite/gcc.dg/Wvla-parameter-12.c new file mode 100644 index 0000000..1be5e48 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-12.c @@ -0,0 +1,36 @@ +/* PR c/101289 - bogus -Wvla-parameter warning when using const bound + { dg-do compile } + { dg-options "-Wall" } */ + +void f1ci_can (const int n, char a[n]); +void f1ci_can (const int n, char a[n]); // { dg-bogus "-Wvla-parameter" } + +void f2ci_can (const int m, char a[m]); +void f2ci_can (int n, char a[n]); // { dg-bogus "-Wvla-parameter" } + +void f3i_can (int n, char a[n]); +void f3i_can (const int n, char a[n]); // { dg-bogus "-Wvla-parameter" } + +void f4i_can (int n, char a[n]); +void f4i_can (const int n, char a[(int)n]); // { dg-bogus "-Wvla-parameter" } + +void f5i_can (int n, char a[(char)n]); +void f5i_can (const int n, char a[(char)n]); // { dg-bogus "-Wvla-parameter" } + +void f6i_can (int m, char a[(char)m]); +void f6i_can (const int n, char a[(char)n]); // { dg-bogus "-Wvla-parameter" "" { xfail *-*-* } } + + +/* PR c/97548 - bogus -Wvla-parameter on a bound expression involving + a parameter */ + +int n; + +void f7ianp1 (int, int[n + 1]); +void f7ianp1 (int, int[n + 1]); +void f7ianp1 (int, int[n + 2]); // { dg-warning "-Wvla-parameter" } + +void f8iakp1 (int k, int [k + 1]); +void f8iakp1 (int k, int [k + 1]); // { dg-bogus "-Wvla-parameter" } +void f8iakp1 (int k, int [1 + k]); // { dg-bogus "-Wvla-parameter" } +void f8iakp1 (int k, int [k + 2]); // { dg-warning "-Wvla-parameter" } -- cgit v1.1 From b25edf6e6feeadc6a5aa337b8c725786227162dd Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Thu, 15 Jul 2021 17:42:10 +0100 Subject: testsuite: Fix testisms in scalar tests PR101457 These testcases accidentally contain the wrong signs for the expected values for the scalar code. The vector code however is correct. Committed as a trivial fix. gcc/testsuite/ChangeLog: PR middle-end/101457 * gcc.dg/vect/vect-reduc-dot-17.c: Fix signs of scalar code. * gcc.dg/vect/vect-reduc-dot-18.c: Likewise. * gcc.dg/vect/vect-reduc-dot-22.c: Likewise. * gcc.dg/vect/vect-reduc-dot-9.c: Likewise. --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c | 5 +++-- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c | 5 +++-- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c | 2 +- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c | 5 +++-- 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c index aa269c4..38f86fe 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c @@ -35,8 +35,9 @@ main (void) { check_vect (); - SIGNEDNESS_3 char a[N], b[N]; - int expected = 0x12345; + SIGNEDNESS_3 char a[N]; + SIGNEDNESS_4 char b[N]; + SIGNEDNESS_1 int expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c index 2b1cc04..2e86ebe 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c @@ -35,8 +35,9 @@ main (void) { check_vect (); - SIGNEDNESS_3 char a[N], b[N]; - int expected = 0x12345; + SIGNEDNESS_3 char a[N]; + SIGNEDNESS_4 char b[N]; + SIGNEDNESS_1 int expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c index febeb19..0bde43a 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c @@ -37,7 +37,7 @@ main (void) SIGNEDNESS_3 char a[N]; SIGNEDNESS_4 short b[N]; - int expected = 0x12345; + SIGNEDNESS_1 long expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c index cbbeede..d1049c9 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c @@ -35,8 +35,9 @@ main (void) { check_vect (); - SIGNEDNESS_3 char a[N], b[N]; - int expected = 0x12345; + SIGNEDNESS_3 char a[N]; + SIGNEDNESS_4 char b[N]; + SIGNEDNESS_1 int expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; -- cgit v1.1 From a9241df96e1950c630550ada9371c0b4a03496cf Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 15 Jul 2021 15:01:57 -0400 Subject: analyzer: handle self-referential phis gcc/analyzer/ChangeLog: * state-purge.cc (self_referential_phi_p): New. (state_purge_per_ssa_name::process_point): Don't purge an SSA name at its def-stmt if the def-stmt is self-referential. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/phi-1.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/phi-1.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/phi-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/phi-1.c b/gcc/testsuite/gcc.dg/analyzer/phi-1.c new file mode 100644 index 0000000..0926003 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/phi-1.c @@ -0,0 +1,24 @@ +/* { dg-do "compile" } */ + +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *) 0) + +extern const char *foo (void); +extern size_t bar (void); + +void +_nl_expand_alias (const char *locale_alias_path) +{ + size_t added; + do + { + added = 0; + while (added == 0 && locale_alias_path[0] != '\0') + { + const char *start = foo (); + if (start < locale_alias_path) + added = bar (); + } + } + while (added != 0); +} -- cgit v1.1 From 33255ad3ac14e3953750fe0f2d82b901c2852ff6 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 15 Jul 2021 15:07:07 -0400 Subject: analyzer: reimplement -Wanalyzer-use-of-uninitialized-value [PR95006 et al] The initial gcc 10 era commit of the analyzer (in 757bf1dff5e8cee34c0a75d06140ca972bfecfa7) had an implementation of -Wanalyzer-use-of-uninitialized-value, but was sufficiently buggy that I removed it in 78b9783774bfd3540f38f5b1e3c7fc9f719653d7 before the release of gcc 10.1 This patch reintroduces the warning, heavily rewritten, with (I hope) a less buggy implementation this time, for GCC 12. gcc/analyzer/ChangeLog: PR analyzer/95006 PR analyzer/94713 PR analyzer/94714 * analyzer.cc (maybe_reconstruct_from_def_stmt): Split out GIMPLE_ASSIGN case into... (get_diagnostic_tree_for_gassign_1): New. (get_diagnostic_tree_for_gassign): New. * analyzer.h (get_diagnostic_tree_for_gassign): New decl. * analyzer.opt (Wanalyzer-write-to-string-literal): New. * constraint-manager.cc (class svalue_purger): New. (constraint_manager::purge_state_involving): New. * constraint-manager.h (constraint_manager::purge_state_involving): New. * diagnostic-manager.cc (saved_diagnostic::supercedes_p): New. (dedupe_winners::handle_interactions): New. (diagnostic_manager::emit_saved_diagnostics): Call it. * diagnostic-manager.h (saved_diagnostic::supercedes_p): New decl. * engine.cc (impl_region_model_context::warn): Convert return type to bool. Return false if the diagnostic isn't saved. (impl_region_model_context::purge_state_involving): New. (impl_sm_context::get_state): Use NULL ctxt when querying old rvalue. (impl_sm_context::set_next_state): Use new sval when querying old state. (class dump_path_diagnostic): Move to region-model.cc (exploded_node::on_stmt): Move to on_stmt_pre and on_stmt_post. Remove call to purge_state_involving. (exploded_node::on_stmt_pre): New, based on the above. Move most of it to region_model::on_stmt_pre. (exploded_node::on_stmt_post): Likewise, moving to region_model::on_stmt_post. (class stale_jmp_buf): Fix parent class to use curiously recurring template pattern. (feasibility_state::maybe_update_for_edge): Call on_call_pre and on_call_post on gcalls. * exploded-graph.h (impl_region_model_context::warn): Return bool. (impl_region_model_context::purge_state_involving): New decl. (exploded_node::on_stmt_pre): New decl. (exploded_node::on_stmt_post): New decl. * pending-diagnostic.h (pending_diagnostic::use_of_uninit_p): New. (pending_diagnostic::supercedes_p): New. * program-state.cc (sm_state_map::get_state): Inherit state for conjured_svalue as well as initial_svalue. (sm_state_map::purge_state_involving): Also support SK_CONJURED. * region-model-impl-calls.cc (call_details::get_uncertainty): Handle m_ctxt being NULL. (call_details::get_or_create_conjured_svalue): New. (region_model::impl_call_fgets): New. (region_model::impl_call_fread): New. * region-model-manager.cc (region_model_manager::get_or_create_initial_value): Return an uninitialized poisoned value for regions that can't have initial values. * region-model-reachability.cc (reachable_regions::mark_escaped_clusters): Handle ctxt being NULL. * region-model.cc (region_to_value_map::purge_state_involving): New. (poisoned_value_diagnostic::use_of_uninit_p): New. (poisoned_value_diagnostic::emit): Handle POISON_KIND_UNINIT. (poisoned_value_diagnostic::describe_final_event): Likewise. (region_model::check_for_poison): New. (region_model::on_assignment): Call it. (class dump_path_diagnostic): Move here from engine.cc. (region_model::on_stmt_pre): New, based on exploded_node::on_stmt. (region_model::on_call_pre): Move the setting of the LHS to a conjured svalue to before the checks for specific functions. Handle "fgets", "fgets_unlocked", and "fread". (region_model::purge_state_involving): New. (region_model::handle_unrecognized_call): Handle ctxt being NULL. (region_model::get_rvalue): Call check_for_poison. (selftest::test_stack_frames): Use NULL for context when getting uninitialized rvalue. (selftest::test_alloca): Likewise. * region-model.h (region_to_value_map::purge_state_involving): New decl. (call_details::get_or_create_conjured_svalue): New decl. (region_model::on_stmt_pre): New decl. (region_model::purge_state_involving): New decl. (region_model::impl_call_fgets): New decl. (region_model::impl_call_fread): New decl. (region_model::check_for_poison): New decl. (region_model_context::warn): Return bool. (region_model_context::purge_state_involving): New. (noop_region_model_context::warn): Return bool. (noop_region_model_context::purge_state_involving): New. (test_region_model_context:: warn): Return bool. * region.cc (region::get_memory_space): New. (region::can_have_initial_svalue_p): New. (region::involves_p): New. * region.h (enum memory_space): New. (region::get_memory_space): New decl. (region::can_have_initial_svalue_p): New decl. (region::involves_p): New decl. * sm-malloc.cc (use_after_free::supercedes_p): New. * store.cc (binding_cluster::purge_state_involving): New. (store::purge_state_involving): New. * store.h (class symbolic_binding): New forward decl. (binding_key::dyn_cast_symbolic_binding): New. (symbolic_binding::dyn_cast_symbolic_binding): New. (binding_cluster::purge_state_involving): New. (store::purge_state_involving): New. * svalue.cc (svalue::can_merge_p): Reject attempts to merge poisoned svalues with other svalues, so that we identify paths in which a variable is conditionally uninitialized. (involvement_visitor::visit_conjured_svalue): New. (svalue::involves_p): Also handle SK_CONJURED. (poison_kind_to_str): Handle POISON_KIND_UNINIT. (poisoned_svalue::maybe_fold_bits_within): New. * svalue.h (enum poison_kind): Add POISON_KIND_UNINIT. (poisoned_svalue::maybe_fold_bits_within): New decl. gcc/ChangeLog: PR analyzer/95006 PR analyzer/94713 PR analyzer/94714 * doc/invoke.texi: Add -Wanalyzer-use-of-uninitialized-value. gcc/testsuite/ChangeLog: PR analyzer/95006 PR analyzer/94713 PR analyzer/94714 * g++.dg/analyzer/pr93212.C: Update location of warning. * g++.dg/analyzer/pr94011.C: Add -Wno-analyzer-use-of-uninitialized-value. * g++.dg/analyzer/pr94503.C: Likewise. * gcc.dg/analyzer/clobbers-1.c: Convert "f" from a local to a param to avoid uninitialized warning. * gcc.dg/analyzer/data-model-1.c (test_12): Add test for uninitialized value on result of alloca. (test_12a): Add expected warning. (test_12c): Likewise. (test_19): Likewise. (test_29b): Likewise. (test_29c): Likewise. (test_37): Remove xfail. (test_37a): Likewise. * gcc.dg/analyzer/data-model-20.c: Add warning about leak. * gcc.dg/analyzer/explode-2.c: Remove params; add -Wno-analyzer-too-complex, -Wno-analyzer-malloc-leak, and xfails. Initialize the locals. * gcc.dg/analyzer/explode-2a.c: Initialize the locals. Add expected leak. * gcc.dg/analyzer/fgets-1.c: New test. * gcc.dg/analyzer/fread-1.c: New test. * gcc.dg/analyzer/malloc-1.c (test_16): Add expected warning. (test_40): Likewise. * gcc.dg/analyzer/memset-CVE-2017-18549-1.c: Check for uninitialized padding. * gcc.dg/analyzer/pr93355-localealias-feasibility.c (fread): New decl. (read_alias_file): Call it. * gcc.dg/analyzer/pr94047.c: Add expected warnings. * gcc.dg/analyzer/pr94851-2.c: Likewise. * gcc.dg/analyzer/pr96841.c: Convert local to a param. * gcc.dg/analyzer/pr98628.c: Likewise. * gcc.dg/analyzer/pr99042.c: Updated expected location of leak diagnostics. * gcc.dg/analyzer/symbolic-1.c: Add expected warnings. * gcc.dg/analyzer/symbolic-7.c: Likewise. * gcc.dg/analyzer/torture/pr93649.c: Add expected warning. Skip with -fno-fat-lto-objects. * gcc.dg/analyzer/uninit-1.c: New test. * gcc.dg/analyzer/uninit-2.c: New test. * gcc.dg/analyzer/uninit-3.c: New test. * gcc.dg/analyzer/uninit-4.c: New test. * gcc.dg/analyzer/uninit-pr94713.c: New test. * gcc.dg/analyzer/uninit-pr94714.c: New test. * gcc.dg/analyzer/use-after-free-2.c: New test. * gcc.dg/analyzer/use-after-free-3.c: New test. * gcc.dg/analyzer/zlib-3.c: Add expected warning. * gcc.dg/analyzer/zlib-6.c: Convert locals to params to avoid uninitialized warnings. Remove xfail. * gcc.dg/analyzer/zlib-6a.c: New test, based on the old version of the above. * gfortran.dg/analyzer/pr97668.f: Add -Wno-analyzer-use-of-uninitialized-value and -Wno-analyzer-too-complex. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/clobbers-1.c | 3 +- gcc/testsuite/gcc.dg/analyzer/data-model-1.c | 32 +++++++++------ gcc/testsuite/gcc.dg/analyzer/data-model-20.c | 2 +- gcc/testsuite/gcc.dg/analyzer/explode-2.c | 16 ++++---- gcc/testsuite/gcc.dg/analyzer/explode-2a.c | 4 +- gcc/testsuite/gcc.dg/analyzer/fgets-1.c | 31 ++++++++++++++ gcc/testsuite/gcc.dg/analyzer/fread-1.c | 13 ++++++ gcc/testsuite/gcc.dg/analyzer/malloc-1.c | 7 ++-- .../gcc.dg/analyzer/memset-CVE-2017-18549-1.c | 8 ++-- .../analyzer/pr93355-localealias-feasibility.c | 7 ++++ gcc/testsuite/gcc.dg/analyzer/pr94047.c | 2 +- gcc/testsuite/gcc.dg/analyzer/pr94851-2.c | 2 +- gcc/testsuite/gcc.dg/analyzer/pr96841.c | 4 +- gcc/testsuite/gcc.dg/analyzer/pr98628.c | 3 +- gcc/testsuite/gcc.dg/analyzer/pr99042.c | 8 ++-- gcc/testsuite/gcc.dg/analyzer/symbolic-1.c | 6 ++- gcc/testsuite/gcc.dg/analyzer/symbolic-7.c | 6 ++- gcc/testsuite/gcc.dg/analyzer/torture/pr93649.c | 3 +- gcc/testsuite/gcc.dg/analyzer/uninit-1.c | 44 ++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/uninit-2.c | 14 +++++++ gcc/testsuite/gcc.dg/analyzer/uninit-3.c | 36 +++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/uninit-4.c | 39 ++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c | 11 +++++ gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c | 12 ++++++ gcc/testsuite/gcc.dg/analyzer/use-after-free-2.c | 8 ++++ gcc/testsuite/gcc.dg/analyzer/use-after-free-3.c | 12 ++++++ gcc/testsuite/gcc.dg/analyzer/zlib-3.c | 2 +- gcc/testsuite/gcc.dg/analyzer/zlib-6.c | 13 ++---- gcc/testsuite/gcc.dg/analyzer/zlib-6a.c | 47 ++++++++++++++++++++++ 29 files changed, 336 insertions(+), 59 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/fgets-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/fread-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/use-after-free-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/use-after-free-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/zlib-6a.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c b/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c index 824dbd4..6400f84 100644 --- a/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/clobbers-1.c @@ -25,9 +25,8 @@ void test_1 (void) __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ } -void test_2 (void) +void test_2 (struct foo f) { - struct foo f; f.i = 42; if (f.j) __analyzer_eval (f.j); /* { dg-warning "TRUE" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index 34932da..908d999 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -137,7 +137,7 @@ void test_11 (void) /* alloca. */ -void test_12 (void) +int test_12 (void) { void *p = __builtin_alloca (256); void *q = __builtin_alloca (256); @@ -145,14 +145,14 @@ void test_12 (void) /* alloca results should be unique. */ __analyzer_eval (p == q); /* { dg-warning "FALSE" } */ - // FIXME: complain about uses of poisoned values + return *(int *)p; /* { dg-warning "use of uninitialized value '\\*\\(int \\*\\)p" } */ } /* Use of uninit value. */ int test_12a (void) { int i; - return i; // FIXME: do we see the return stmt? + return i; /* { dg-warning "use of uninitialized value 'i'" } */ } void test_12b (void *p, void *q) @@ -165,9 +165,11 @@ int test_12c (void) int i; int j; - j = i; // FIXME: should complain about this + j = i; /* { dg-warning "use of uninitialized value 'i'" } */ - return j; + /* We should not emit followup warnings after the first warning about + an uninitialized value. */ + return j; /* { dg-bogus "use of uninitialized value" } */ } struct coord @@ -348,7 +350,9 @@ void test_19 (void) { int i, j; /* Compare two uninitialized locals. */ - __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" "unknown " } */ + /* { dg-warning "use of uninitialized value 'i'" "uninit i" { target *-*-* } .-1 } */ + /* { dg-warning "use of uninitialized value 'j'" "uninit j" { target *-*-* } .-2 } */ } void test_20 (int i, int j) @@ -649,8 +653,10 @@ void test_29b (void) __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value 'p\\\[10\\\].x'" "uninit" { target *-*-* } .-1 } */ + __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value 'p\\\[10\\\].y'" "uninit" { target *-*-* } .-1 } */ q = &p[7]; @@ -698,8 +704,10 @@ void test_29c (int len) __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value '\\*p\\\[10\\\].x'" "uninit" { target *-*-* } .-1 } */ + __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value '\\*p\\\[10\\\].y'" "uninit" { target *-*-* } .-1 } */ q = &p[7]; @@ -811,7 +819,7 @@ void test_36 (int i) int test_37 (void) { int *ptr; - return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" "uninit-warning-removed" { xfail *-*-* } } */ + return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */ } /* Write through uninitialized pointer. */ @@ -819,7 +827,7 @@ int test_37 (void) void test_37a (int i) { int *ptr; - *ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" "uninit-warning-removed" { xfail *-*-* } } */ + *ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" } */ } // TODO: the various other ptr deref poisonings diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-20.c b/gcc/testsuite/gcc.dg/analyzer/data-model-20.c index 8fdbb6b..ff65883 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-20.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-20.c @@ -17,7 +17,7 @@ test (int n) { for (; i >= 0; i++) { free(arr[i]); /* { dg-bogus "double-'free'" } */ } - free(arr); + free(arr); /* { dg-warning "leak" } */ return NULL; } } diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2.c b/gcc/testsuite/gcc.dg/analyzer/explode-2.c index 70d8fec..3b987e1 100644 --- a/gcc/testsuite/gcc.dg/analyzer/explode-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/explode-2.c @@ -2,9 +2,11 @@ independently, so the total combined number of states at any program point within the loop is NUM_VARS * NUM_STATES. - Set the limits high enough that we can fully explore this. */ + However, due to the way the analyzer represents heap-allocated regions + this never terminates, eventually hitting the complexity limit + (PR analyzer/93695). */ -/* { dg-additional-options "--param analyzer-max-enodes-per-program-point=200 --param analyzer-bb-explosion-factor=50" } */ +/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-malloc-leak" } */ #include @@ -12,35 +14,35 @@ extern int get (void); void test (void) { - void *p0, *p1, *p2, *p3; + void *p0 = NULL, *p1 = NULL, *p2 = NULL, *p3 = NULL; while (get ()) { switch (get ()) { default: case 0: - p0 = malloc (16); /* { dg-warning "leak" } */ + p0 = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */ break; case 1: free (p0); /* { dg-warning "double-'free' of 'p0'" "" { xfail *-*-* } } */ break; case 2: - p1 = malloc (16); /* { dg-warning "leak" } */ + p1 = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */ break; case 3: free (p1); /* { dg-warning "double-'free' of 'p1'" "" { xfail *-*-* } } */ break; case 4: - p2 = malloc (16); /* { dg-warning "leak" } */ + p2 = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */ break; case 5: free (p2); /* { dg-warning "double-'free' of 'p2'" "" { xfail *-*-* } } */ break; case 6: - p3 = malloc (16); /* { dg-warning "leak" } */ + p3 = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */ break; case 7: free (p3); /* { dg-warning "double-'free' of 'p3'" "" { xfail *-*-* } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2a.c b/gcc/testsuite/gcc.dg/analyzer/explode-2a.c index 126407f..f60354c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/explode-2a.c +++ b/gcc/testsuite/gcc.dg/analyzer/explode-2a.c @@ -8,13 +8,13 @@ extern int get (void); void test (void) { - void *p0, *p1, *p2, *p3; + void *p0 = NULL, *p1 = NULL, *p2 = NULL, *p3 = NULL; /* Due to not purging constraints on SSA names within loops (PR analyzer/101068), the analyzer effectively treats the original explode-2.c as this code. */ int a = get (); int b = get (); - while (a) + while (a) /* { dg-warning "leak" } */ { switch (b) { diff --git a/gcc/testsuite/gcc.dg/analyzer/fgets-1.c b/gcc/testsuite/gcc.dg/analyzer/fgets-1.c new file mode 100644 index 0000000..e93d24c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fgets-1.c @@ -0,0 +1,31 @@ +/* { dg-do "compile" } */ + +#define NULL ((void *) 0) +typedef struct _IO_FILE FILE; + +extern char *fgets(char *__restrict __s, int __n, + FILE *__restrict __stream); +extern char *fgets_unlocked(char *__restrict __s, int __n, + FILE *__restrict __stream); + +char +test_1 (FILE *fp) +{ + char buf[400]; + + if (fgets (buf, sizeof buf, fp) == NULL) + return 0; + + return buf[0]; +} + +char +test_2 (FILE *fp) +{ + char buf[400]; + + if (fgets_unlocked (buf, sizeof buf, fp) == NULL) + return 0; + + return buf[0]; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/fread-1.c b/gcc/testsuite/gcc.dg/analyzer/fread-1.c new file mode 100644 index 0000000..593cb7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fread-1.c @@ -0,0 +1,13 @@ +/* { dg-additional-options "-fanalyzer-checker=taint" } */ + +typedef __SIZE_TYPE__ size_t; + +extern size_t fread (void *, size_t, size_t, void *); + +int +test_1 (void *fp) +{ + int i; + fread (&i, sizeof (i), 1, fp); + return i; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c index 448b8558..df2fc9c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c @@ -204,8 +204,7 @@ void test_16 (void) bar (); fail: - free (q); /* { dg-warning "free of uninitialized 'q'" "" { xfail *-*-* } } */ - /* TODO(xfail): implement uninitialized detection. */ + free (q); /* { dg-warning "use of uninitialized value 'q'" } */ free (p); } @@ -459,8 +458,8 @@ int * test_40 (int i) { int *p = (int*)malloc(sizeof(int*)); - i = *p; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */ - /* TODO: (it's also uninitialized) */ + i = *p; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" "possibly-null" } */ + /* { dg-warning "use of uninitialized value '\\*p'" "uninit" { target *-*-*} .-1 } */ return p; } diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c index 9dd1139..de9b5e3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c @@ -37,6 +37,8 @@ struct aac_srb_reply #define ST_OK 0 #define SRB_STATUS_SUCCESS 0x01 +extern void check_uninit (u8 v); + /* Adapted from drivers/scsi/aacraid/commctrl.c */ static int aac_send_raw_srb(/* [...snip...] */) @@ -66,10 +68,8 @@ static int aac_send_raw_srb(/* [...snip...] */) __analyzer_eval (reply.sense_data_size == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data[0] == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (reply.sense_data[AAC_SENSE_BUFFERSIZE - 1] == 0); /* { dg-warning "TRUE" } */ - /* TODO: the following should be detected as uninitialized, when - that diagnostic is reimplemented. */ - __analyzer_eval (reply.padding[0] == 0); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (reply.padding[1] == 0); /* { dg-warning "UNKNOWN" } */ + check_uninit (reply.padding[0]); /* { dg-warning "uninitialized value" } */ + check_uninit (reply.padding[1]); /* { dg-warning "uninitialized value" } */ } static int aac_send_raw_srb_fixed(/* [...snip...] */) diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c index 1a34d05..c7b49d2 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c @@ -30,6 +30,7 @@ typedef __SIZE_TYPE__ size_t; typedef struct _IO_FILE FILE; extern FILE *fopen (const char *__restrict __filename, const char *__restrict __modes); +extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); extern int fclose (FILE *__stream); extern int isspace (int) __attribute__((__nothrow__, __leaf__)); @@ -50,6 +51,12 @@ read_alias_file (const char *fname, int fname_len) if (fp == NULL) return 0; + if (fread (buf, sizeof buf, 1, fp) != 1) + { + fclose (fp); + return 0; + } + cp = buf; /* Ignore leading white space. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94047.c b/gcc/testsuite/gcc.dg/analyzer/pr94047.c index 5107ec0..d13da3e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr94047.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr94047.c @@ -13,7 +13,7 @@ void foo (void) { struct list l; - tlist t = l; + tlist t = l; /* { dg-warning "use of uninitialized value 'l'" } */ for (;;) bar (&t); } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c b/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c index 6094721..b837451 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c @@ -45,7 +45,7 @@ int pamark(void) { if (curbp->b_amark == (AMARK *)NULL) curbp->b_amark = p; else - last->m_next = p; + last->m_next = p; /* { dg-warning "dereference of NULL 'last'" } */ } p->m_name = (char)c; /* { dg-bogus "leak of 'p'" "bogus leak" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96841.c b/gcc/testsuite/gcc.dg/analyzer/pr96841.c index 8546661..c766582 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr96841.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr96841.c @@ -10,10 +10,8 @@ void th (int *); void -bv (__SIZE_TYPE__ ny) +bv (__SIZE_TYPE__ ny, int ***mf) { - int ***mf; - while (l8 ()) { *mf = 0; diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98628.c b/gcc/testsuite/gcc.dg/analyzer/pr98628.c index e2fa778..fa0ca96 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr98628.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr98628.c @@ -7,8 +7,7 @@ struct chanset_t { struct chanset_t *next; char dname[]; }; -void help_subst() { - char *writeidx; +void help_subst(char *writeidx) { for (;; help_subst_chan = *help_subst_chan_0_0) { foo(help_subst_chan.next->dname); if (help_subst_chan_0_0) { diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99042.c b/gcc/testsuite/gcc.dg/analyzer/pr99042.c index c3d124f..f28a9de 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr99042.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr99042.c @@ -29,8 +29,8 @@ int test_3 (void) if ((p->file = fopen("test.txt", "w")) == NULL) return 1; unknown_fn (); - return 0; /* { dg-warning "leak" } */ -} + return 0; +} /* { dg-warning "leak" } */ int test_4 (void) { @@ -38,8 +38,8 @@ int test_4 (void) struct foo *p = &f; if ((p->file = fopen("test.txt", "w")) == NULL) return 1; - return 0; /* { dg-warning "leak" } */ -} + return 0; +} /* { dg-warning "leak" } */ int test_5 (void) { diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c index feab9ce..0eba646 100644 --- a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c @@ -11,14 +11,16 @@ void test_1 (char a, char b, char c, char d, char e, char f, __analyzer_eval (arr[2] == a); /* { dg-warning "TRUE" } */ __analyzer_eval (arr[3] == b); /* { dg-warning "TRUE" } */ - __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ // TODO: report uninit + __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value 'arr\\\[4\\\]'" "uninit" { target *-*-* } .-1 } */ /* Replace one concrete binding's value with a different value. */ arr[3] = c; /* (3) */ __analyzer_eval (arr[2] == a); /* { dg-warning "TRUE" } */ __analyzer_eval (arr[3] == c); /* { dg-warning "TRUE" } */ __analyzer_eval (arr[3] == b); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ // TODO: report uninit + __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value 'arr\\\[4\\\]'" "uninit" { target *-*-* } .-1 } */ /* Symbolic binding. */ arr[i] = d; /* (4) */ diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c index 4f01367..665e0b6 100644 --- a/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-7.c @@ -37,8 +37,10 @@ void test_3 (int i) int arr[2]; /* Concrete reads. */ - __analyzer_eval (arr[0] == 42); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (arr[0] == 42); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value 'arr\\\[0\\\]'" "uninit" { target *-*-* } .-1 } */ /* Symbolic read. */ - __analyzer_eval (arr[i] == 42); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (arr[i] == 42); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value 'arr\\\[i\\\]'" "uninit" { target *-*-* } .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr93649.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr93649.c index 9d92939..314c8f3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/torture/pr93649.c +++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr93649.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ /* { dg-additional-options "-Wno-incompatible-pointer-types -Wno-analyzer-too-complex" } */ /* TODO: ideally we shouldn't have -Wno-analyzer-too-complex above; it appears to be needed due to the recursion. */ @@ -57,7 +58,7 @@ ts (struct dz *cx) { struct dz nt; - if (nt.r5) + if (nt.r5) /* { dg-warning "use of uninitialized value 'nt.r5'" } */ { m6 (cx); h5 (cx); diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c new file mode 100644 index 0000000..8fcdcd6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c @@ -0,0 +1,44 @@ +#include "analyzer-decls.h" + +int test_1 (void) +{ + int i; + return i; /* { dg-warning "use of uninitialized value 'i'" } */ +} + +int test_2 (void) +{ + int i; + return i * 2; /* { dg-warning "use of uninitialized value 'i'" } */ +} + +int test_3 (void) +{ + static int i; + return i; +} + +int test_4 (void) +{ + int *p; + return *p; /* { dg-warning "use of uninitialized value 'p'" } */ +} + +int test_5 (int flag, int *q) +{ + int *p; + if (flag) /* { dg-message "following 'false' branch" } */ + p = q; + + /* There should be two enodes here, + i.e. not merging the init vs non-init states. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ + + return *p; /* { dg-warning "use of uninitialized value 'p'" } */ +} + +int test_6 (int i) +{ + int arr[10]; + return arr[i]; /* { dg-warning "use of uninitialized value 'arr\\\[i\\\]'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-2.c b/gcc/testsuite/gcc.dg/analyzer/uninit-2.c new file mode 100644 index 0000000..0b0b8b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-2.c @@ -0,0 +1,14 @@ +typedef __SIZE_TYPE__ size_t; + +extern size_t strlen (const char *__s) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__pure__)) + __attribute__ ((__nonnull__ (1))); + +extern char *read_file (const char *file); + +size_t test_1 (const char *file) +{ + char *str = read_file (file); + return strlen (str); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-3.c b/gcc/testsuite/gcc.dg/analyzer/uninit-3.c new file mode 100644 index 0000000..fa33e0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-3.c @@ -0,0 +1,36 @@ +/* Reduced from linux 5.3.11: drivers/net/wireless/ath/ath10k/usb.c */ + +/* The original file has this licence header. */ + +// SPDX-License-Identifier: ISC +/* + * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl + */ + +/* Adapted from include/linux/compiler_attributes.h. */ +#define __printf(a, b) __attribute__((__format__(printf, a, b))) + +/* From drivers/net/wireless/ath/ath10k/core.h. */ + +struct ath10k; + +/* From drivers/net/wireless/ath/ath10k/debug.h. */ + +enum ath10k_debug_mask { + /* [...other values removed...] */ + ATH10K_DBG_USB_BULK = 0x00080000, +}; + +extern unsigned int ath10k_debug_mask; + +__printf(3, 4) void __ath10k_dbg(struct ath10k *ar, + enum ath10k_debug_mask mask, + const char *fmt, ...); + +static void ath10k_usb_hif_tx_sg(struct ath10k *ar) +{ + if (ath10k_debug_mask & ATH10K_DBG_USB_BULK) + __ath10k_dbg(ar, ATH10K_DBG_USB_BULK, "usb bulk transmit failed: %d\n", 42); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-4.c b/gcc/testsuite/gcc.dg/analyzer/uninit-4.c new file mode 100644 index 0000000..791b111 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-4.c @@ -0,0 +1,39 @@ +/* Example of interprocedural detection of an uninitialized field + in a heap-allocated struct. */ + +#include +#include "analyzer-decls.h" + +struct foo +{ + int i; + int j; + int k; +}; + +struct foo *__attribute__((noinline)) +alloc_foo (int a, int b) +{ + struct foo *p = malloc (sizeof (struct foo)); + if (!p) + return NULL; + p->i = a; + p->k = b; + return p; +} + +void test (int x, int y, int z) +{ + struct foo *p = alloc_foo (x, z); + if (!p) + return; + + __analyzer_eval (p->i == x); /* { dg-warning "TRUE" } */ + + __analyzer_eval (p->j == y); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use of uninitialized value '\\*p\\.j'" "uninit" { target *-*-* } .-1 } */ + + __analyzer_eval (p->k == z); /* { dg-warning "TRUE" } */ + + free (p); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c new file mode 100644 index 0000000..cc337dc --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c @@ -0,0 +1,11 @@ +void f1 (int *); +void f2 (int); + +int foo (void) +{ + int *p; + + f1 (p); /* { dg-warning "use of uninitialized value 'p'" } */ + f2 (p[0]); /* { dg-warning "use of uninitialized value 'p'" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c new file mode 100644 index 0000000..df07f98 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c @@ -0,0 +1,12 @@ +#include + +int main (void) +{ + int *p; + int i; + + p = &i; /* { dg-bogus "uninitialized" } */ + printf ("%d\n", p[0]); /* { dg-warning "use of uninitialized value '\\*p'" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/use-after-free-2.c b/gcc/testsuite/gcc.dg/analyzer/use-after-free-2.c new file mode 100644 index 0000000..fc138ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/use-after-free-2.c @@ -0,0 +1,8 @@ +int test (void) +{ + int *ptr = (int *)__builtin_malloc (sizeof (int)); + *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */ + __builtin_free (ptr); + + return *ptr; /* { dg-warning "use after 'free' of 'ptr'" "use-after-free" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/use-after-free-3.c b/gcc/testsuite/gcc.dg/analyzer/use-after-free-3.c new file mode 100644 index 0000000..b19fd3d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/use-after-free-3.c @@ -0,0 +1,12 @@ +#include + +void test_1 (int x, int y, int *out) +{ + int *ptr = (int *)malloc (sizeof (int)); + if (!ptr) + return; + *ptr = 19; + + free (ptr); + *out = *ptr; /* { dg-warning "use after 'free' of 'ptr'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c index 5faada1..57f5dcd 100644 --- a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c +++ b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c @@ -179,7 +179,7 @@ static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, f = 1 << (k - w); for (j = i >> w; j < z; j += f) - q[j] = r; + q[j] = r; /* { dg-warning "use of uninitialized value 'r.base'" } */ mask = (1 << w) - 1; while ((i & mask) != x[h]) { diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-6.c b/gcc/testsuite/gcc.dg/analyzer/zlib-6.c index 0d814c0..c8e06c6 100644 --- a/gcc/testsuite/gcc.dg/analyzer/zlib-6.c +++ b/gcc/testsuite/gcc.dg/analyzer/zlib-6.c @@ -16,15 +16,8 @@ typedef struct inflate_blocks_state { extern int inflate_flush(inflate_blocks_statef *, z_stream *, int); -int inflate_blocks(inflate_blocks_statef *s, z_stream *z, int r) { - uInt t; - uLong b; - uInt k; - Byte *p; - uInt n; - Byte *q; - uInt m; - +int inflate_blocks(inflate_blocks_statef *s, z_stream *z, int r, + uLong b, uInt k, Byte *p, uInt n, Byte *q, uInt m) { while (k < (3)) { { if (n) @@ -41,7 +34,7 @@ int inflate_blocks(inflate_blocks_statef *s, z_stream *z, int r) { return inflate_flush(s, z, r); } }; - b |= ((uLong)(n--, *p++)) << k; /* { dg-warning "use of uninitialized value" "uninit-warning-removed" { xfail *-*-* } } */ + b |= ((uLong)(n--, *p++)) << k; k += 8; } } diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-6a.c b/gcc/testsuite/gcc.dg/analyzer/zlib-6a.c new file mode 100644 index 0000000..9676e0b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/zlib-6a.c @@ -0,0 +1,47 @@ +typedef unsigned char Byte; +typedef unsigned int uInt; +typedef unsigned long uLong; + +typedef struct z_stream_s { + Byte *next_in; + uInt avail_in; + uLong total_in; +} z_stream; + +typedef struct inflate_blocks_state { + uInt bitk; + uLong bitb; + Byte *write; +} inflate_blocks_statef; + +extern int inflate_flush(inflate_blocks_statef *, z_stream *, int); + +int inflate_blocks(inflate_blocks_statef *s, z_stream *z, int r) { + uInt t; + uLong b; + uInt k; + Byte *p; + uInt n; + Byte *q; + uInt m; + + while (k < (3)) { /* { dg-warning "use of uninitialized value 'k'" } */ + { + if (n) /* { dg-warning "use of uninitialized value 'n'" } */ + r = 0; + else { + { + s->bitb = b; /* { dg-warning "use of uninitialized value 'b'" } */ + s->bitk = k; /* { dg-warning "use of uninitialized value 'k'" } */ + z->avail_in = n; /* { dg-warning "use of uninitialized value 'n'" } */ + z->total_in += p - z->next_in; /* { dg-warning "use of uninitialized value 'p'" } */ + z->next_in = p; /* { dg-warning "use of uninitialized value 'p'" } */ + s->write = q; /* { dg-warning "use of uninitialized value 'q'" } */ + } + return inflate_flush(s, z, r); + } + }; + b |= ((uLong)(n--, *p++)) << k; /* { dg-warning "use of uninitialized value" } */ + k += 8; /* { dg-warning "use of uninitialized value 'k'" } */ + } +} -- cgit v1.1 From f0500db3692276f60e0562c17c87a0cb03e34398 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 15 Jul 2021 13:15:03 -0600 Subject: Detect buffer overflow by aggregate and vector stores [PR97027]. Resolves: PR middle-end/97027 - missing warning on buffer overflow storing a larger scalar into a smaller array gcc/ChangeLog: PR middle-end/97027 * tree-ssa-strlen.c (handle_assign): New function. (maybe_warn_overflow): Add argument. (nonzero_bytes_for_type): New function. (count_nonzero_bytes): Handle more tree types. Call nonzero_bytes_for_tye. (count_nonzero_bytes): Handle types. (handle_store): Handle stores from function calls. (strlen_check_and_optimize_call): Move code to handle_assign. Call it for assignments from function calls. gcc/testsuite/ChangeLog: PR middle-end/97027 * gcc.dg/Wstringop-overflow-15.c: Remove an xfail. * gcc.dg/Wstringop-overflow-47.c: Adjust xfails. * gcc.dg/torture/pr69170.c: Avoid valid warnings. * gcc.dg/torture/pr70025.c: Prune out a false positive. * gcc.dg/vect/pr97769.c: Initialize a loop control variable. * gcc.target/i386/pr92658-avx512bw-trunc.c: Increase buffer size to avoid overflow. * gcc.target/i386/pr92658-avx512f.c: Same. * gcc.dg/Wstringop-overflow-68.c: New test. * gcc.dg/Wstringop-overflow-69.c: New test. * gcc.dg/Wstringop-overflow-70.c: New test. * gcc.dg/Wstringop-overflow-71.c: New test. * gcc.dg/strlenopt-95.c: New test. --- gcc/testsuite/gcc.dg/Wstringop-overflow-15.c | 2 +- gcc/testsuite/gcc.dg/Wstringop-overflow-47.c | 17 +++-- gcc/testsuite/gcc.dg/Wstringop-overflow-68.c | 104 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-69.c | 84 +++++++++++++++++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-70.c | 21 ++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-71.c | 105 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/strlenopt-95.c | 65 +++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr69170.c | 2 +- gcc/testsuite/gcc.dg/torture/pr70025.c | 5 ++ gcc/testsuite/gcc.dg/vect/pr97769.c | 2 +- 10 files changed, 398 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-68.c create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-69.c create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-70.c create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-71.c create mode 100644 gcc/testsuite/gcc.dg/strlenopt-95.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c index 1907bac..87f8462 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c @@ -30,7 +30,7 @@ void vla_bounded (int n) a[0] = 0; a[1] = 1; a[n] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } - a[69] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + a[69] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" } sink (&a); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c index 6412874..968f6ee 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c @@ -31,15 +31,15 @@ void nowarn_c32 (char c) void warn_c32 (char c) { - extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" } + extern char warn_a32[32]; // { dg-message "at offset (32|1) into destination object 'warn_a32' of size 32" "pr97027" } void *p = warn_a32 + 1; - *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" } + *(C32*)p = (C32){ c }; // { dg-warning "writing (1 byte|32 bytes) into a region of size (0|31)" "pr97027" } /* Verify a local variable too. */ char a32[32]; p = a32 + 1; - *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" } + *(C32*)p = (C32){ c }; // { dg-warning "writing (1 byte|32 bytes) into a region of size (0|31)" "pr97027" } sink (p); } @@ -60,15 +60,20 @@ void nowarn_i16_64 (int16_t i) void warn_i16_64 (int16_t i) { - extern char warn_a64[64]; // { dg-message "at offset 128 to object 'warn_a64' with size 64" "pr97027" { xfail *-*-* } } +/* The IL below that's visible to the warning changes from one target to + another. On some like aarch64 it's a single vector store, on others + like x86_64 it's a series of BIT_FIELD_REFs. The overflow by + the former is detected but the latter is not yet. */ + + extern char warn_a64[64]; // { dg-message "at offset (1|128) into destination object 'warn_a64' of size (63|64)" "pr97027 note" { xfail { ! aarch64-*-* } } } void *p = warn_a64 + 1; I16_64 *q = (I16_64*)p; - *q = (I16_64){ i }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } } + *q = (I16_64){ i }; // { dg-warning "writing (1 byte|64 bytes) into a region of size (0|63)" "pr97027" { xfail { ! aarch64-*-* } } } char a64[64]; p = a64 + 1; q = (I16_64*)p; - *q = (I16_64){ i }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } } + *q = (I16_64){ i }; // { dg-warning "writing (1 byte|64 bytes) into a region of size (0|63)" "pr97027" { xfail { ! aarch64-*-* } } } sink (p); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c new file mode 100644 index 0000000..d2d3ae5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c @@ -0,0 +1,104 @@ +/* PR tree-optimization/97027 - missing warning on buffer overflow storing + a larger scalar into a smaller array + Verify overflow by aggregate stores. + { dg-do compile } + { dg-options "-O2" } */ + +#define A(N) (A ## N) +#define Ac1 (AC1){ 0 } +#define Ac2 (AC2){ 0, 1 } +#define Ac4 (AC4){ 0, 1, 2, 3 } +#define Ac8 (AC8){ 0, 1, 2, 3, 4, 5, 6, 7 } +#define Ac16 (AC16){ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } + +typedef struct AC1 { char a[1]; } AC1; +typedef struct AC2 { char a[2]; } AC2; +typedef struct AC3 { char a[3]; } AC3; +typedef struct AC4 { char a[4]; } AC4; +typedef struct AC5 { char a[5]; } AC5; +typedef struct AC8 { char a[8]; } AC8; +typedef struct AC16 { char a[16]; } AC16; + +extern char a1[1], a2[2], a3[3], a4[4], a5[5], a6[6], a7[7], a8[8], a15[15]; + +extern AC1 ac1; +extern AC2 ac2; +extern AC4 ac4; +extern AC8 ac8; +extern AC16 ac16; + +extern AC1 fac1 (void); +extern AC2 fac2 (void); +extern AC4 fac4 (void); +extern AC8 fac8 (void); +extern AC16 fac16 (void); + +void nowarn (void) +{ + *(AC1*)a1 = Ac1; + *(AC2*)a2 = Ac2; + *(AC4*)a4 = Ac4; + *(AC4*)a5 = Ac4; + *(AC4*)a6 = Ac4; + *(AC4*)a7 = Ac4; + *(AC8*)a8 = Ac8; + *(AC8*)a15 = Ac8; +} + +void warn_comp_lit_zero (void) +{ + *(AC2*)a1 = (AC2){ }; // { dg-warning "writing 2 bytes into a region of size 1" } + *(AC4*)a2 = (AC4){ }; // { dg-warning "writing 4 bytes into a region of size 2" } + *(AC4*)a3 = (AC4){ }; // { dg-warning "writing 4 bytes into a region of size 3" } + *(AC8*)a4 = (AC8){ }; // { dg-warning "writing 8 bytes into a region of size 4" } + *(AC8*)a7 = (AC8){ }; // { dg-warning "writing 8 bytes into a region of size 7" } + *(AC16*)a15 = (AC16){ };// { dg-warning "writing 16 bytes into a region of size 15" } +} + +void warn_comp_lit (void) +{ + *(AC2*)a1 = Ac2; // { dg-warning "writing 2 bytes into a region of size 1" "pr??????" { xfail *-*-* } } + *(AC4*)a2 = Ac4; // { dg-warning "writing 4 bytes into a region of size 2" "pr??????" { xfail *-*-* } } + *(AC4*)a3 = Ac4; // { dg-warning "writing 4 bytes into a region of size 3" "pr??????" { xfail *-*-* } } + *(AC8*)a4 = Ac8; // { dg-warning "writing 8 bytes into a region of size 4" "pr??????" { xfail *-*-* } } + *(AC8*)a7 = Ac8; // { dg-warning "writing 8 bytes into a region of size 7" "pr??????" { xfail *-*-* } } + *(AC16*)a15 = Ac16; // { dg-warning "writing 16 bytes into a region of size 15" "pr??????" { xfail *-*-* } } +} + +void warn_aggr_decl (void) +{ + *(AC2*)a1 = ac2; // { dg-warning "writing 2 bytes into a region of size 1" } + *(AC4*)a2 = ac4; // { dg-warning "writing 4 bytes into a region of size 2" } + *(AC4*)a3 = ac4; // { dg-warning "writing 4 bytes into a region of size 3" } + *(AC8*)a4 = ac8; // { dg-warning "writing 8 bytes into a region of size 4" } + *(AC8*)a7 = ac8; // { dg-warning "writing 8 bytes into a region of size 7" } + *(AC16*)a15 = ac16; // { dg-warning "writing 16 bytes into a region of size 15" } +} + +void warn_aggr_parm (AC2 pc2, AC4 pc4, AC8 pc8, AC16 pc16) +{ + *(AC2*)a1 = pc2; // { dg-warning "writing 2 bytes into a region of size 1" } + *(AC4*)a2 = pc4; // { dg-warning "writing 4 bytes into a region of size 2" } + *(AC4*)a3 = pc4; // { dg-warning "writing 4 bytes into a region of size 3" } + *(AC8*)a4 = pc8; // { dg-warning "writing 8 bytes into a region of size 4" } + *(AC8*)a7 = pc8; // { dg-warning "writing 8 bytes into a region of size 7" } + *(AC16*)a15 = pc16; // { dg-warning "writing 16 bytes into a region of size 15" } +} + +void warn_aggr_func (void) +{ + *(AC2*)a1 = fac2 (); // { dg-warning "writing 2 bytes into a region of size 1" } + *(AC4*)a2 = fac4 (); // { dg-warning "writing 4 bytes into a region of size 2" } + *(AC4*)a3 = fac4 (); // { dg-warning "writing 4 bytes into a region of size 3" } + *(AC8*)a4 = fac8 (); // { dg-warning "writing 8 bytes into a region of size 4" } + *(AC8*)a7 = fac8 (); // { dg-warning "writing 8 bytes into a region of size 7" } + *(AC16*)a15 = fac16 ();// { dg-warning "writing 16 bytes into a region of size 15" } + + extern AC2 fac2_x (); + + *(AC2*)a1 = fac2_x (); // { dg-warning "writing 2 bytes into a region of size 1" } + + extern AC2 fac2_p (char*); + + *(AC2*)a1 = fac2_p (0); // { dg-warning "writing 2 bytes into a region of size 1" } +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c new file mode 100644 index 0000000..754b481 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c @@ -0,0 +1,84 @@ +/* PR tree-optimization/97027 - missing warning on buffer overflow storing + a larger scalar into a smaller array + Verify overflow by vector stores. + { dg-do compile } + { dg-options "-O2" } */ + +#define V(N) __attribute__ ((vector_size (N))) +#define C1 (VC1){ 0 } +#define C2 (VC2){ 0, 1 } +#define C4 (VC4){ 0, 1, 2, 3 } +#define C8 (VC8){ 0, 1, 2, 3, 4, 5, 6, 7 } +#define C16 (VC16){ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } + +typedef V (1) char VC1; +typedef V (2) char VC2; +typedef V (4) char VC4; +typedef V (8) char VC8; +typedef V (16) char VC16; + +extern char a1[1], a2[2], a3[3], a4[4], a5[5], a6[6], a7[7], a8[8], a15[15]; + +extern VC1 c1; +extern VC2 c2; +extern VC4 c4; +extern VC8 c8; +extern VC16 c16; + +extern VC1 fc1 (void); +extern VC2 fc2 (void); +extern VC4 fc4 (void); +extern VC8 fc8 (void); +extern VC16 fc16 (void); + +void nowarn (void) +{ + *(VC1*)a1 = C1; + *(VC2*)a2 = C2; + *(VC4*)a4 = C4; + *(VC4*)a5 = C4; + *(VC4*)a6 = C4; + *(VC4*)a7 = C4; + *(VC8*)a8 = C8; + *(VC8*)a15 = C8; +} + +void warn_vec_lit (void) +{ + *(VC2*)a1 = C2; // { dg-warning "writing 2 bytes into a region of size 1" } + *(VC4*)a2 = C4; // { dg-warning "writing 4 bytes into a region of size 2" } + *(VC4*)a3 = C4; // { dg-warning "writing 4 bytes into a region of size 3" } + *(VC8*)a4 = C8; // { dg-warning "writing 8 bytes into a region of size 4" } + *(VC8*)a7 = C8; // { dg-warning "writing 8 bytes into a region of size 7" } + *(VC16*)a15 = C16; // { dg-warning "writing 16 bytes into a region of size 15" } +} + +void warn_vec_decl (void) +{ + *(VC2*)a1 = c2; // { dg-warning "writing 2 bytes into a region of size 1" } + *(VC4*)a2 = c4; // { dg-warning "writing 4 bytes into a region of size 2" } + *(VC4*)a3 = c4; // { dg-warning "writing 4 bytes into a region of size 3" } + *(VC8*)a4 = c8; // { dg-warning "writing 8 bytes into a region of size 4" } + *(VC8*)a7 = c8; // { dg-warning "writing 8 bytes into a region of size 7" } + *(VC16*)a15 = c16; // { dg-warning "writing 16 bytes into a region of size 15" } +} + +void warn_vec_parm (VC2 pc2, VC4 pc4, VC8 pc8, VC16 pc16) +{ + *(VC2*)a1 = pc2; // { dg-warning "writing 2 bytes into a region of size 1" } + *(VC4*)a2 = pc4; // { dg-warning "writing 4 bytes into a region of size 2" } + *(VC4*)a3 = pc4; // { dg-warning "writing 4 bytes into a region of size 3" } + *(VC8*)a4 = pc8; // { dg-warning "writing 8 bytes into a region of size 4" } + *(VC8*)a7 = pc8; // { dg-warning "writing 8 bytes into a region of size 7" } + *(VC16*)a15 = pc16; // { dg-warning "writing 16 bytes into a region of size 15" } +} + +void warn_vec_func (void) +{ + *(VC2*)a1 = fc2 (); // { dg-warning "writing 2 bytes into a region of size 1" } + *(VC4*)a2 = fc4 (); // { dg-warning "writing 4 bytes into a region of size 2" } + *(VC4*)a3 = fc4 (); // { dg-warning "writing 4 bytes into a region of size 3" } + *(VC8*)a4 = fc8 (); // { dg-warning "writing 8 bytes into a region of size 4" } + *(VC8*)a7 = fc8 (); // { dg-warning "writing 8 bytes into a region of size 7" } + *(VC16*)a15 = fc16 ();// { dg-warning "writing 16 bytes into a region of size 15" } +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c new file mode 100644 index 0000000..5d8bfa9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/97027 - missing warning on buffer overflow storing + a larger scalar into a smaller array + Verify overflow by vector stores. + { dg-do compile } + { dg-options "-O3" } */ + +void* nowarn_loop (void) +{ + char *p = __builtin_malloc (16); + for (int i = 0; i != 16; ++i) + p[i] = i; + return p; +} + +void* warn_loop (void) +{ + char *p = __builtin_malloc (15); + for (int i = 0; i != 16; ++i) + p[i] = i; // { dg-warning "writing 16 bytes into a region of size 15" } + return p; +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c new file mode 100644 index 0000000..dccee35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c @@ -0,0 +1,105 @@ +/* PR tree-optimization/97027 - missing warning on buffer overflow storing + a larger scalar into a smaller array + Verify warnings for overflow by stores of results of built-in functions. + { dg-do compile } + { dg-options "-O2" } */ + +typedef __INT16_TYPE__ int16_t; +typedef __SIZE_TYPE__ size_t; + +extern int abs (int); + +extern void* alloca (size_t); + +extern double nan (const char *); +_Decimal32 nand32 (const char *); + +extern size_t strlen (const char *); +extern char* strcpy (char *, const char *); + + +extern unsigned char ax[], a1[1], a2[2], a8[8]; + + +void nowarn_abs (int i) +{ + *(int *)ax = abs (i); + *(char *)a1 = abs (i); +} + +void warn_abs (int i) +{ + *(int *)a1 = abs (i); // { dg-warning "\\\[-Wstringop-overflow" } +} + + +void nowarn_alloca (size_t n) +{ + *(void **)ax = alloca (n); +} + +void warn_alloca (size_t n) +{ + *(void **)a1 = alloca (n); // { dg-warning "\\\[-Wstringop-overflow" } +} + + +void nowarn_complex (double x, double i) +{ + *(_Complex double *)ax = __builtin_complex (x, i); +} + +void warn_complex (double x, double i) +{ + _Complex double *p = (_Complex double *)a1; + *p = __builtin_complex (x, i); // { dg-warning "\\\[-Wstringop-overflow" "pr101455" { xfail *-*-* } } +} + + +void nowarn_nan (const char *s) +{ + *(double *)ax = nan (s); +} + +void warn_nan (const char *s) +{ + *(double *)a1 = nan (s); // { dg-warning "\\\[-Wstringop-overflow" } +} + + +void nowarn_nand32 (const char *s) +{ + *(_Decimal32 *)ax = nand32 (s); +} + +void warn_nand32 (const char *s) +{ + *(_Decimal32 *)a1 = nand32 (s); // { dg-warning "\\\[-Wstringop-overflow" } +} + + +void nowarn_strlen (const char *s1, const char *s2, const char *s3) +{ + *(char *)ax = strlen (s1); + *(char *)a1 = strlen (s2); + *(size_t *)a8 = strlen (s3); +} + +void warn_strlen (const char *s1, const char *s2) +{ + *(int16_t *)a1 = strlen (s1); // { dg-warning "\\\[-Wstringop-overflow" } + *(size_t *)a2 = strlen (s2); // { dg-warning "\\\[-Wstringop-overflow" } +} + + +void nowarn_strcpy (char *s1, char *s2, const char *s3) +{ + *(char **)ax = strcpy (s1, s2); + *(char **)a8 = strcpy (s2, s3); +} + +void warn_strcpy (char *s1, char *s2, const char *s3) +{ + *(char **)a1 = strcpy (s1, s2); // { dg-warning "\\\[-Wstringop-overflow" } + *(char **)a2 = strcpy (s2, s3); // { dg-warning "\\\[-Wstringop-overflow" } +} diff --git a/gcc/testsuite/gcc.dg/strlenopt-95.c b/gcc/testsuite/gcc.dg/strlenopt-95.c new file mode 100644 index 0000000..505bc99 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-95.c @@ -0,0 +1,65 @@ +/* Verify strlen results of vector assignments. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#include "strlenopt.h" + +#define V(N) __attribute__ ((vector_size (N))) + +typedef V (1) char VC1; +typedef V (2) char VC2; +typedef V (4) char VC4; +typedef V (8) char VC8; +typedef V (16) char VC16; + +extern char a[]; + +#define A(expr) ((expr) ? (void)0 : abort ()) + +void test_fold (int i) +{ + *(VC4*)a = (VC4){ }; + A (strlen (a) == 0); + A (!a[1] && !a[2] && !a[3]); + + *(VC4*)a = (VC4){ 0, 1 }; + A (strlen (a) == 0); + A (a[1] == 1 && !a[2] && !a[3]); + + *(VC4*)a = (VC4){ 1 }; + A (strlen (a) == 1); + A (!a[1] && !a[2] && !a[3]); + + *(VC4*)a = (VC4){ 1, 0, 3 }; + A (strlen (a) == 1); + A (!a[1] && a[2] == 3 && !a[3]); + + *(VC4*)a = (VC4){ 1, 2 }; + A (strlen (a) == 2); + A (!a[2] && !a[3]); + + *(VC4*)a = (VC4){ 1, 2, 0, 4 }; + A (strlen (a) == 2); + A (!a[2] && a[3] == 4); + + *(VC4*)a = (VC4){ 1, 2, 3 }; + A (strlen (a) == 3); + A (!a[3]); + + *(VC8*)a = (VC8){ 1, 2, 3, 0, 5 }; + A (strlen (a) == 3); + + *(VC8*)a = (VC8){ 1, 2, 3, 0, 5, 6 }; + A (strlen (a) == 3); + + *(VC8*)a = (VC8){ 1, 2, 3, 0, 5, 6, 7 }; + A (strlen (a) == 3); + A (strlen (a + 1) == 2); + A (strlen (a + 2) == 1); + A (strlen (a + 3) == 0); + + A (a[4] == 5 && a[5] == 6 && a[6] == 7 && a[7] == 8); +} + +/* { dg-final { scan-tree-dump-not "abort \\(" "strlen1" } } + { dg-final { scan-tree-dump-not "strlen \\(" "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr69170.c b/gcc/testsuite/gcc.dg/torture/pr69170.c index 2af0bde..a39125a 100644 --- a/gcc/testsuite/gcc.dg/torture/pr69170.c +++ b/gcc/testsuite/gcc.dg/torture/pr69170.c @@ -6,7 +6,7 @@ typedef struct { char buf[]; } hash_state; int a; -hash_state b; +extern hash_state b; void fn1() { a = 0; diff --git a/gcc/testsuite/gcc.dg/torture/pr70025.c b/gcc/testsuite/gcc.dg/torture/pr70025.c index 6c43a0a..7cf28c4 100644 --- a/gcc/testsuite/gcc.dg/torture/pr70025.c +++ b/gcc/testsuite/gcc.dg/torture/pr70025.c @@ -80,3 +80,8 @@ main () __builtin_abort (); return 0; } + +/* At -O3 the loop in bar() is vectorized and results in a (possibly + unreachable) out-of-bounds store to p.d7[8]: + _22(D)->d7[8] = _122; + { dg-prune-output "-Wstringop-overflow" } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr97769.c b/gcc/testsuite/gcc.dg/vect/pr97769.c index 127f91a..59e0b46 100644 --- a/gcc/testsuite/gcc.dg/vect/pr97769.c +++ b/gcc/testsuite/gcc.dg/vect/pr97769.c @@ -25,7 +25,7 @@ fn2(tmp *p1) { char *d = (char *)p1->d1; int *b = p1->h1; - for (int a; a; a++, d += 4) + for (int a = 0; a; a++, d += 4) fn1(d, *b++); } -- cgit v1.1 From 3bf6e1f89dbd2c67c419d3d4e94085208611262f Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Fri, 16 Jul 2021 15:56:35 +0100 Subject: testsuite: fix IL32 issues with usdot tests. Fix tests when int == long by using long long instead. gcc/testsuite/ChangeLog: PR middle-end/101457 * gcc.dg/vect/vect-reduc-dot-19.c: Use long long. * gcc.dg/vect/vect-reduc-dot-20.c: Likewise. * gcc.dg/vect/vect-reduc-dot-21.c: Likewise. * gcc.dg/vect/vect-reduc-dot-22.c: Likewise. --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c | 8 ++++---- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c | 8 ++++---- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c | 6 +++--- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c index dbeaaec..d00f24a 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c @@ -13,15 +13,15 @@ #define SIGNEDNESS_4 unsigned #endif -SIGNEDNESS_1 long __attribute__ ((noipa)) -f (SIGNEDNESS_1 long res, SIGNEDNESS_3 char *restrict a, +SIGNEDNESS_1 long long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long long res, SIGNEDNESS_3 char *restrict a, SIGNEDNESS_4 short *restrict b) { for (__INTPTR_TYPE__ i = 0; i < N; ++i) { int av = a[i]; int bv = b[i]; - SIGNEDNESS_2 long mult = av * bv; + SIGNEDNESS_2 long long mult = av * bv; res += mult; } return res; @@ -37,7 +37,7 @@ main (void) SIGNEDNESS_3 char a[N]; SIGNEDNESS_4 short b[N]; - int expected = 0x12345; + SIGNEDNESS_1 long long expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c index d757fb1..17adbca8 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c @@ -13,15 +13,15 @@ #define SIGNEDNESS_4 unsigned #endif -SIGNEDNESS_1 long __attribute__ ((noipa)) -f (SIGNEDNESS_1 long res, SIGNEDNESS_3 short *restrict a, +SIGNEDNESS_1 long long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long long res, SIGNEDNESS_3 short *restrict a, SIGNEDNESS_4 char *restrict b) { for (__INTPTR_TYPE__ i = 0; i < N; ++i) { int av = a[i]; int bv = b[i]; - SIGNEDNESS_2 long mult = av * bv; + SIGNEDNESS_2 long long mult = av * bv; res += mult; } return res; @@ -37,7 +37,7 @@ main (void) SIGNEDNESS_3 short a[N]; SIGNEDNESS_4 char b[N]; - int expected = 0x12345; + SIGNEDNESS_1 long long expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c index 6d08bf4..6cc6a4f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c @@ -13,8 +13,8 @@ #define SIGNEDNESS_4 unsigned #endif -SIGNEDNESS_1 long __attribute__ ((noipa)) -f (SIGNEDNESS_1 long res, SIGNEDNESS_3 char *restrict a, +SIGNEDNESS_1 long long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long long res, SIGNEDNESS_3 char *restrict a, SIGNEDNESS_4 short *restrict b) { for (__INTPTR_TYPE__ i = 0; i < N; ++i) @@ -37,7 +37,7 @@ main (void) SIGNEDNESS_3 char a[N]; SIGNEDNESS_4 short b[N]; - int expected = 0x12345; + SIGNEDNESS_1 long long expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c index 0bde43a..e13d3d5 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c @@ -13,8 +13,8 @@ #define SIGNEDNESS_4 unsigned #endif -SIGNEDNESS_1 long __attribute__ ((noipa)) -f (SIGNEDNESS_1 long res, SIGNEDNESS_3 char *restrict a, +SIGNEDNESS_1 long long __attribute__ ((noipa)) +f (SIGNEDNESS_1 long long res, SIGNEDNESS_3 char *restrict a, SIGNEDNESS_4 short *restrict b) { for (__INTPTR_TYPE__ i = 0; i < N; ++i) @@ -37,7 +37,7 @@ main (void) SIGNEDNESS_3 char a[N]; SIGNEDNESS_4 short b[N]; - SIGNEDNESS_1 long expected = 0x12345; + SIGNEDNESS_1 long long expected = 0x12345; for (int i = 0; i < N; ++i) { a[i] = BASE + i * 5; -- cgit v1.1 From 94ba897be8b59ef5926eed4c77fd53812fb20add Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 16 Jul 2021 11:08:58 -0600 Subject: PR testsuite/101468 - Wstringop-overflow tests failures gcc/testsuite/ChangeLog: PR testsuite/101468 * gcc.dg/Wstringop-overflow-41.c: Adjust to avoid target-specific failures. * gcc.dg/Wstringop-overflow-42.c: Same. * gcc.dg/Wstringop-overflow-68.c: Same. * gcc.dg/Wstringop-overflow-70.c: Same. * gcc.dg/Wstringop-overflow-71.c: Same. * gcc.dg/strlenopt-95.c: Fix typos. --- gcc/testsuite/gcc.dg/Wstringop-overflow-41.c | 3 ++- gcc/testsuite/gcc.dg/Wstringop-overflow-42.c | 12 ++++++------ gcc/testsuite/gcc.dg/Wstringop-overflow-68.c | 12 ++++++------ gcc/testsuite/gcc.dg/Wstringop-overflow-70.c | 5 ++++- gcc/testsuite/gcc.dg/Wstringop-overflow-71.c | 22 +++++++++++++++------- gcc/testsuite/gcc.dg/strlenopt-95.c | 8 ++++---- 6 files changed, 37 insertions(+), 25 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c index 9b2d2cb..e255e67 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c @@ -29,7 +29,8 @@ void char_array_cst_off_cst_size (void) sink (p); ++idx; - memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" "pr?????" { xfail ilp32 } } + memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" } + sink (p); ++idx; memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 0" } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c index 4bb22f2..8527eea 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c @@ -23,21 +23,21 @@ void cpy_ui_1_max (unsigned i, const char *s) { if (i < 1) i = 1; d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" } - d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { xfail ilp32 } } + d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { xfail { ! lp64 } } } } void cpy_sl_1_max (long i, const char *s) { if (i < 1) i = 1; - d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" } - d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" } + d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { target { ! ptr_eq_short } } } + d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { target { ! ptr_eq_short } } } } void cpy_ul_1_max (unsigned long i, const char *s) { if (i < 1) i = 1; - d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" } + d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { target { ! ptr_eq_short } } } /* Because of integer wraparound the offset's range is [1, 0] so the overflow isn't diagnosed (yet). */ @@ -56,7 +56,7 @@ void cpy_si_min_m1 (int i, const char *s) void cpy_sl_min_m1 (long i, const char *s) { if (i > -1) i = -1; - d = strcpy (a + i - 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" } - d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" } + d = strcpy (a + i - 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { target { ! ptr_eq_short } } } + d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { target { ! ptr_eq_short } } } d = strcpy (a + i + 2, s); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c index d2d3ae5..6bcba27 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c @@ -57,12 +57,12 @@ void warn_comp_lit_zero (void) void warn_comp_lit (void) { - *(AC2*)a1 = Ac2; // { dg-warning "writing 2 bytes into a region of size 1" "pr??????" { xfail *-*-* } } - *(AC4*)a2 = Ac4; // { dg-warning "writing 4 bytes into a region of size 2" "pr??????" { xfail *-*-* } } - *(AC4*)a3 = Ac4; // { dg-warning "writing 4 bytes into a region of size 3" "pr??????" { xfail *-*-* } } - *(AC8*)a4 = Ac8; // { dg-warning "writing 8 bytes into a region of size 4" "pr??????" { xfail *-*-* } } - *(AC8*)a7 = Ac8; // { dg-warning "writing 8 bytes into a region of size 7" "pr??????" { xfail *-*-* } } - *(AC16*)a15 = Ac16; // { dg-warning "writing 16 bytes into a region of size 15" "pr??????" { xfail *-*-* } } + *(AC2*)a1 = Ac2; // { dg-warning "writing 2 bytes into a region of size 1" "pr101475" { xfail *-*-* } } + *(AC4*)a2 = Ac4; // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail *-*-* } } + *(AC4*)a3 = Ac4; // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail *-*-* } } + *(AC8*)a4 = Ac8; // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail *-*-* } } + *(AC8*)a7 = Ac8; // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail *-*-* } } + *(AC16*)a15 = Ac16; // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail *-*-* } } } void warn_aggr_decl (void) diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c index 5d8bfa9..82c4d9f 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-70.c @@ -16,6 +16,9 @@ void* warn_loop (void) { char *p = __builtin_malloc (15); for (int i = 0; i != 16; ++i) - p[i] = i; // { dg-warning "writing 16 bytes into a region of size 15" } + /* The size of the write below depends on the target. When vectorized + the vector size may be 4 or 16, otherwise it may be a series of byte + assignments. */ + p[i] = i; // { dg-warning "writing (1|2|4|16) bytes? into a region of size (0|1|3|15)" } return p; } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c index dccee35..f56a005 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-71.c @@ -12,7 +12,15 @@ extern int abs (int); extern void* alloca (size_t); extern double nan (const char *); -_Decimal32 nand32 (const char *); + +#ifdef __DEC32_MAX__ + _Decimal32 nand32 (const char *); +#else +/* _Decimal32 is supported only conditionally and not available on all + targets. */ +# define _Decimal32 double +# define nand32(s) nan (s) +#endif extern size_t strlen (const char *); extern char* strcpy (char *, const char *); @@ -56,23 +64,23 @@ void warn_complex (double x, double i) } -void nowarn_nan (const char *s) +__attribute__ ((noipa)) void nowarn_nan (const char *s) { *(double *)ax = nan (s); } -void warn_nan (const char *s) +__attribute__ ((noipa)) void warn_nan (const char *s) { *(double *)a1 = nan (s); // { dg-warning "\\\[-Wstringop-overflow" } } -void nowarn_nand32 (const char *s) +__attribute__ ((noipa)) void nowarn_nand32 (const char *s) { *(_Decimal32 *)ax = nand32 (s); } -void warn_nand32 (const char *s) +__attribute__ ((noipa)) void warn_nand32 (const char *s) { *(_Decimal32 *)a1 = nand32 (s); // { dg-warning "\\\[-Wstringop-overflow" } } @@ -88,7 +96,7 @@ void nowarn_strlen (const char *s1, const char *s2, const char *s3) void warn_strlen (const char *s1, const char *s2) { *(int16_t *)a1 = strlen (s1); // { dg-warning "\\\[-Wstringop-overflow" } - *(size_t *)a2 = strlen (s2); // { dg-warning "\\\[-Wstringop-overflow" } + *(size_t *)a2 = strlen (s2); // { dg-warning "\\\[-Wstringop-overflow" "!ptr_eq_short" { target { ! ptr_eq_short } } } } @@ -101,5 +109,5 @@ void nowarn_strcpy (char *s1, char *s2, const char *s3) void warn_strcpy (char *s1, char *s2, const char *s3) { *(char **)a1 = strcpy (s1, s2); // { dg-warning "\\\[-Wstringop-overflow" } - *(char **)a2 = strcpy (s2, s3); // { dg-warning "\\\[-Wstringop-overflow" } + *(char **)a2 = strcpy (s2, s3); // { dg-warning "\\\[-Wstringop-overflow" "!ptr_eq_short" { target { ! ptr_eq_short } } } } diff --git a/gcc/testsuite/gcc.dg/strlenopt-95.c b/gcc/testsuite/gcc.dg/strlenopt-95.c index 505bc99..6e0a79d 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-95.c +++ b/gcc/testsuite/gcc.dg/strlenopt-95.c @@ -1,6 +1,6 @@ /* Verify strlen results of vector assignments. { dg-do compile } - { dg-options "-O2 -Wall" } */ + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ #include "strlenopt.h" @@ -52,7 +52,7 @@ void test_fold (int i) *(VC8*)a = (VC8){ 1, 2, 3, 0, 5, 6 }; A (strlen (a) == 3); - *(VC8*)a = (VC8){ 1, 2, 3, 0, 5, 6, 7 }; + *(VC8*)a = (VC8){ 1, 2, 3, 0, 5, 6, 7, 8 }; A (strlen (a) == 3); A (strlen (a + 1) == 2); A (strlen (a + 2) == 1); @@ -61,5 +61,5 @@ void test_fold (int i) A (a[4] == 5 && a[5] == 6 && a[6] == 7 && a[7] == 8); } -/* { dg-final { scan-tree-dump-not "abort \\(" "strlen1" } } - { dg-final { scan-tree-dump-not "strlen \\(" "strlen1" } } */ +/* { dg-final { scan-tree-dump-not "abort \\(" "optimized" } } + { dg-final { scan-tree-dump-not "strlen \\(" "optimized" } } */ -- cgit v1.1 From 9ea10c480565fa42b1804fb436f7e26ca77b71a3 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 16 Jul 2021 15:47:06 -0400 Subject: analyzer: add __analyzer_dump_state gcc/analyzer/ChangeLog: * engine.cc (exploded_node::on_stmt_pre): Handle __analyzer_dump_state. * program-state.cc (extrinsic_state::get_sm_idx_by_name): New. (program_state::impl_call_analyzer_dump_state): New. * program-state.h (extrinsic_state::get_sm_idx_by_name): New decl. (program_state::impl_call_analyzer_dump_state): New decl. * region-model-impl-calls.cc (call_details::get_arg_string_literal): New. * region-model.h (call_details::get_arg_string_literal): New decl. gcc/ChangeLog: * doc/analyzer.texi: Add __analyzer_dump_state. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/analyzer-decls.h (__analyzer_dump_state): New. * gcc.dg/analyzer/dump-state.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h | 5 +++++ gcc/testsuite/gcc.dg/analyzer/dump-state.c | 14 ++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/dump-state.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h index 2446693..e8745c0 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h +++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h @@ -35,6 +35,11 @@ extern void __analyzer_dump_path (void); /* Dump the region_model's state to stderr. */ extern void __analyzer_dump_region_model (void); +/* Emit a warning describing the state of the 2nd argument + (which can be of any type) with respect to NAME. + This is for use when debugging, and may be of use in DejaGnu tests. */ +extern void __analyzer_dump_state (const char *name, ...); + /* Emit a warning with text "TRUE", FALSE" or "UNKNOWN" based on the truthfulness of the argument. */ extern void __analyzer_eval (int); diff --git a/gcc/testsuite/gcc.dg/analyzer/dump-state.c b/gcc/testsuite/gcc.dg/analyzer/dump-state.c new file mode 100644 index 0000000..618a5a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/dump-state.c @@ -0,0 +1,14 @@ +/* Verify that __analyzer_dump_state works as expected. */ + +#include +#include "analyzer-decls.h" + +void test_1 (void) +{ + void *p = malloc (1024); + __analyzer_dump_state ("malloc", p); /* { dg-warning "state: 'unchecked'" } */ + free (p); + __analyzer_dump_state ("malloc", p); /* { dg-warning "state: 'freed'" } */ + __analyzer_dump_state (NULL, p); /* { dg-error "cannot determine state machine" } */ + __analyzer_dump_state ("not a state machine", p); /* { dg-error "unrecognized state machine 'not a state machine'" } */ +} -- cgit v1.1 From 704e8a825c78b9a8424c291509413bbb48e602c7 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Fri, 16 Jul 2021 11:42:14 -0400 Subject: Add wi_fold_in_parts. range-ops uses wi_fold to individually fold subranges one at a time and then combined them. This patch first calls wi_fold_in_parts which checks if one of the subranges is small, and if so, further splits that subrange into constants. gcc/ PR tree-optimization/96542 * range-op.cc (range_operator::wi_fold_in_parts): New. (range_operator::fold_range): Call wi_fold_in_parts. (operator_lshift::wi_fold): Fix broken lshift by [0,0]. * range-op.h (wi_fold_in_parts): Add prototype. gcc/testsuite * gcc.dg/pr96542.c: New. --- gcc/testsuite/gcc.dg/pr96542.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr96542.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr96542.c b/gcc/testsuite/gcc.dg/pr96542.c new file mode 100644 index 0000000..5014f2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr96542.c @@ -0,0 +1,27 @@ +/* { dg-do compile} */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + + +unsigned char +foo (unsigned int x) +{ + _Bool y = x; + return (((unsigned char) ~0) >> y) * 2; +} + +unsigned char +bar (unsigned int x) +{ + return (((unsigned char) ~0) >> (_Bool) x) * 2; +} + +unsigned +baz (unsigned int x) +{ + if (x >= 4) return 32; + return (-1U >> x) * 16; +} + +/* { dg-final { scan-tree-dump-times "254" 2 "evrp" } } */ +/* { dg-final { scan-tree-dump "= PHI <32.*, 4294967280" "evrp" } } */ + -- cgit v1.1 From 0103d18dfc9a29bea69e5122fbdf3477d3e1384f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 17 Jul 2021 14:24:19 +0200 Subject: Support EAF_NOT_RETURNED in tree-ssa-structalias gcc/ChangeLog: 2021-07-17 Jan Hubicka * tree-ssa-structalias.c (handle_rhs_call): Support EAF_NOT_RETURNED. (handle_const_call): Liekise (handle_pure_call): Liekise gcc/testsuite/ChangeLog: 2021-07-17 Jan Hubicka * gcc.dg/tree-ssa/modref-6.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/modref-6.c | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/modref-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c new file mode 100644 index 0000000..8db9a1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c @@ -0,0 +1,37 @@ +/* { dg-options "-O2 -fdump-tree-modref1 -fdump-tree-optimized" } */ +/* { dg-do compile } */ +int c; +__attribute__ ((noinline)) +int *test (int *b) +{ + c++; + return *b ? &c : 0; +} +__attribute__ ((noinline, pure)) +int *pure_test (int *b) +{ + return *b && c ? &c : 0; +} +__attribute__ ((noinline, const)) +int *const_test (int *b) +{ + return b ? &c : 0; +} +void escape (int *); + +int test2() +{ + int a = 42; + escape (test (&a)); + escape (pure_test (&a)); + escape (const_test (&a)); + return a; +} +/* Flags for normal call. */ +/* { dg-final { scan-tree-dump "parm 0 flags: direct noclobber noescape nodirectescape not_returned" "modref1" } } */ +/* Flags for pure call. */ +/* { dg-final { scan-tree-dump "parm 0 flags: direct not_returned" "modref1" } } */ +/* Flags for const call. */ +/* { dg-final { scan-tree-dump "parm 0 flags: unused not_returned" "modref1" } } */ +/* Overall we want to make "int a" non escaping. */ +/* { dg-final { scan-tree-dump "return 42" "optimized" } } */ -- cgit v1.1 From 8df3ee8f7d85d0708f3c3ca96b55c9230c2ae9f0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 19 Jul 2021 13:29:16 +0200 Subject: tree-optimization/101505 - properly determine stmt precision for PHIs Loop vectorization pattern recog fails to walk PHIs when determining stmt precisions. This fails to recognize non-mask uses for bools in PHIs and outer loop vectorization. 2021-07-19 Richard Biener PR tree-optimization/101505 * tree-vect-patterns.c (vect_determine_precisions): Walk PHIs also for loop vectorization. * gcc.dg/vect/pr101505.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr101505.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr101505.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr101505.c b/gcc/testsuite/gcc.dg/vect/pr101505.c new file mode 100644 index 0000000..e2b8945 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr101505.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O1" } */ + +int n2; + +__attribute__ ((simd)) char +w7 (void) +{ + short int xb = n2; + int qp; + + for (qp = 0; qp < 2; ++qp) + xb = xb < 1; + + return xb; +} -- cgit v1.1 From f007a638a86e4b59bef0a0d8efa5bb8c5e5b200a Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Mon, 19 Jul 2021 10:24:59 -0700 Subject: debug: Allow means for targets to opt out of CTF/BTF support CTF/BTF debug formats can be safely enabled for all ELF-based targets by default in GCC. CTF/BTF debug formats now adopt a similar approach as taken for DWARF debug format via the DWARF2_DEBUGGING_INFO. - By default, CTF/BTF formats can be enabled for all ELF-based targets. - By default, CTF/BTF formats can be disabled for all non ELF-based targets. - If the user passed a -gctf but CTF is not enabled for the target, GCC issues an error to the user (as is done currently with other debug formats) - "target system does not support the 'ctf' debug format". Analogous behavior for -gbtf command line option. A previous commit disabled the CTF and BTF testcases on the AIX platform. This is not necessary now that CTF and BTF debug formats are disabled by default on all non-ELF targets. GCC emits an error message when -gctf/-gbtf is used on such platforms and these tests will be skipped. gcc/ * config/elfos.h (CTF_DEBUGGING_INFO): New definition. (BTF_DEBUGGING_INFO): Likewise. * doc/tm.texi.in: Document the new macros. * doc/tm.texi: Regenerated. * toplev.c: Guard initialization of debug hooks. gcc/testsuite/ * gcc.dg/debug/btf/btf.exp: Do not run BTF testsuite if target does not support BTF format. Remove redundant check for AIX. * gcc.dg/debug/ctf/ctf.exp: Do not run CTF testsuite if target does not support CTF format. Remove redundant check for AIX. * lib/gcc-dg.exp: Remove redundant check for AIX. --- gcc/testsuite/gcc.dg/debug/btf/btf.exp | 16 +++++++++------- gcc/testsuite/gcc.dg/debug/ctf/ctf.exp | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf.exp b/gcc/testsuite/gcc.dg/debug/btf/btf.exp index e173515..15593fd 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf.exp +++ b/gcc/testsuite/gcc.dg/debug/btf/btf.exp @@ -24,11 +24,6 @@ if { [istarget nvptx-*-*] } { return } -if { [istarget "powerpc-ibm-aix*"] } { - set torture_execute_xfail "powerpc-ibm-aix*" - return -} - # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { @@ -39,8 +34,15 @@ if ![info exists DEFAULT_CFLAGS] then { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ - "" $DEFAULT_CFLAGS +set comp_output [gcc_target_compile \ + "$srcdir/$subdir/../trivial.c" "trivial.S" assembly \ + "additional_flags=-gbtf"] +if { ! [string match "*: target system does not support the * debug format*" \ + $comp_output] } { + remove-build-file "trivial.S" + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ + "" $DEFAULT_CFLAGS +} # All done. dg-finish diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp index 0b650ed..7ad6723 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp @@ -24,11 +24,6 @@ if { [istarget nvptx-*-*] } { return } -if { [istarget "powerpc-ibm-aix*"] } { - set torture_execute_xfail "powerpc-ibm-aix*" - return -} - # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { @@ -39,8 +34,15 @@ if ![info exists DEFAULT_CFLAGS] then { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ - "" $DEFAULT_CFLAGS +set comp_output [gcc_target_compile \ + "$srcdir/$subdir/../trivial.c" "trivial.S" assembly \ + "additional_flags=-gctf"] +if { ! [string match "*: target system does not support the * debug format*" \ + $comp_output] } { + remove-build-file "trivial.S" + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ + "" $DEFAULT_CFLAGS +} # All done. dg-finish -- cgit v1.1 From a113b14398f2a4ad2742e6e9c87e25cac60f263e Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 19 Jul 2021 15:44:02 -0400 Subject: analyzer: add svalue::can_have_associated_state_p [PR101503] PR analyzer/101503 reports an assertion failure due to an unexpected "UNKNOWN" value (due to using --param analyzer-max-svalue-depth=0). This patch fixes this by rejecting attempts to purge state involving unknown/poisoned svalues (in region_model::purge_state_involving), as these svalues should not have state associated with them - they are singletons w.r.t each type. To be more systematic about this, the patch also introduces a new svalue::can_have_associated_state_p which returns false for unknown/poisoned svalues, so that we can reject adding constraints or sm-state on them, or building various kinds of svalue in terms of them (e.g. unary ops, binary ops, etc). gcc/analyzer/ChangeLog: PR analyzer/101503 * constraint-manager.cc (constraint_manager::add_constraint): Use can_have_associated_state_p rather than testing for unknown. (constraint_manager::get_or_add_equiv_class): Likewise. * program-state.cc (sm_state_map::set_state): Likewise. (sm_state_map::impl_set_state): Add assertion. * region-model-manager.cc (region_model_manager::maybe_fold_unaryop): Handle poisoned values. (region_model_manager::maybe_fold_binop): Move handling of unknown values... (region_model_manager::get_or_create_binop): ...to here, and generalize to use can_have_associated_state_p. (region_model_manager::maybe_fold_sub_svalue): Use can_have_associated_state_p rather than testing for unknown. (region_model_manager::maybe_fold_repeated_svalue): Use unknown when the size or repeated value is "unknown"/"poisoned". * region-model.cc (region_model::purge_state_involving): Reject attempts to purge unknown/poisoned svalues, as these svalues should not have state associated with them. * svalue.cc (sub_svalue::sub_svalue): Assert that we're building on top of an svalue with can_have_associated_state_p. (repeated_svalue::repeated_svalue): Likewise. (bits_within_svalue::bits_within_svalue): Likewise. * svalue.h (svalue::can_have_associated_state_p): New. (unknown_svalue::can_have_associated_state_p): New. (poisoned_svalue::can_have_associated_state_p): New. (unaryop_svalue::unaryop_svalue): Assert that we're building on top of an svalue with can_have_associated_state_p. (binop_svalue::binop_svalue): Likewise. (widening_svalue::widening_svalue): Likewise. gcc/testsuite/ChangeLog: PR analyzer/101503 * gcc.dg/analyzer/pr101503.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/pr101503.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101503.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101503.c b/gcc/testsuite/gcc.dg/analyzer/pr101503.c new file mode 100644 index 0000000..16faf6e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101503.c @@ -0,0 +1,11 @@ +/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */ + +int val; + +int +fn (void) +{ + val = fn (); + + return 0; +} -- cgit v1.1 From e0e82856d535f56c916382f892ed2435dde54d4d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 20 Jul 2021 17:26:10 +0200 Subject: rs6000: Fix up easy_vector_constant_msb handling [PR101384] The following gcc.dg/pr101384.c testcase is miscompiled on powerpc64le-linux. easy_altivec_constant has code to try construct vector constants with different element sizes, perhaps different from CONST_VECTOR's mode. But as written, that works fine for vspltis[bhw] cases, but not for the vspltisw x,-1; vsl[bhw] x,x,x case, because that creates always a V16QImode, V8HImode or V4SImode constant containing broadcasted constant with just the MSB set. The vspltis_constant function etc. expects the vspltis[bhw] instructions where the small [-16..15] or even [-32..30] constant is sign-extended to the remaining step bytes, but that is not the case for the 0x80...00 constants, with step > 1 we can't handle e.g. { 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff } vectors but do want to handle e.g. { 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80 } and similarly with copies > 1 we do want to handle e.g. { 0x80808080, 0x80808080, 0x80808080, 0x80808080 }. 2021-07-20 Jakub Jelinek PR target/101384 * config/rs6000/rs6000-protos.h (easy_altivec_constant): Change return type from bool to int. * config/rs6000/rs6000.c (vspltis_constant): Fix up handling the EASY_VECTOR_MSB case if either step or copies is not 1. (vspltis_shifted): Fix comment typo. (easy_altivec_constant): Change return type from bool to int, instead of returning true return byte size of the element mode that should be used to synthetize the constant. * config/rs6000/predicates.md (easy_vector_constant_msb): Require that vspltis_shifted is 0, handle the case where easy_altivec_constant assumes using different vector mode from CONST_VECTOR's mode. * config/rs6000/altivec.md (easy_vector_constant_msb splitter): Use easy_altivec_constant to determine mode in which -1 >> -1 should be performed, use rs6000_expand_vector_init instead of gen_vec_initv4sisi. * gcc.dg/pr101384.c: New test. * gcc.target/powerpc/pr101384-1.c: New test. * gcc.target/powerpc/pr101384-2.c: New test. --- gcc/testsuite/gcc.dg/pr101384.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101384.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101384.c b/gcc/testsuite/gcc.dg/pr101384.c new file mode 100644 index 0000000..7030c0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101384.c @@ -0,0 +1,39 @@ +/* PR target/101384 */ +/* { dg-do run } */ +/* { dg-options "-O2 -Wno-psabi -w" } */ + +typedef unsigned char __attribute__((__vector_size__ (16))) U; +typedef unsigned short __attribute__((__vector_size__ (8 * sizeof (short)))) V; + +U u; +V v; + +__attribute__((noipa)) U +foo (void) +{ + U y = (U) { 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, + 0x80, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff } + u; + return y; +} + +__attribute__((noipa)) V +bar (void) +{ + V y = (V) { 0x8000, 0xffff, 0x8000, 0xffff, + 0x8000, 0xffff, 0x8000, 0xffff } + v; + return y; +} + +int +main () +{ + U x = foo (); + for (unsigned i = 0; i < 16; i++) + if (x[i] != ((i & 3) ? 0xff : 0x80)) + __builtin_abort (); + V y = bar (); + for (unsigned i = 0; i < 8; i++) + if (y[i] != ((i & 1) ? 0xffff : 0x8000)) + __builtin_abort (); + return 0; +} -- cgit v1.1 From e07d30fdcaec4906e0dcb948fc4748bf74c15c05 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 20 Jul 2021 13:08:39 -0600 Subject: Handle all UBSAN built-ins in -Wuninitialized [PR101300]. Resolves: PR middle-end/101300 - -fsanitize=undefined suppresses -Wuninitialized for a VLA read at -O0 gcc/ChangeLog: PR middle-end/101300 * tree-ssa-uninit.c (check_defs): Handle UBSAN built-ins. gcc/testsuite/ChangeLog: PR middle-end/101300 * gcc.dg/uninit-pr101300.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr101300.c | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr101300.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr101300.c b/gcc/testsuite/gcc.dg/uninit-pr101300.c new file mode 100644 index 0000000..4392e8ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr101300.c @@ -0,0 +1,53 @@ +/* PR middle-end/101300 - -fsanitize=undefined suppresses -Wuninitialized + for a VLA read at -O0 + { dg-do compile } + { dg-options "-O0 -Wall -fsanitize=undefined" } */ + +int warn_vla_rd0 (int n) +{ + char a[n]; + return a[0]; // { dg-warning "\\\[-Wuninitialized]" } +} + +int warn_vla_rd1 (int n) +{ + char a[n]; + return a[1]; // { dg-warning "\\\[-Wuninitialized]" } +} + +int warn_vla_rdi (int n, int i) +{ + char a[n]; + return a[i]; // { dg-warning "\\\[-Wuninitialized]" } +} + + +int warn_vla_wr0_rd2_1_0 (int n) +{ + char a[n]; + a[0] = __LINE__; + int x = a[2]; // { dg-warning "\\\[-Wuninitialized]" } + int y = a[1]; // { dg-warning "\\\[-Wuninitialized]" } + int z = a[0]; + return x + y + z; +} + +int warn_vla_wr1_rd2_1_0 (int n) +{ + char a[n]; + a[1] = __LINE__; + int x = a[2]; // { dg-warning "\\\[-Wuninitialized]" } + int y = a[1]; + int z = a[0]; // { dg-warning "\\\[-Wuninitialized]" } + return x + y + z; +} + +int warn_vla_wr2_rd2_1_0 (int n) +{ + char a[n]; + a[2] = __LINE__; + int x = a[2]; + int y = a[1]; // { dg-warning "\\\[-Wuninitialized]" } + int z = a[0]; // { dg-warning "\\\[-Wuninitialized]" } + return x + y + z; +} -- cgit v1.1 From 8bf5b49ebd2176b8c535147377381dd07fbdd643 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 20 Jul 2021 13:48:20 -0600 Subject: Correct stpcpy offset computation for -Warray-bounds et al. [PR101397]. Resolves: PR middle-end/101397 - spurious warning writing to the result of stpcpy minus 1 gcc/ChangeLog: PR middle-end/101397 * builtins.c (gimple_call_return_array): Add argument. Correct offsets for memchr, mempcpy, stpcpy, and stpncpy. (compute_objsize_r): Adjust offset computation for argument returning built-ins. gcc/testsuite/ChangeLog: PR middle-end/101397 * gcc.dg/Warray-bounds-80.c: New test. * gcc.dg/Warray-bounds-81.c: New test. * gcc.dg/Warray-bounds-82.c: New test. * gcc.dg/Warray-bounds-83.c: New test. * gcc.dg/Warray-bounds-84.c: New test. * gcc.dg/Wstringop-overflow-46.c: Adjust expected output. --- gcc/testsuite/gcc.dg/Warray-bounds-80.c | 96 +++++++++ gcc/testsuite/gcc.dg/Warray-bounds-81.c | 302 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-82.c | 258 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-83.c | 172 +++++++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-84.c | 65 ++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-46.c | 5 +- 6 files changed, 895 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-80.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-81.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-82.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-83.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-84.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-80.c b/gcc/testsuite/gcc.dg/Warray-bounds-80.c new file mode 100644 index 0000000..4ef32fb --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-80.c @@ -0,0 +1,96 @@ +/* PR tree-optimization/101397 - spurious warning writing to the result + of stpcpy minus 1 + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +char* stpcpy (char*, const char*); + +void sink (int, ...); + +extern char ax[], a3[3], a5[5], *s; + +volatile int x; + +void test_stpcpy (int i) +{ + { + char *p = stpcpy (ax, s); + x = p[-9]; // { dg-bogus "\\\[-Warray-bounds" } + x = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + x = p[ 0]; + x = p[+9]; + } + + { + char *p = stpcpy (a3, s); + x = p[-2]; // { dg-bogus "\\\[-Warray-bounds" } + x = p[-1]; // { dg-bogus "\\\[-Warray-bounds" } + } + + { + char *p = stpcpy (a3, s); + x = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-2], p[-1], p[0], p[1], p[2]); + x = p[ 3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + /* Stpcpy always returns a pointer to the copied nul (which must + exist) and never a past-the-end pointer. As a result, P below + is in [a5, a5 + 4]. */ + char *p = stpcpy (a5, s); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = stpcpy (a5 + 1, s); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3]); + x = p[ 4]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = stpcpy (a5 + 2, s); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2]); + x = p[ 3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = stpcpy (a5 + 3, s); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1]); + x = p[ 2]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + /* Because strlen (a3) is at most 2, the stpcpy call must return + a pointer in the range [ax, ax + 2], and so -3 is necessarily + out of bounds. */ + char *p = stpcpy (ax, a3); + p[-3] = 1; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (i >= 0) + i = -1; + + char *p = stpcpy (a3, s); + x = p[i]; // { dg-bogus "\\\[-Warray-bounds" } + } + + { + if (i >= -3) + i = -3; + + char *p = stpcpy (a3, s); + p[i] = 1; // { dg-warning "\\\[-Warray-bounds" } + } + +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-81.c b/gcc/testsuite/gcc.dg/Warray-bounds-81.c new file mode 100644 index 0000000..27e725d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-81.c @@ -0,0 +1,302 @@ +/* PR tree-optimization/101397 - spurious warning writing to the result + of stpcpy minus 1 + Verify warnings for indexing into a pointer returned from stpncpy. + The call stpncpy(S1, S2, N) returns the address of the copy of + the first NUL is it exists or &S1[N] otherwise. + { dg-do compile } + { dg-options "-O2 -Wall -Wno-stringop-truncation" } */ + +typedef __SIZE_TYPE__ size_t; + +void* calloc (size_t, size_t); +char* stpncpy (char*, const char*, size_t); + +void sink (int, ...); + +extern char ax[], a3[3], a5[5], a7[7], a9[9], *s; + +volatile int x; + +/* Verify warnings for indexing into the result of stpncpy with a source + pointing to an array of unknown bound. */ + +void test_stpncpy_from_ptr (int i, int n) +{ + { + // P is in [ax, ax + 5]. + char *p = stpncpy (ax, s, 5); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-5], p[-1], p[0], p[9]); + } + + { + // P is in [a5, a5 + 3]. + char *p = stpncpy (a5, s, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[ 1], p[ 2], p[ 3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // P is in [ax, ax + 4]. + char *p = stpncpy (a5, s, 4); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[ 1], p[ 2], p[ 3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // P is in [ax, ax + 5]. + char *p = stpncpy (a5, s, n); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[ 1], p[ 2], p[ 3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // P is in [ax, ax + 4]. + char *p = stpncpy (a5, s, 4); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; + + if (i > -5) i = -5; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} + +/* Verify warnings for indexing into the result of stpncpy with a source + an array of size 5. */ + +void test_stpncpy_from_a5 (int i, int n, int n3_9) +{ + { + // The returned pointer is in [ax, ax + 3]. + char *p = stpncpy (ax, a5, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0], p[1], p[99]); + } + + { + // The returned pointer is in [ax, ax + 5]. + char *p = stpncpy (ax, a5, 5); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + { + //The returned pointer is in [ax, ax + 5] even though n is not known. + char *p = stpncpy (ax, a5, n); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-5], p[-4], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[9], p[99]); + } + + + { + // The returned pointer is in [a3, a3 + 3]. + char *p = stpncpy (a3, a5, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[ 1], p[ 2]); + x = p[ 3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is in [a3, a3 + 3]. + char *p = stpncpy (a3, a5, n); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[ 1], p[ 2]); + x = p[ 3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (n3_9 < 3 || 9 < n3_9) + n3_9 = 3; + + // The returned pointer is in [a3, a3 + 3]. + char *p = stpncpy (a3, a5, n3_9); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[ 1], p[ 2]); + x = p[ 3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = stpncpy (a3, a5, 3); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} + + +/* Verify warnings for indexing into the result of stpncpy with a source + an array of size 7. */ + +void test_stpncpy_from_a7 (int i, int n, int n3_9) +{ + { + // The returned pointer is ax + 5. + char *p = stpncpy (ax, a7, 5); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + { + //The returned pointer is in [ax, ax + 7] even though n is not known. + char *p = stpncpy (ax, a7, n); + x = p[-8]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-7], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); + } + + + { + // The returned pointer is in [a5, a5 + 3]. + char *p = stpncpy (a5, a7, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is a5 + 4. + char *p = stpncpy (a5, a7, 4); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is in [a5, a5 + 5]. + char *p = stpncpy (a5, a7, n); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (n3_9 < 3 || 9 < n3_9) + n3_9 = 3; + + // The returned pointer is in [a5, a5 + 5]. + char *p = stpncpy (a5, a7, n3_9); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = stpncpy (a5, a7, 4); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; + + if (i > -5) i = -5; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} + + +void test_stpncpy_from_a5_to_allocated (int i, int n, int n5_7, int n3_9) +{ + if (n5_7 < 5 || 7 < n5_7) + n5_7 = 5; + + { + char *d = calloc (n5_7, 1); + char *p = stpncpy (d, s, n); + x = p[-8]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-7], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *d = calloc (n5_7, 1); + char *p = stpncpy (d, a3, n); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *d = calloc (n5_7, 1); + char *p = stpncpy (d, a5, n); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *d = calloc (n5_7, 1); + char *p = stpncpy (d, a9, n); + x = p[-8]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-7], p[-6], p[-5], p[-3], p[-4], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *d = calloc (n5_7, 1); + char *p = stpncpy (d, a3, n3_9); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *d = calloc (n5_7, 1); + char *p = stpncpy (d, a9, n3_9); + x = p[-8]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-7], p[-6], p[-5], p[-4], p[-4], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-82.c b/gcc/testsuite/gcc.dg/Warray-bounds-82.c new file mode 100644 index 0000000..b5dd919 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-82.c @@ -0,0 +1,258 @@ +/* PR tree-optimization/101397 - spurious warning writing to the result + of stpcpy minus 1 + Verify warnings for indexing into a pointer returned from mempcpy. + The call mempcpy(S1, S2, N) returns &S1[N]. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +void* mempcpy (void*, const void*, size_t); + +extern char ax[], a3[3], a5[5], a7[7], *s; + +volatile int x; + +/* Verify warnings for indexing into the result of mempcpy with a source + pointing to an array of unknown bound. */ + +void test_mempcpy_from_ptr (int i) +{ + { + char *p = mempcpy (ax, s, 5); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + { + char *p = mempcpy (a5, s, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; + x = p[ 1]; + x = p[ 2]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = mempcpy (a5, s, 4); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-4]; + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; + x = p[ 1]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = mempcpy (a5, s, 4); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; + + if (i > -5) i = -5; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} + +/* Verify warnings for indexing into the result of mempcpy with a source + an array of size 5. */ + +void test_mempcpy_from_a5 (int i, int n, int n3_9) +{ + { + // The returned pointer is ax + 3 as specified by the bound. + char *p = mempcpy (ax, a5, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-3]; + x = p[-2]; + x = p[ 0]; + x = p[ 1]; + x = p[ 2]; + } + + { + // The returned pointer is ax + 5. + char *p = mempcpy (ax, a5, 5); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + { + //The returned pointer is in [ax, ax + 5] even though n is not known. + char *p = mempcpy (ax, a5, n); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + + { + // The returned pointer is a3 + 3. + char *p = mempcpy (a3, a5, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-3]; + x = p[-1]; + x = p[ 0]; // { dg-warning "\\\[-Warray-bounds" } + x = p[ 1]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is in [a3, a3 + 3]. + char *p = mempcpy (a3, a5, n); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; + x = p[ 2]; + x = p[ 3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (n3_9 < 3 || 9 < n3_9) + n3_9 = 3; + + // The returned pointer is a3. + char *p = mempcpy (a3, a5, n3_9); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = mempcpy (a3, a5, 3); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} + + +/* Verify warnings for indexing into the result of mempcpy with a source + an array of size 7. */ + +void test_mempcpy_from_a7 (int i, int n, int n3_9) +{ + { + // The returned pointer is ax + 5. + char *p = mempcpy (ax, a7, 5); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + { + //The returned pointer is in [ax, ax + 7] even though n is not known. + char *p = mempcpy (ax, a7, n); + x = p[-8]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-7]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + + { + // The returned pointer is a5 + 3 as specified by the bound. + char *p = mempcpy (a5, a7, 3); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-3]; + x = p[-2]; + x = p[ 0]; + x = p[ 1]; + x = p[ 2]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is a5 + 4. + char *p = mempcpy (a5, a7, 4); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-4]; + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; + x = p[ 1]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is in [a5, a5 + 5]. + char *p = mempcpy (a5, a7, n); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; + x = p[ 4]; + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (n3_9 < 3 || 9 < n3_9) + n3_9 = 3; + + // The returned pointer is in [a5 + 3, a5 + 5]. + char *p = mempcpy (a5, a7, n3_9); + x = p[-6]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-5]; + x = p[-3]; + x = p[-2]; + x = p[-1]; + x = p[ 0]; + x = p[ 1]; + x = p[ 2]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = mempcpy (a5, a7, 4); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; + + if (i > -5) i = -5; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-83.c b/gcc/testsuite/gcc.dg/Warray-bounds-83.c new file mode 100644 index 0000000..b1d02ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-83.c @@ -0,0 +1,172 @@ +/* PR tree-optimization/101397 - spurious warning writing to the result + of stpcpy minus 1 + Verify warnings for indexing into a pointer returned from stpncpy. + The call stpncpy(S1, S2, N) returns the address of the copy of + the first NUL is it exists or &S1[N] otherwise. + { dg-do compile } + { dg-options "-O2 -Wall -Wno-stringop-truncation" } */ + +typedef __SIZE_TYPE__ size_t; + +__attribute__ ((alloc_size (1))) const void* alloc (size_t); + +void* memchr (const void*, int, size_t); + +void sink (int, ...); + +extern char ax[], a3[3], a5[5], a7[7], a9[9]; + +volatile int x; + +/* Verify warnings for indexing into the result of memchr. */ + +void test_memchr (int i, int n, int n3_5, int n3_9) +{ + { + /* Because memchr never returns a past-the-end pointer the result + below is in [ax, ax + 4]. */ + const char *p = memchr (ax, x, 5); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + x = p[-4]; + x = p[-1]; + x = p[ 0]; + x = p[ 9]; + } + + { + // The returned pointer is in [ax, ax + n]. + const char *p = memchr (ax, x, n); + sink (p[-99], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[99]); + } + + + { + // The returned pointer is in [a5, a5 + 2]. + const char *p = memchr (a5, x, 3); + x = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is a5 + 4. + const char *p = memchr (a5, x, 4); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + // The returned pointer is in [a5, a5 + 4]. + const char *p = memchr (a5, x, n); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (n3_5 < 3 || 5 < n3_5) + n3_5 = 3; + + // The returned pointer is in [a7, a7 + 4]. + const char *p = memchr (a7, x, n3_5); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + if (n3_9 < 3 || 9 < n3_9) + n3_9 = 3; + + // The returned pointer is in [a5, a5 + 4]. + const char *p = memchr (a5, x, n3_9); + x = p[-5]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *p = memchr (a5, x, 4); + + if (i > -1) i = -1; + x = p[i]; + + if (i > -2) i = -2; + x = p[i]; + + if (i > -3) i = -3; + x = p[i]; + + if (i > -4) i = -4; + x = p[i]; // { dg-warning "\\\[-Warray-bounds" } + } +} + + +void test_memchr_in_allocated (int i, int n, int n5_7, int n3_9) +{ + if (n5_7 < 5 || 7 < n5_7) + n5_7 = 5; + + { + const char *s = alloc (n5_7); + const char *p = memchr (s, x, n); + x = p[-7]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-6], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *s = alloc (n5_7); + const char *p = memchr (s, x, n); + x = p[-7]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *s = alloc (n5_7); + const char *p = memchr (s, x, n); + x = p[-7]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *s = alloc (n5_7); + const char *p = memchr (s, x, n); + x = p[-7]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-6], p[-5], p[-3], p[-4], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *s = alloc (n5_7); + const char *p = memchr (s, x, n3_9); + x = p[-7]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + const char *s = alloc (n5_7); + const char *p = memchr (s, x, n3_9); + x = p[-7]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-6], p[-5], p[-4], p[-4], p[-2], p[-1], p[0]); + sink (p[1], p[2], p[3], p[4], p[5], p[6]); + x = p[7]; // { dg-warning "\\\[-Warray-bounds" } + } + +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-84.c b/gcc/testsuite/gcc.dg/Warray-bounds-84.c new file mode 100644 index 0000000..b9350d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-84.c @@ -0,0 +1,65 @@ +/* PR tree-optimization/101397 - spurious warning writing to the result + of stpcpy minus 1 + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +char* strcpy (char*, const char*); + +void sink (int, ...); + +extern char ax[], a3[3], a5[5], *s; + +volatile int x; + +void test_strcpy (int i) +{ + { + char *p = strcpy (ax, s); + x = p[-1]; // { dg-warning "\\\[-Warray-bounds" } + x = p[ 0]; + x = p[+9]; + } + + { + char *p = strcpy (a3, s); + x = p[-1]; // { dg-warning "\\\[-Warray-bounds" } + x = p[0]; + x = p[1]; + x = p[2]; + x = p[3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = strcpy (a5, s); + x = p[-1]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[0], p[1], p[2], p[3], p[4]); + x = p[ 5]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = strcpy (a5 + 1, s); + x = p[-2]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-1], p[0], p[1], p[2], p[3]); + x = p[4]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = strcpy (a5 + 2, s); + x = p[-3]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-2], p[-1], p[0], p[1], p[2]); + x = p[3]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = strcpy (a5 + 3, s); + x = p[-4]; // { dg-warning "\\\[-Warray-bounds" } + sink (p[-3], p[-2], p[-1], p[0], p[1]); + x = p[2]; // { dg-warning "\\\[-Warray-bounds" } + } + + { + char *p = strcpy (ax, a3); + p[-1] = 1; // { dg-warning "\\\[-Warray-bounds" } + sink (p[0], p[1], p[2], p[9], p[99]); + } +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c index b126fcb..042c967 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c @@ -79,9 +79,8 @@ void warn_memchr_var_memset_range (const void *s, unsigned n) as in the first two notes. The exact value probably isn't too important. */ char *p0 = malloc (UR (5, 7)); - // { dg-message ": destination object of size \\\[5, 7]" "note 1" { target *-*-* } .-1 } - // { dg-message "at offset \\\[1, 7] into destination object of size \\\[5, 7]" "note 2" { target *-*-* } .-2 } - // { dg-message "at offset \\\[2, 7] into destination object of size \\\[5, 7]" "note 3" { target *-*-* } .-3 } + // { dg-message "at offset \\\[\[01\], 6] into destination object of size \\\[5, 7]" "note 2" { target *-*-* } .-1 } + // { dg-message "at offset \\\[2, 7] into destination object of size \\\[5, 7]" "note 3" { target *-*-* } .-2 } sink (p0); char *p1 = memchr (p0, '1', n); -- cgit v1.1 From 62acc72a957b561462a436fcb2d6caac5b363190 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 21 Jul 2021 07:50:20 +0100 Subject: unroll: Avoid unnecessary tail loops for constant niters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit unroll and jam can decide to unroll the outer loop of a nest like: for (int j = 0; j < n; ++j) for (int i = 0; i < n; ++i) x[i] += __builtin_expf (y[j][i]); It then uses a tail loop to handle any left-over iterations. However, the code is structured so that this tail loop is always used. If n is a multiple of the unroll factor UF, the final UF iterations will use the tail loop rather than the unrolled loop. “Fixing†that for variable loop counts would mean introducing another runtime test: a branch around the tail loop if there are no more iterations. There's at least an argument that the overhead of doing that test might not pay for itself. But we use this structure even if the iteration count is provably a multiple of UF at compile time. E.g. with s/n/100/ and an unroll factor of 2, the first 98 iterations use the unrolled loop and the final 2 iterations use the original loop. This patch makes the unroller avoid a tail loop in that case. The end result seemed easier to follow if variables were declared at the point of initialisation, so that it's more obvious which ones are meaningful even when there's no tail loop. gcc/ * tree-ssa-loop-manip.c (determine_exit_conditions): Return a null exit condition if no tail loop is needed, and if the original exit condition should therefore be kept as-is. (tree_transform_and_unroll_loop): Handle that case here too. gcc/testsuite/ * gcc.dg/unroll-9.c: New test/ --- gcc/testsuite/gcc.dg/unroll-9.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/unroll-9.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/unroll-9.c b/gcc/testsuite/gcc.dg/unroll-9.c new file mode 100644 index 0000000..2d65ec3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/unroll-9.c @@ -0,0 +1,12 @@ +/* { dg-options "-O3 -fdump-tree-unrolljam -fno-math-errno" } */ + +void +f (float *restrict x, float y[100][100]) +{ + for (int j = 0; j < 100; ++j) + for (int i = 0; i < 100; ++i) + x[i] += __builtin_expf (y[j][i]); +} + +/* The loop should be unrolled 2 times, without a tail loop. */ +/* { dg-final { scan-tree-dump-times "__builtin_expf" 2 "unrolljam" } } */ -- cgit v1.1 From 957952ce64e067c56e58df5ee36bbb004eecffa1 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 21 Jul 2021 07:50:20 +0100 Subject: unroll: Run VN on unrolled-and-jammed loops Unroll and jam can sometimes leave redundancies. E.g. for: for (int j = 0; j < 100; ++j) for (int i = 0; i < 100; ++i) x[i] += y[i] * z[j][i]; the new loop will do the equivalent of: for (int j = 0; j < 100; j += 2) for (int i = 0; i < 100; ++i) { x[i] += y[i] * z[j][i]; x[i] += y[i] * z[j + 1][i]; } with two reads of y[i] and with a round trip through memory for x[i]. At the moment these redundancies survive till vectorisation, so if vectorisation succeeds, we're reliant on being able to remove the redundancies from the vector form. This can be hard to do if a vector loop uses predication. E.g. on SVE we end up with: .L3: ld1w z3.s, p0/z, [x3, x0, lsl 2] ld1w z0.s, p0/z, [x5, x0, lsl 2] ld1w z1.s, p0/z, [x2, x0, lsl 2] mad z1.s, p1/m, z0.s, z3.s ld1w z2.s, p0/z, [x4, x0, lsl 2] st1w z1.s, p0, [x3, x0, lsl 2] // store to x[i] ld1w z1.s, p0/z, [x3, x0, lsl 2] // load back from x[i] mad z0.s, p1/m, z2.s, z1.s st1w z0.s, p0, [x3, x0, lsl 2] add x0, x0, x6 whilelo p0.s, w0, w1 b.any .L3 This patch runs a value-numbering pass on loops after a successful unroll-and-jam, which gets rid of the unnecessary load and gives a more accurate idea of vector costs. Unfortunately the redundant store still persists without a pre-vect DSE, but that feels like a separate issue. Note that the pass requires the loop to have a single exit, hence the simple calculation of exit_bbs. gcc/ * gimple-loop-jam.c: Include tree-ssa-sccvn.h. (tree_loop_unroll_and_jam): Run value-numbering on a loop that has been successfully unrolled. gcc/testsuite/ * gcc.dg/unroll-10.c: New test. --- gcc/testsuite/gcc.dg/unroll-10.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/unroll-10.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/unroll-10.c b/gcc/testsuite/gcc.dg/unroll-10.c new file mode 100644 index 0000000..0559915 --- /dev/null +++ b/gcc/testsuite/gcc.dg/unroll-10.c @@ -0,0 +1,13 @@ +/* { dg-options "-O3 -fdump-tree-unrolljam" } */ + +void +f (int *restrict x, int *restrict y, int z[restrict 100][100]) +{ + for (int j = 0; j < 100; ++j) + for (int i = 0; i < 100; ++i) + x[i] += y[i] * z[j][i]; +} + +/* The loop should be unrolled 2 times, leaving one load from x, + one load from y and 2 loads from z. */ +/* { dg-final { scan-tree-dump-times { = \(*\*} 4 "unrolljam" } } */ -- cgit v1.1 From e0a7a6752dad7848eb4b29b826a551c0992256ec Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 21 Jul 2021 17:24:08 -0400 Subject: analyzer: fix issues with phi handling The analyzer's state purging code was overzealously purging state for ssa names that might be used within phi nodes, leading to false positives from -Wanalyzer-use-of-uninitialized-value. This patch updates phi handling in the analyzer to fix these issues. gcc/analyzer/ChangeLog: * region-model.cc (region_model::handle_phi): Add "old_state" param and use it. (region_model::update_for_phis): Update so that all of the phi stmts are effectively handled simultaneously, rather than in order. * region-model.h (region_model::handle_phi): Add "old_state" param. * state-purge.cc (self_referential_phi_p): Replace with... (name_used_by_phis_p): ...this new function. (state_purge_per_ssa_name::process_point): Update to use the above, so that all phi stmts at a basic block are effectively considered simultaneously, and only consider the phi arguments for the pertinent in-edge. * supergraph.cc (cfg_superedge::get_phi_arg_idx): New. (cfg_superedge::get_phi_arg): Use the above. * supergraph.h (cfg_superedge::get_phi_arg_idx): New decl. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/explode-2.c: Remove xfail. * gcc.dg/analyzer/explode-2a.c: Remove expected leak warning on while stmt. * gcc.dg/analyzer/phi-2.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/explode-2.c | 2 +- gcc/testsuite/gcc.dg/analyzer/explode-2a.c | 2 +- gcc/testsuite/gcc.dg/analyzer/phi-2.c | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/phi-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2.c b/gcc/testsuite/gcc.dg/analyzer/explode-2.c index 3b987e1..c16982f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/explode-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/explode-2.c @@ -24,7 +24,7 @@ void test (void) p0 = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */ break; case 1: - free (p0); /* { dg-warning "double-'free' of 'p0'" "" { xfail *-*-* } } */ + free (p0); /* { dg-warning "double-'free' of 'p0'" } */ break; case 2: diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2a.c b/gcc/testsuite/gcc.dg/analyzer/explode-2a.c index f60354c..32c71ca 100644 --- a/gcc/testsuite/gcc.dg/analyzer/explode-2a.c +++ b/gcc/testsuite/gcc.dg/analyzer/explode-2a.c @@ -14,7 +14,7 @@ void test (void) explode-2.c as this code. */ int a = get (); int b = get (); - while (a) /* { dg-warning "leak" } */ + while (a) { switch (b) { diff --git a/gcc/testsuite/gcc.dg/analyzer/phi-2.c b/gcc/testsuite/gcc.dg/analyzer/phi-2.c new file mode 100644 index 0000000..2ab8344 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/phi-2.c @@ -0,0 +1,27 @@ +/* { dg-additional-options "-O1" } */ + +struct list_head { + struct list_head *next, *prev; +}; + +struct mbochs_dmabuf { + /* [...snip...] */ + struct dma_buf *buf; + /* [...snip...] */ + struct list_head next; + /* [...snip...] */ +}; + +void mbochs_close(struct list_head *dmabufs, + struct mbochs_dmabuf *dmabuf, + struct mbochs_dmabuf *tmp) +{ + /* [...snip...] */ + while (&dmabuf->next != dmabufs) + { + dmabuf = tmp; + tmp = ((struct mbochs_dmabuf *)((void *)(tmp->next.next) - __builtin_offsetof(struct mbochs_dmabuf, next))); + } + + /* [...snip...] */ +} -- cgit v1.1 From 893b12cc12877aca1c9df6272123b26eddf12722 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 21 Jul 2021 19:19:31 -0400 Subject: analyzer: bulletproof -Wanalyzer-file-leak [PR101547] gcc/analyzer/ChangeLog: PR analyzer/101547 * sm-file.cc (file_leak::emit): Handle m_arg being NULL. (file_leak::describe_final_event): Handle ev.m_expr being NULL. gcc/testsuite/ChangeLog: PR analyzer/101547 * gcc.dg/analyzer/pr101547.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/pr101547.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101547.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101547.c b/gcc/testsuite/gcc.dg/analyzer/pr101547.c new file mode 100644 index 0000000..8791cff --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101547.c @@ -0,0 +1,11 @@ +char * +fopen (const char *restrict, const char *restrict); + +void +k2 (void) +{ + char *setfiles[1]; + int i; + + setfiles[i] = fopen ("", ""); /* { dg-warning "use of uninitialized value 'i'" } */ +} /* { dg-warning "leak of FILE" } */ -- cgit v1.1 From e58093276a6e319c2a6d9f02e343fbf8400dab60 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 19 Jul 2021 14:02:57 -0400 Subject: Only call vrp_visit_cond_stmt if range_of_stmt doesn't resolve to a const. Eevntually all functionality will be subsumed. Until then, call it only if needed. gcc/ PR tree-optimization/101496 * vr-values.c (simplify_using_ranges::fold_cond): Call range_of_stmt first, then vrp_visit_cond_Stmt. gcc/testsuite * gcc.dg/pr101496.c: New. --- gcc/testsuite/gcc.dg/pr101496.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101496.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101496.c b/gcc/testsuite/gcc.dg/pr101496.c new file mode 100644 index 0000000..091d4ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101496.c @@ -0,0 +1,22 @@ +/* PR tree-optimization/101496 */ +/* { dg-do compile } */ +/* { dg-options "-O2 " } */ + +int c_1, li_2, us_3, func_14_s_5; + +void func_14() { + { + unsigned uli_8 = 0; + lbl1806324B: + if (uli_8 /= us_3 |= func_14_s_5 < 0 | func_14_s_5 != c_1) { + uli_8 += c_1 >= us_3; + if (uli_8) + ; + else + li_2 &&func_14_s_5 <= c_1 ?: 0; + unsigned *ptr_9 = &uli_8; + } + } + goto lbl1806324B; +} + -- cgit v1.1 From ea789238b2c24eedf70b56257235adf3d33c5a0a Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 19 Jul 2021 15:16:25 -0400 Subject: Check for undefined on COND_EXPR before querying type. gcc/ PR tree-optimization/101497 * gimple-range-fold.cc (fold_using_range::range_of_cond_expr): Check for undefined. gcc/testsuite * gcc.dg/pr101497.c: New. --- gcc/testsuite/gcc.dg/pr101497.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101497.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101497.c b/gcc/testsuite/gcc.dg/pr101497.c new file mode 100644 index 0000000..fcfe059 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101497.c @@ -0,0 +1,13 @@ +/* PR tree-optimization/101497 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wno-div-by-zero" } */ + +char uc_1; +int i_4, func_12_uli_6; +void func_12() { + int *ptr_8 = &func_12_uli_6; + *ptr_8 = 0 >= 211 - uc_1 <= 0; + i_4 %= 0; + i_4 *= *ptr_8; +} + -- cgit v1.1 From b362d7947b37059fdb6de62145fa5146258dd58f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 22 Jul 2021 11:49:33 -0600 Subject: Add new test for PR65178. gcc/testsuite/ChangeLog: PR tree-optimization/65178 * gcc.dg/uninit-pr65178.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr65178.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr65178.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr65178.c b/gcc/testsuite/gcc.dg/uninit-pr65178.c new file mode 100644 index 0000000..21eb354 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr65178.c @@ -0,0 +1,21 @@ +/* PR tree-optimizatiom/65178 - incorrect -Wmaybe-uninitialized when using + nested loops + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void *bar (int); + +char *foo (void) +{ + char *c = "bla"; + char *buf; + for (int a = 1;; a = 0) + { + for (char *s = c; *s; ++s) + { + } + if (!a) break; + buf = (char *) bar (1); + } + return buf; // { dg-bogus "\\\[-Wmaybe-uninitialized" } +} -- cgit v1.1 From 60933a148ab33c82915b40690b3ced6abc32a1bf Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 22 Jul 2021 22:36:05 -0400 Subject: analyzer: fix feasibility false +ve with overly complex svalues gcc/analyzer/ChangeLog: * diagnostic-manager.cc (class auto_disable_complexity_checks): New. (epath_finder::explore_feasible_paths): Use it to disable complexity checks whilst processing the worklist. * region-model-manager.cc (region_model_manager::region_model_manager): Initialize m_check_complexity. (region_model_manager::reject_if_too_complex): Bail if m_check_complexity is false. * region-model.h (region_model_manager::enable_complexity_check): New. (region_model_manager::disable_complexity_check): New. (region_model_manager::m_check_complexity): New. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/feasibility-3.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/feasibility-3.c | 133 ++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/feasibility-3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c new file mode 100644 index 0000000..0c0bd14 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c @@ -0,0 +1,133 @@ +/* Reduced and adapted from Linux: fs/proc/inode.c: proc_reg_open + (GPL v2.0). */ + +/* Types. */ + +typedef unsigned char u8; +typedef _Bool bool; +typedef unsigned int gfp_t; + +struct file; +struct kmem_cache; +struct proc_dir_entry; + +struct inode { /* [...snip...] */ }; + +enum { + PROC_ENTRY_PERMANENT = 1U << 0, +}; + +struct proc_ops { + /* [...snip...] */ + int (*proc_open)(struct inode *, struct file *); + /* [...snip...] */ + int (*proc_release)(struct inode *, struct file *); + /* [...snip...] */ +}; + +struct proc_dir_entry { + /* [...snip...] */ + struct completion *pde_unload_completion; + /* [...snip...] */ + union { + const struct proc_ops *proc_ops; + const struct file_operations *proc_dir_ops; + }; + /* [...snip...] */ + u8 flags; + /* [...snip...] */ +}; + +struct pde_opener { + /* [...snip...] */ + struct file *file; + /* [...snip...] */ +}; + +struct proc_inode { + /* [...snip...] */ + struct proc_dir_entry *pde; + /* [...snip...] */ + struct inode vfs_inode; +}; + +/* Data. */ + +static struct kmem_cache *pde_opener_cache __attribute__((__section__(".data..ro_after_init"))); + +/* Functions. */ + +void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __attribute__((__malloc__)); +void kmem_cache_free(struct kmem_cache *, void *); + +static inline bool pde_is_permanent(const struct proc_dir_entry *pde) +{ + return pde->flags & PROC_ENTRY_PERMANENT; +} + +static inline struct proc_inode *PROC_I(const struct inode *inode) +{ + void *__mptr = (void *)(inode); + return ((struct proc_inode *)(__mptr - __builtin_offsetof(struct proc_inode, vfs_inode))); +} + +static inline struct proc_dir_entry *PDE(const struct inode *inode) +{ + return PROC_I(inode)->pde; +} + +/* We don't want to emit bogus use of uninitialized value 'pdeo' + warnings from -Wanalyzer-use-of-uninitialized-value in this function; + these would require following infeasible paths in which "release" is + first NULL (to avoid the initialization of "pdeo") and then is non-NULL + (to access "pdeo"). + + "release" is sufficiently complicated in this function to hit the + complexity limit for symbolic values during enode exploration. */ + +static int proc_reg_open(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *pde = PDE(inode); + int rv = 0; + typeof(((struct proc_ops*)0)->proc_open) open; + typeof(((struct proc_ops*)0)->proc_release) release; + struct pde_opener *pdeo; + + if (pde_is_permanent(pde)) { + open = pde->proc_ops->proc_open; + if (open) + rv = open(inode, file); + return rv; + } + + /* [...snip...] */ + + release = pde->proc_ops->proc_release; + if (release) { + pdeo = kmem_cache_alloc(pde_opener_cache, + ((( gfp_t)(0x400u|0x800u)) + | (( gfp_t)0x40u) + | (( gfp_t)0x80u))); + if (!pdeo) { + rv = -12; + goto out_unuse; + } + } + + open = pde->proc_ops->proc_open; + if (open) + rv = open(inode, file); + + if (release) { + if (rv == 0) { + + pdeo->file = file; /* { dg-bogus "uninit" } */ + /* [...snip...] */ + } else + kmem_cache_free(pde_opener_cache, pdeo); /* { dg-bogus "uninit" } */ + } + +out_unuse: + /* [...snip...] */ + return rv; +} -- cgit v1.1 From cf5f544227f16b63e224529190329eb0edca791c Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 26 Jul 2021 17:30:26 +0100 Subject: Fold bswap32(x) != 0 to x != 0 (and related transforms) This patch to match.pd implements several closely related folding simplifications at the tree-level, that make use of the property that bit permutation functions, rotate and bswap have inverses. [1] bswap(X) eq/ne C, for constant C, simplifies to X eq/ne C' where C'=bswap(C), generalizing the transform in the subject. [2] bswap(X) eq/ne bswap(Y) simplifies to X eq/ne Y. [3] lrotate(X,C1) eq/ne C2 simplifies to X eq/ne C3, where C3 = rrotate(C2,C1), i.e. apply the inverse rotation to C2. [4] Likewise, rrotate(X,C1) eq/ne C2 simplifies to X eq/ne C3, where C3 = lrotate(C2,C1). [5] rotate(X,Z) eq/ne rotate(Y,Z) simplifies to X eq/ne Y, when the bit-count Z (the same on both sides) has no side-effects. [6] rotate(X,Y) eq/ne 0 simplifies to X eq/ne 0 if Y has no side-effects. [7] Likewise, rotate(X,Y) eq/ne -1 simplifies to X eq/ne -1, if Y has no side-effects. 2010-07-26 Roger Sayle Marc Glisse gcc/ChangeLog * match.pd (rotate): Simplify equality/inequality of rotations. (bswap): Simplify equality/inequality tests of byte swapping. gcc/testsuite/ChangeLog * gcc.dg/fold-eqrotate-1.c: New test case. * gcc.dg/fold-eqbswap-1.c: New test case. --- gcc/testsuite/gcc.dg/fold-eqbswap-1.c | 113 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/fold-eqrotate-1.c | 46 ++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-eqbswap-1.c create mode 100644 gcc/testsuite/gcc.dg/fold-eqrotate-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/fold-eqbswap-1.c b/gcc/testsuite/gcc.dg/fold-eqbswap-1.c new file mode 100644 index 0000000..ed9820b --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-eqbswap-1.c @@ -0,0 +1,113 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int test1(int x, int y) +{ +#if __SIZEOF_INT__ == 4 + return __builtin_bswap32(x) == __builtin_bswap32(y); +#else + return x == y; +#endif +} + +int test2(int x, int y) +{ +#if __SIZEOF_INT__ == 4 + return __builtin_bswap32(x) != __builtin_bswap32(y); +#else + return x != y; +#endif +} + +int test3(int x) +{ +#if __SIZEOF_INT__ == 4 + return __builtin_bswap32(x) == 12345; +#else + return x; +#endif +} + +int test4(int x) +{ +#if __SIZEOF_INT__ == 4 + return __builtin_bswap32(x) != 12345; +#else + return x; +#endif +} + +int test1ll(long long x, long long y) +{ +#if __SIZEOF_LONG_LONG__ == 8 + return __builtin_bswap64(x) == __builtin_bswap64(y); +#else + return x == y; +#endif +} + +int test2ll(long long x, long long y) +{ +#if __SIZEOF_LONG_LONG__ == 8 + return __builtin_bswap64(x) != __builtin_bswap64(y); +#else + return x != y; +#endif +} + +int test3ll(long long x) +{ +#if __SIZEOF_LONG_LONG__ == 8 + return __builtin_bswap64(x) == 12345; +#else + return (int)x; +#endif +} + +int test4ll(long long x) +{ +#if __SIZEOF_LONG_LONG__ == 8 + return __builtin_bswap64(x) != 12345; +#else + return (int)x; +#endif +} + +int test1s(short x, short y) +{ +#if __SIZEOF_SHORT__ == 2 + return __builtin_bswap16(x) == __builtin_bswap16(y); +#else + return x == y; +#endif +} + +int test2s(short x, short y) +{ +#if __SIZEOF_SHORT__ == 2 + return __builtin_bswap16(x) != __builtin_bswap16(y); +#else + return x != y; +#endif +} + +int test3s(short x) +{ +#if __SIZEOF_SHORT__ == 2 + return __builtin_bswap16(x) == 12345; +#else + return (int)x; +#endif +} + +int test4s(short x) +{ +#if __SIZEOF_SHORT__ == 2 + return __builtin_bswap16(x) != 12345; +#else + return (int)x; +#endif +} + +/* { dg-final { scan-tree-dump-times "__builtin_bswap" 0 "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/fold-eqrotate-1.c b/gcc/testsuite/gcc.dg/fold-eqrotate-1.c new file mode 100644 index 0000000..7d2b637 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-eqrotate-1.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int test1(unsigned int x, unsigned int y) +{ +#if __SIZEOF_INT__ == 4 + unsigned int r1 = (x << 16) | (x >> 16); + unsigned int r2 = (y << 16) | (y >> 16); + return r1 == r2; +#else + return x == y; +#endif +} + +int test2(unsigned int x) +{ +#if __SIZEOF_INT__ == 4 + unsigned int r1 = (x << 16) | (x >> 16); + return r1 == 12345; +#else + return x == 12345; +#endif +} + +int test3(unsigned int x) +{ +#if __SIZEOF_INT__ == 4 + unsigned int r1 = (x << 16) | (x >> 16); + return r1 == 0; +#else + return x == 0; +#endif +} + +int test4(unsigned int x) +{ +#if __SIZEOF_INT__ == 4 + unsigned int r1 = (x << 16) | (x >> 16); + return r1 == ~0; +#else + return x == ~0; +#endif +} + +/* { dg-final { scan-tree-dump-times "r>>" 0 "optimized" } } */ + -- cgit v1.1 From 1ce0b26e6e1e6c348b1d54f1f462a44df6fe47f5 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 26 Jul 2021 09:40:32 -0400 Subject: Adjust ranges for to_upper and to_lower. Exclude lower case chars from to_upper and upper case chars from to_lower. gcc/ PR tree-optimization/78888 * gimple-range-fold.cc (fold_using_range::range_of_builtin_call): Add cases for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER. gcc/testsuite/ * gcc.dg/pr78888.c: New. --- gcc/testsuite/gcc.dg/pr78888.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr78888.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr78888.c b/gcc/testsuite/gcc.dg/pr78888.c new file mode 100644 index 0000000..77a130c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr78888.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/78888 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +void kill (void); +void keep (void); + +void g (int x) +{ + if (__builtin_toupper ((unsigned char)x) == 'a') + kill (); + if (__builtin_toupper ((unsigned char)x) == 'z') + kill (); + if (__builtin_tolower ((unsigned char)x) == 'A') + kill (); + if (__builtin_tolower ((unsigned char)x) == 'Z') + kill (); + + if (__builtin_toupper ((unsigned char)x) == 'A') + keep (); + if (__builtin_toupper ((unsigned char)x) == 'Z') + keep (); + if (__builtin_tolower ((unsigned char)x) == 'a') + keep (); + if (__builtin_tolower ((unsigned char)x) == 'z') + keep (); +} +/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */ +/* { dg-final { scan-tree-dump-times "keep" 4 "evrp"} } */ -- cgit v1.1 From 3a1d168e9e0e3e38adedf5df393e9f8c075fc755 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 26 Jul 2021 15:25:00 -0400 Subject: analyzer: fix uninit false +ve when returning structs This patch fixes some false positives from -Wanalyzer-use-of-uninitialized-value when returning structs from functions (seen on the Linux kernel). gcc/analyzer/ChangeLog: * region-model.cc (region_model::on_call_pre): Always set conjured LHS, not just for SSA names. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/sock-1.c: New test. * gcc.dg/analyzer/sock-2.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/sock-1.c | 112 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/sock-2.c | 20 ++++++ 2 files changed, 132 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/sock-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/sock-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/sock-1.c b/gcc/testsuite/gcc.dg/analyzer/sock-1.c new file mode 100644 index 0000000..0f3e822 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/sock-1.c @@ -0,0 +1,112 @@ +typedef unsigned int __u32; +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +typedef __u32 u32; +typedef __s64 s64; +typedef __u64 u64; +typedef long long __kernel_time64_t; +typedef _Bool bool; +typedef __s64 time64_t; +struct __kernel_timespec { + __kernel_time64_t tv_sec; + long long tv_nsec; +}; +struct timespec64 { + time64_t tv_sec; + long tv_nsec; +}; + +extern struct timespec64 ns_to_timespec64(const s64 nsec); +int put_timespec64(const struct timespec64 *ts, + struct __kernel_timespec *uts); + +/* [...snip...] */ + +extern int put_old_timespec32(const struct timespec64 *, void *); + +/* [...snip...] */ + +/* [...snip...] */ + +typedef s64 ktime_t; + +/* [...snip...] */ + +extern void ktime_get_real_ts64(struct timespec64 *tv); + +/* [...snip...] */ + +enum tk_offsets { + TK_OFFS_REAL, + TK_OFFS_BOOT, + TK_OFFS_TAI, + TK_OFFS_MAX, +}; + +extern ktime_t ktime_get(void); +extern ktime_t ktime_get_with_offset(enum tk_offsets offs); +extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs); +extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs); +extern ktime_t ktime_get_raw(void); +extern u32 ktime_get_resolution_ns(void); + + +static ktime_t ktime_get_real(void) +{ + return ktime_get_with_offset(TK_OFFS_REAL); +} + +/* [...snip...] */ + +struct socket { + /* [...snip...] */ + struct sock *sk; + /* [...snip...] */ +}; + +/* [...snip...] */ + +struct sock { + /* [...snip...] */ + ktime_t sk_stamp; + /* [...snip...] */ +}; + +/* [...snip...] */ + +static ktime_t sock_read_timestamp(struct sock *sk) +{ + return *(const volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp); +} + +static void sock_write_timestamp(struct sock *sk, ktime_t kt) +{ + *(volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp) = kt; +} + +/* [...snip...] */ + +int sock_gettstamp(struct socket *sock, void *userstamp, + bool timeval, bool time32) +{ + struct sock *sk = sock->sk; + struct timespec64 ts; + + /* [...snip...] */ + ts = ns_to_timespec64((sock_read_timestamp(sk))); + if (ts.tv_sec == -1) + return -2; + if (ts.tv_sec == 0) { + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); + ts = ns_to_timespec64((kt)); + } + + if (timeval) + ts.tv_nsec /= 1000; + + + if (time32) + return put_old_timespec32(&ts, userstamp); + return put_timespec64(&ts, userstamp); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/sock-2.c b/gcc/testsuite/gcc.dg/analyzer/sock-2.c new file mode 100644 index 0000000..237e0cb --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/sock-2.c @@ -0,0 +1,20 @@ +__extension__ typedef __signed__ long long __s64; +typedef __s64 time64_t; +struct timespec64 { + time64_t tv_sec; + long tv_nsec; +}; + +extern struct timespec64 ns_to_timespec64(void); + +int sock_gettstamp() +{ + struct timespec64 ts; + + /* [...snip...] */ + ts = ns_to_timespec64(); + if (ts.tv_sec == -1) + return -2; + /* [...snip...] */ + return 0; +} -- cgit v1.1 From 13586172d0b70c9d7ca464fc5a2a46a8532b06d7 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Tue, 27 Jul 2021 10:02:38 +0200 Subject: ipa: Adjust references to identify read-only globals this patch has been motivated by SPEC 2017's 544.nab_r in which there is a static variable which is never written to and so zero throughout the run-time of the benchmark. However, it is passed by reference to a function in which it is read and (after some multiplications) passed into __builtin_exp which in turn unnecessarily consumes almost 10% of the total benchmark run-time. The situation is illustrated by the added testcase remref-3.c. The patch adds a flag to ipa-prop descriptor of each parameter to mark such parameters. IPA-CP and inling then take the effort to remove IPA_REF_ADDR references in the caller and only add IPA_REF_LOAD reference to the clone/overall inlined function. This is sufficient for subsequent symbol table analysis code to identify the read-only variable as such and optimize the code. There are two changes from the RFC version posted to the list earlier. First, three missing calls to get_base_address were added (there was another one in an assert). Second, references are not stripped off the callers if the cloned function cannot change the signature. The second change reveals a real shortcoming stemming from the fact we cannot adjust function prototypes with fnspecs. But that is a more general problem. gcc/ChangeLog: 2021-07-20 Martin Jambor * cgraph.h (ipa_replace_map): New field force_load_ref. * ipa-prop.h (ipa_param_descriptor): Reduce precision of move_cost, aded new flag load_dereferenced, adjusted comments. (ipa_get_param_dereferenced): New function. (ipa_set_param_dereferenced): Likewise. * cgraphclones.c (cgraph_node::create_virtual_clone): Follow it. * ipa-cp.c: Include gimple.h. (ipcp_discover_new_direct_edges): Take into account dereferenced flag. (get_replacement_map): New parameter force_load_ref, set the appropriate flag in ipa_replace_map if set. (struct symbol_and_index_together): New type. (adjust_refs_in_act_callers): New function. (adjust_references_in_caller): Likewise. (create_specialized_node): When appropriate, call adjust_references_in_caller and force only load references. * ipa-prop.c (load_from_dereferenced_name): New function. (ipa_analyze_controlled_uses): Also detect loads from a dereference, harden testing of call statements. (ipa_write_node_info): Stream the dereferenced flag. (ipa_read_node_info): Likewise. (ipa_set_jf_constant): Also create refdesc when jump function references a variable. (cgraph_node_for_jfunc): Rename to symtab_node_for_jfunc, work also on references of variables and return a symtab_node. Adjust all callers. (propagate_controlled_uses): Also remove references to VAR_DECLs. gcc/testsuite/ChangeLog: 2021-06-29 Martin Jambor * gcc.dg/ipa/remref-3.c: New test. * gcc.dg/ipa/remref-4.c: Likewise. * gcc.dg/ipa/remref-5.c: Likewise. * gcc.dg/ipa/remref-6.c: Likewise. --- gcc/testsuite/gcc.dg/ipa/remref-3.c | 23 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/remref-4.c | 31 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/remref-5.c | 38 +++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/remref-6.c | 24 +++++++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/ipa/remref-3.c create mode 100644 gcc/testsuite/gcc.dg/ipa/remref-4.c create mode 100644 gcc/testsuite/gcc.dg/ipa/remref-5.c create mode 100644 gcc/testsuite/gcc.dg/ipa/remref-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/remref-3.c b/gcc/testsuite/gcc.dg/ipa/remref-3.c new file mode 100644 index 0000000..8a82ca6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/remref-3.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-early-inlining -fdump-ipa-cp-details -fdump-tree-optimized" } */ + +static double global = 0.0; + +double foo_temp5; + +static void foo(double *ptr) { + static double abcd; + double v, exp_res; + v = *ptr; + exp_res = __builtin_exp(v); + foo_temp5 = exp_res * abcd; + abcd += foo_temp5; +} + +void entry() +{ + foo(&global); +} + +/* { dg-final { scan-ipa-dump "Removed a reference" "cp" } } */ +/* { dg-final { scan-tree-dump-not "builtin_exp" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/remref-4.c b/gcc/testsuite/gcc.dg/ipa/remref-4.c new file mode 100644 index 0000000..5a55437 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/remref-4.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-early-inlining -fdump-ipa-cp-details -fdump-tree-optimized" } */ + +static double global = 0.0; +double foo_temp5; + +static void foo(double *ptr) { + static double abcd; + double v, exp_res; + v = *ptr; + exp_res = __builtin_exp(v); + foo_temp5 = exp_res * abcd; + abcd += foo_temp5; +} + +double last_value; + +static void bar(double *ptr) +{ + last_value = *ptr; + foo (ptr); +} + +void entry() +{ + bar (&global); +} + +/* { dg-final { scan-ipa-dump "Removed a reference" "cp" } } */ +/* { dg-final { scan-ipa-dump "replaced it with LOAD" "cp" } } */ +/* { dg-final { scan-tree-dump-not "builtin_exp" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/remref-5.c b/gcc/testsuite/gcc.dg/ipa/remref-5.c new file mode 100644 index 0000000..c520e34 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/remref-5.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-cp-details -fdump-tree-optimized" } */ + +static double global = 0.0; +double foo_temp5; + +static void foo(double *ptr) { + static double abcd; + double v, exp_res; + v = *ptr; + exp_res = __builtin_exp(v); + foo_temp5 = exp_res * abcd; + abcd += foo_temp5; +} + +double last_value; + +static void bar(double *ptr) +{ + last_value = *ptr; + for (unsigned i = 0; i < 200; i++) + foo (ptr); +} + +void entry() +{ + bar (&global); +} + +void decoy(double *ptr) +{ + bar (ptr); +} + + +/* { dg-final { scan-ipa-dump "Removed a reference" "cp" } } */ +/* { dg-final { scan-ipa-dump "replaced it with LOAD" "cp" } } */ +/* { dg-final { scan-tree-dump-times "builtin_exp" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/remref-6.c b/gcc/testsuite/gcc.dg/ipa/remref-6.c new file mode 100644 index 0000000..de36493 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/remref-6.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-early-inlining -fno-ipa-cp -fdump-tree-optimized" } */ + +static double global = 0.0; + +double foo_temp5; + +static void foo(double *ptr) { + static double abcd; + double v, exp_res; + v = *ptr; + exp_res = __builtin_exp(v); + foo_temp5 = exp_res * abcd; + abcd += foo_temp5; +} + +void entry() +{ + foo(&global); +} + +/* { dg-final { scan-ipa-dump "Removed a reference" "inline" } } */ +/* { dg-final { scan-ipa-dump "replaced it with LOAD" "inline" } } */ +/* { dg-final { scan-tree-dump-not "builtin_exp" "optimized" } } */ -- cgit v1.1 From 66030d68a7edfc9504a50469598e0707b8f787ce Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 22 Jul 2021 12:26:16 +0200 Subject: tree-optimization/101573 - improve uninit warning at -O0 We can improve uninit warnings from the early pass by looking at PHI arguments on fallthru edges that are uninitialized and have uses that are before a possible loop exit. This catches some cases earlier that we'd only warn in a more confusing way after early inlining as seen by testcase adjustments. It introduces FAIL: gcc.dg/uninit-23.c (test for excess errors) where we additionally warn gcc.dg/uninit-23.c:21:13: warning: 't4' is used uninitialized [-Wuninitialized] which I think is OK even if it's not obvious that the new warning is an improvement when you look at the obvious source. Somehow for all cases I never get the `'foo' was declared here` notes, I didn't dig why that happens but it's odd. 2021-07-22 Richard Biener PR tree-optimization/101573 * tree-ssa-uninit.c (warn_uninit_phi_uses): New function looking at uninitialized PHI arg defs in some constrained cases. (warn_uninitialized_vars): Call it. (execute_early_warn_uninitialized): Calculate dominators. * gcc.dg/uninit-pr101573.c: New testcase. * gcc.dg/uninit-15-O0.c: Adjust. * gcc.dg/uninit-15.c: Likewise. * gcc.dg/uninit-23.c: Likewise. * c-c++-common/uninit-17.c: Likewise. --- gcc/testsuite/gcc.dg/uninit-15-O0.c | 2 +- gcc/testsuite/gcc.dg/uninit-15.c | 10 +++++----- gcc/testsuite/gcc.dg/uninit-23.c | 2 +- gcc/testsuite/gcc.dg/uninit-pr101573.c | 10 ++++++++++ 4 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr101573.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-15-O0.c b/gcc/testsuite/gcc.dg/uninit-15-O0.c index a3fd2b63..36d9634 100644 --- a/gcc/testsuite/gcc.dg/uninit-15-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-15-O0.c @@ -15,6 +15,6 @@ void baz(); void bar() { int j; /* { dg-message "was declared here" {} { xfail *-*-* } } */ - for (; foo(j); ++j) + for (; foo(j); ++j) /* { dg-warning "is used uninitialized" } */ baz(); } diff --git a/gcc/testsuite/gcc.dg/uninit-15.c b/gcc/testsuite/gcc.dg/uninit-15.c index 8ee10c2..85cb116 100644 --- a/gcc/testsuite/gcc.dg/uninit-15.c +++ b/gcc/testsuite/gcc.dg/uninit-15.c @@ -1,7 +1,7 @@ /* PR tree-optimization/17506 - We issue an uninitialized variable warning at a wrong location at + We used to issue an uninitialized variable warning at a wrong location at line 11, which is very confusing. Make sure we print out a note to - make it less confusing. (not xfailed alternative) + make it less confusing. (xfailed alternative) But it is of course ok if we warn in bar about uninitialized use of j. (not xfailed alternative) */ /* { dg-do compile } */ @@ -10,7 +10,7 @@ inline int foo (int i) { - if (i) /* { dg-warning "used uninitialized" } */ + if (i) /* { dg-warning "used uninitialized" "" { xfail *-*-* } } */ return 1; return 0; } @@ -20,7 +20,7 @@ void baz (void); void bar (void) { - int j; /* { dg-message "note: 'j' was declared here" "" } */ - for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" "" { xfail *-*-* } } */ + int j; /* { dg-message "note: 'j' was declared here" "" { xfail *-*-* } } */ + for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" } */ baz (); } diff --git a/gcc/testsuite/gcc.dg/uninit-23.c b/gcc/testsuite/gcc.dg/uninit-23.c index d64eb7d..87b4e98 100644 --- a/gcc/testsuite/gcc.dg/uninit-23.c +++ b/gcc/testsuite/gcc.dg/uninit-23.c @@ -18,7 +18,7 @@ ql (void) int *t4 = go; /* { dg-warning "is used uninitialized" } */ l1: - *t4 = (*t4 != 0) ? 0 : 2; + *t4 = (*t4 != 0) ? 0 : 2; /* { dg-warning "is used uninitialized" } */ } if (ij != 0) diff --git a/gcc/testsuite/gcc.dg/uninit-pr101573.c b/gcc/testsuite/gcc.dg/uninit-pr101573.c new file mode 100644 index 0000000..a574844 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr101573.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wuninitialized" } */ + +int main(int argc, char **argv) +{ + int a; + for(; a < 5; ++a) /* { dg-warning "is used uninitialized" } */ + ; + return 0; +} -- cgit v1.1 From a0f9a5dcc3bbe6c7de499e17d201d0f2cb512649 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 27 Jul 2021 13:51:55 -0600 Subject: Use OEP_DECL_NAME when comparing VLA bounds [PR101585]. Resolves: PR c/101585 - Bad interaction of -fsanitize=undefined and -Wvla-parameters gcc/c-family: PR c/101585 * c-warn.c (warn_parm_ptrarray_mismatch): Use OEP_DECL_NAME. gcc/testsuite: PR c/101585 * gcc.dg/Wvla-parameter-13.c: New test. --- gcc/testsuite/gcc.dg/Wvla-parameter-13.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Wvla-parameter-13.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-13.c b/gcc/testsuite/gcc.dg/Wvla-parameter-13.c new file mode 100644 index 0000000..f64d29c --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-parameter-13.c @@ -0,0 +1,18 @@ +/* PR c/101585 - Bad interaction of -fsanitize=undefined and -Wvla-parameters + { dg-do compile } + { dg-options "-Wall -fsanitize=undefined" } */ + +void f1 (int n, int (*)[n]); +void f1 (int n, int (*)[n]); // { dg-bogus "\\\[-Wvla-parameter" } + +void g1 (int m, int (*)[m]); +void g1 (int n, int (*)[n]); // { dg-bogus "\\\[-Wvla-parameter" "pr101605" { xfail *-*-* } } + +void h1 (int n, int (*)[n]); +void h1 (int n, int (*)[n + 1]); // { dg-warning "\\\[-Wvla-parameter" } + +void f2 (int m, int n, int (*)[m][n]); +void f2 (int n, int m, int (*)[n][m]); // { dg-bogus "\\\[-Wvla-parameter" "pr101605" { xfail *-*-* } } + +void g2 (int m, int n, int (*)[m][n]); +void g2 (int n, int m, int (*)[m][n]); // { dg-warning "\\\[-Wvla-parameter" "pr101605" { xfail *-*-* } } -- cgit v1.1 From 6aacd901b800ee8a2a03123669b299a08aad0504 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 27 Jul 2021 16:02:54 -0600 Subject: Let -Wuninitialized assume built-ins don't change const arguments [PR101584]. PR tree-optimization/101584 - missing -Wuninitialized with an allocated object after a built-in call gcc/ChangeLog: PR tree-optimization/101584 * tree-ssa-uninit.c (builtin_call_nomodifying_p): New function. (check_defs): Call it. gcc/testsuite/ChangeLog: PR tree-optimization/101584 * gcc.dg/uninit-38.c: Remove assertions. * gcc.dg/uninit-41.c: New test. --- gcc/testsuite/gcc.dg/uninit-38.c | 39 +------------ gcc/testsuite/gcc.dg/uninit-41.c | 121 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 37 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/uninit-41.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-38.c b/gcc/testsuite/gcc.dg/uninit-38.c index 8dacc8c..0d70bcd 100644 --- a/gcc/testsuite/gcc.dg/uninit-38.c +++ b/gcc/testsuite/gcc.dg/uninit-38.c @@ -1,5 +1,5 @@ -/* Verify that dereferencing uninitialized allocated objects and VLAs - correctly reflects offsets into the objects. +/* Verify that dereferencing uninitialized VLAs correctly reflects + offsets into the objects. The test's main purpose is to exercise the formatting of MEM_REFs. If -Wuninitialized gets smarter and detects uninitialized accesses before they're turned into MEM_REFs the test will likely need to @@ -18,41 +18,6 @@ extern void* malloc (size_t); void sink (void*, ...); -#undef T -#define T(Type, idx, off) \ - __attribute__ ((noipa)) \ - void UNIQ (test_)(int n) \ - { \ - void *p = malloc (n); \ - Type *q = (Type*)((char*)p + off); \ - sink (p, q[idx]); \ - } \ - typedef void dummy_type - -T (int, 0, 0); // { dg-warning "'\\*\\(int \\*\\)p' is used uninitialized" } -T (int, 0, 1); // { dg-warning "'\\*\\(int \\*\\)\\(\\(char \\*\\)p \\+ 1\\)'" } -T (int, 0, 2); // { dg-warning "'\\*\\(int \\*\\)\\(\\(char \\*\\)p \\+ 2\\)'" } -T (int, 0, 3); // { dg-warning "'\\*\\(int \\*\\)\\(\\(char \\*\\)p \\+ 3\\)'" } -T (int, 0, 4); // { dg-warning "'\\(\\(int \\*\\)p\\)\\\[1]'" } -T (int, 0, 5); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 1\\)\\)\\\[1]'" } -T (int, 0, 6); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 2\\)\\)\\\[1]'" } -T (int, 0, 7); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 3\\)\\)\\\[1]'" } -T (int, 0, 8); // { dg-warning "'\\(\\(int \\*\\)p\\)\\\[2]'" } -T (int, 0, 9); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 1\\)\\)\\\[2]'" } - - -T (int, 1, 0); // { dg-warning "'\\(\\(int \\*\\)p\\)\\\[1]' is used uninitialized" } -T (int, 1, 1); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 1\\)\\)\\\[1]'" } -T (int, 1, 2); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 2\\)\\)\\\[1]'" } -T (int, 1, 3); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 3\\)\\)\\\[1]'" } -T (int, 1, 4); // { dg-warning "'\\(\\(int \\*\\)p\\)\\\[2]'" } -T (int, 1, 5); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 1\\)\\)\\\[2]'" } -T (int, 1, 6); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 2\\)\\)\\\[2]'" } -T (int, 1, 7); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 3\\)\\)\\\[2]'" } -T (int, 1, 8); // { dg-warning "'\\(\\(int \\*\\)p\\)\\\[3]'" } -T (int, 1, 9); // { dg-warning "'\\(\\(int \\*\\)\\(\\(char \\*\\)p \\+ 1\\)\\)\\\[3]'" } - -#undef T #define T(Type, idx, off) \ __attribute__ ((noipa)) \ void UNIQ (test_)(int n) \ diff --git a/gcc/testsuite/gcc.dg/uninit-41.c b/gcc/testsuite/gcc.dg/uninit-41.c new file mode 100644 index 0000000..b485611 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-41.c @@ -0,0 +1,121 @@ +/* Verify that calls to non-modifying built-ins aren't considered + potentially modifying. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +void* alloca (size_t); +void* calloc (size_t, size_t); +void* malloc (size_t); +int printf (const char *, ...); +int scanf (const char *, ...); +int sprintf (char *, const char *, ...); +int snprintf (char *, size_t, const char *, ...); +int puts (const char *); +char* strcpy (char*, const char*); +size_t strlen (const char*); + +void noproto (); + +void sink (int, ...); + +extern char a[]; + +void nowarn_noproto (const char *fmt) +{ + int i; + noproto (&i); + sink (i); +} + +void nowarn_scanf (const char *fmt) +{ + int i; + scanf ("%i", &i); + sink (i); +} + +void test_puts_sprintf_alloca (const char *fmt) +{ + char *p; + { + p = alloca (8); + sprintf (a, fmt, p); // fmt might contain %n + puts (p); + } + + { + p = alloca (8); + snprintf (0, 0, fmt, p); // same as above + puts (p); + } +} + +void test_puts_alloca (const char *s) +{ + char *p = alloca (8); + + { + char a[] = "foo"; + puts (a); + } + + puts (p); // { dg-warning "-Wuninitialized" } + + { + p = alloca (strlen (s) + 1); + strcpy (p, s); + puts (p); + } + + { + /* Verify that the puts() calls above isn't considered to have + potentially modified *P, and same for the one below. */ + p = alloca (strlen (s)); + puts (p); // { dg-warning "-Wuninitialized" } + puts (p + 1); // { dg-warning "-Wuninitialized" } + } +} + + +void test_puts_malloc (const char *s, const char *t) +{ + char *p; + + { + p = malloc (strlen (s) + 1); + strcpy (p, s); + puts (p); + } + + { + p = malloc (strlen (t)); + puts (p); // { dg-warning "-Wuninitialized" } + } +} + + +void test_puts_vla (const char *s, const char *t) +{ + { + char a[strlen (s) + 1]; + strcpy (a, s); + puts (a); + } + + { + char b[strlen (t)]; + puts (b); // { dg-warning "-Wuninitialized" } + } +} + + +void test_printf_puts (const char *s) +{ + char *p = __builtin_malloc (1); + + printf ("%s", s); + + puts (p); // { dg-warning "-Wuninitialized" } +} -- cgit v1.1 From 8af0c50a29346f97a370f76bd881ccb4252b1e4d Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Wed, 28 Jul 2021 08:41:38 +0200 Subject: Correct a mistake in a warnung for -Wnonnull. In the warning for -Wnonnull when warning about array parameters with bounds > 0 and which are NULL the numbers referring to the two arguments are switched. This patch corrects the mistake. 2021-07-28 Martin Uecker gcc/ * calls.c (maybe_warn_rdwr_sizes): Correct argument numbers in warning that were switched. gcc/testsuite/ * gcc.dg/Wnonnull-4.c: Correct argument numbers in warnings. --- gcc/testsuite/gcc.dg/Wnonnull-4.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wnonnull-4.c b/gcc/testsuite/gcc.dg/Wnonnull-4.c index 180a40d..2c1c45a 100644 --- a/gcc/testsuite/gcc.dg/Wnonnull-4.c +++ b/gcc/testsuite/gcc.dg/Wnonnull-4.c @@ -27,9 +27,9 @@ void test_fca_n (int r_m1) T ( 0); // Verify positive bounds. - T ( 1); // { dg-warning "argument 1 of variable length array 'char\\\[n]' is null but the corresponding bound argument 2 value is 1" } - T ( 9); // { dg-warning "argument 1 of variable length array 'char\\\[n]' is null but the corresponding bound argument 2 value is 9" } - T (max); // { dg-warning "argument 1 of variable length array 'char\\\[n]' is null but the corresponding bound argument 2 value is \\d+" } + T ( 1); // { dg-warning "argument 2 of variable length array 'char\\\[n]' is null but the corresponding bound argument 1 value is 1" } + T ( 9); // { dg-warning "argument 2 of variable length array 'char\\\[n]' is null but the corresponding bound argument 1 value is 9" } + T (max); // { dg-warning "argument 2 of variable length array 'char\\\[n]' is null but the corresponding bound argument 1 value is \\d+" } } @@ -55,9 +55,9 @@ void test_fsa_x_n (int r_m1) T ( 0); // Verify positive bounds. - T ( 1); // { dg-warning "argument 1 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 2 value is 1" } - T ( 9); // { dg-warning "argument 1 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 2 value is 9" } - T (max); // { dg-warning "argument 1 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" } + T ( 1); // { dg-warning "argument 2 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 1 value is 1" } + T ( 9); // { dg-warning "argument 2 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 1 value is 9" } + T (max); // { dg-warning "argument 2 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 1 value is \\d+" } } @@ -83,9 +83,9 @@ void test_fia_1_n (int r_m1) T ( 0); // Verify positive bounds. - T ( 1); // { dg-warning "argument 1 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 2 value is 1" } - T ( 9); // { dg-warning "argument 1 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 2 value is 9" } - T (max); // { dg-warning "argument 1 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" } + T ( 1); // { dg-warning "argument 2 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 1 value is 1" } + T ( 9); // { dg-warning "argument 2 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 1 value is 9" } + T (max); // { dg-warning "argument 2 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 1 value is \\d+" } } @@ -111,9 +111,9 @@ void test_fla_3_n (int r_m1) T ( 0); // Verify positive bounds. - T ( 1); // { dg-warning "argument 1 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 2 value is 1" } - T ( 9); // { dg-warning "argument 1 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 2 value is 9" } - T (max); // { dg-warning "argument 1 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" } + T ( 1); // { dg-warning "argument 2 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 1 value is 1" } + T ( 9); // { dg-warning "argument 2 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 1 value is 9" } + T (max); // { dg-warning "argument 2 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 1 value is \\d+" } } @@ -139,9 +139,9 @@ void test_fda_n_5 (int r_m1) T ( 0); // Verify positive bounds. - T ( 1); // { dg-warning "argument 1 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 2 value is 1" } - T ( 9); // { dg-warning "argument 1 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 2 value is 9" } - T (max); // { dg-warning "argument 1 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 2 value is \\d+" } + T ( 1); // { dg-warning "argument 2 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 1 value is 1" } + T ( 9); // { dg-warning "argument 2 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 1 value is 9" } + T (max); // { dg-warning "argument 2 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 1 value is \\d+" } } @@ -167,7 +167,7 @@ void test_fca_n_n (int r_m1) T ( 0); // Verify positive bounds. - T ( 1); // { dg-warning "argument 1 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 2 value is 1" } - T ( 9); // { dg-warning "argument 1 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 2 value is 9" } - T (max); // { dg-warning "argument 1 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" } + T ( 1); // { dg-warning "argument 2 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 1 value is 1" } + T ( 9); // { dg-warning "argument 2 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 1 value is 9" } + T (max); // { dg-warning "argument 2 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 1 value is \\d+" } } -- cgit v1.1 From 84606efb0c6b1c1598d5ec6b05544e71596663b5 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 28 Jul 2021 10:33:46 +0530 Subject: analyzer: Recognize __builtin_free as a matching deallocator Recognize __builtin_free as being equivalent to free when passed into __attribute__((malloc ())), similar to how it is treated when it is encountered as a call. This fixes spurious warnings in glibc where xmalloc family of allocators as well as reallocarray, memalign, etc. are declared to have __builtin_free as the free function. gcc/analyzer/ChangeLog: * sm-malloc.cc (malloc_state_machine::get_or_create_deallocator): Recognize __builtin_free. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/attr-malloc-1.c (compatible_alloc, compatible_alloc2): New extern allocator declarations. (test_9, test_10): New tests. --- gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c index 3de32b1..a9a2a3d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c @@ -11,6 +11,12 @@ extern struct foo *foo_acquire (void) extern void use_foo (const struct foo *) __attribute__((nonnull)); +extern struct foo *compatible_alloc (void) + __attribute__ ((malloc (__builtin_free))); + +extern struct foo *compatible_alloc2 (void) + __attribute__ ((malloc (free))); + void test_1 (void) { struct foo *p = foo_acquire (); @@ -73,3 +79,16 @@ int test_8 (struct foo *p) foo_release (p); return p->m_int; /* { dg-warning "use after 'foo_release' of 'p'" } */ } + +/* Recognize that __builtin_free and free are the same thing. */ +void test_9 (void) +{ + struct foo *p = compatible_alloc (); + free (p); +} + +void test_10 (void) +{ + struct foo *p = compatible_alloc2 (); + __builtin_free (p); +} -- cgit v1.1 From 31534ac26e0ec1deeb648b2548dbbe17574ea78c Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 28 Jul 2021 15:43:47 +0530 Subject: analyzer: Handle strdup builtins Consolidate allocator builtin handling and add support for __builtin_strdup and __builtin_strndup. gcc/analyzer/ChangeLog: * analyzer.cc (is_named_call_p, is_std_named_call_p): Make first argument a const_tree. * analyzer.h (is_named_call_p, -s_std_named_call_p): Likewise. * sm-malloc.cc (known_allocator_p): New function. (malloc_state_machine::on_stmt): Use it. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/strdup-1.c (test_4, test_5, test_6): New tests. --- gcc/testsuite/gcc.dg/analyzer/strdup-1.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/strdup-1.c b/gcc/testsuite/gcc.dg/analyzer/strdup-1.c index 6b950ca..9ac3921 100644 --- a/gcc/testsuite/gcc.dg/analyzer/strdup-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/strdup-1.c @@ -14,8 +14,27 @@ void test_2 (const char *s) char *p = strdup (s); free (p); } + void test_3 (const char *s) { char *p = strdup (s); /* { dg-message "this call could return NULL" } */ requires_nonnull (p); /* { dg-warning "use of possibly-NULL 'p'" } */ } + +/* Repeat tests for __builtin_strdup. */ +void test_4 (const char *s) +{ + char *p = __builtin_strdup (s); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'p'" } */ + +void test_5 (const char *s) +{ + char *p = __builtin_strdup (s); + free (p); +} + +void test_6 (const char *s) +{ + char *p = __builtin_strdup (s); /* { dg-message "this call could return NULL" } */ + requires_nonnull (p); /* { dg-warning "use of possibly-NULL 'p'" } */ +} -- cgit v1.1 From 6bb6e2044ced33d08175361b8e39a9c5d4a868a6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 28 Jul 2021 14:16:35 +0200 Subject: tree-optimization/101615 - SLP permute opt of existing vectors This fixes one issue discovered when analyzing PR101615, namely we happily push permutes to pre-existing vectors but end up not actually permuting them. In fact we don't want to, so force materialization on the external. It doesn't fix the original testcase though. 2021-07-28 Richard Biener PR tree-optimization/101615 * tree-vect-slp.c (vect_optimize_slp): Pre-existing vector external nodes cannot be permuted so make them perm_out 0. * gcc.dg/vect/bb-slp-pr101615-1.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-1.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-1.c new file mode 100644 index 0000000..d1c9c02 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-1.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-additional-options "-w -Wno-psabi" } */ + +#include "tree-vect.h" + +typedef int v4si __attribute__((vector_size(16))); + +int a[4]; +int b[4]; + +void __attribute__((noipa)) +foo (v4si x) +{ + b[0] = a[3] + x[0]; + b[1] = a[2] + x[1]; + b[2] = a[1] + x[2]; + b[3] = a[0] + x[3]; +} + +int main() +{ + check_vect (); + for (int i = 0; i < 4; ++i) + a[i] = i; + v4si x = (v4si) { 8, 6, 4, 2 }; + foo (x); + if (b[0] != 11 || b[1] != 8 || b[2] != 5 || b[3] != 2) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 3c91efec15af4f922a9af495e178bbb66d2e9d1f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 28 Jul 2021 15:12:00 +0200 Subject: tree-optimization/101615 - SLP permute opt with CTOR roots CTOR roots are not explicitely represented so we have to make sure to materialize permutes on SLP graph entries to them. 2021-07-28 Richard Biener PR tree-optimization/101615 * tree-vect-slp.c (vect_optimize_slp): Materialize permutes at CTOR SLP graph entries. * gcc.dg/vect/bb-slp-pr101615-2.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-2.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-2.c new file mode 100644 index 0000000..ac89883 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101615-2.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-additional-options "-O3 -w -Wno-psabi" } */ + +#include "tree-vect.h" + +int res[6] = { 5, 7, 11, 3, 3, 3 }; +int a[6] = {5, 5, 8}; +int c; + +int main() +{ + check_vect (); + for (int b = 0; b <= 4; b++) + for (; c <= 4; c++) { + a[0] |= 1; + for (int e = 0; e <= 4; e++) + a[e + 1] |= 3; + } + for (int d = 0; d < 6; d++) + if (a[d] != res[d]) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 37eb3ef48c9840475646528751b5f8ffb7eb34ce Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 28 Jul 2021 14:47:54 -0400 Subject: analyzer: play better with -fsanitize=bounds gcc/analyzer/ChangeLog: * region-model.cc (region_model::on_call_pre): Treat IFN_UBSAN_BOUNDS, BUILT_IN_STACK_SAVE, and BUILT_IN_STACK_RESTORE as no-ops, rather than handling them as unknown functions. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/torture/ubsan-1.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/torture/ubsan-1.c | 60 +++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/ubsan-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/ubsan-1.c b/gcc/testsuite/gcc.dg/analyzer/torture/ubsan-1.c new file mode 100644 index 0000000..b9f34f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/ubsan-1.c @@ -0,0 +1,60 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ +/* { dg-additional-options "-fsanitize=bounds" } */ + +#include +#include "../analyzer-decls.h" + +int test_1 (int *arr, int i, int n) +{ + if (i >= n) + return 0; + return arr[i]; +} + +int test_2 (int *arr, int i, int n) +{ + if (i >= n) + return 0; + if (arr[i]) + __analyzer_eval (arr[i]); /* { dg-warning "TRUE" } */ + else + __analyzer_eval (arr[i]); /* { dg-warning "FALSE" } */ +} + +int test_3 (int arr[], int i, int n) +{ + if (i >= n) + return 0; + if (arr[i]) + __analyzer_eval (arr[i]); /* { dg-warning "TRUE" } */ + else + __analyzer_eval (arr[i]); /* { dg-warning "FALSE" } */ +} + +void test_4 (int i, int n) +{ + int arr[n]; + arr[i] = 42; + __analyzer_eval (arr[i] == 42); /* { dg-warning "TRUE" } */ +} + +void test_5 (int i, int n) +{ + int *arr = malloc (sizeof(int) * n); + if (arr) + { + arr[i] = 42; + __analyzer_eval (arr[i] == 42); /* { dg-warning "TRUE" } */ + } + free (arr); +} + +int global; + +void test_6 (int i, int n) +{ + int arr[n]; + int saved = global; + arr[i] = 42; + __analyzer_eval (saved == global); /* { dg-warning "TRUE" } */ +} -- cgit v1.1 From f471739e636734c2b4933cc4cb4ebad6cb2083ad Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 28 Jul 2021 17:24:23 -0400 Subject: PR 100168: Fix call test on power10. Fix a test that was checking for 64-bit TOC calls, to also allow for PC-relative calls. 2021-07-28 Michael Meissner gcc/testsuite PR testsuite/100168 * gcc.dg/pr56727-2.c: Add support for PC-relative calls. --- gcc/testsuite/gcc.dg/pr56727-2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr56727-2.c b/gcc/testsuite/gcc.dg/pr56727-2.c index c54369e..77fdf4b 100644 --- a/gcc/testsuite/gcc.dg/pr56727-2.c +++ b/gcc/testsuite/gcc.dg/pr56727-2.c @@ -18,4 +18,4 @@ void h () /* { dg-final { scan-assembler "@(PLT|plt)" { target i?86-*-* x86_64-*-* } } } */ /* { dg-final { scan-assembler "@(PLT|plt)" { target { powerpc*-*-linux* && ilp32 } } } } */ -/* { dg-final { scan-assembler "bl f\n\\s*nop" { target { powerpc*-*-linux* && lp64 } } } } */ +/* { dg-final { scan-assembler "(bl f\n\\s*nop)|(bl f@notoc)" { target { powerpc*-*-linux* && lp64 } } } } */ -- cgit v1.1 From b9cbf8c9e0bc72f59b643165247fae646560aadd Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Jul 2021 16:14:38 -0600 Subject: Correct -Warray-bounds handling if function pointers [PR101601]. Resolves: PR middle-end/101601 - -Warray-bounds triggers error: arrays of functions are not meaningful PR middle-end/101601 gcc/ChangeLog: * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref): Remove a pointless test. Handle pointers to functions. gcc/testsuite/ChangeLog: * g++.dg/warn/Warray-bounds-25.C: New test. * gcc.dg/Warray-bounds-85.c: New test. --- gcc/testsuite/gcc.dg/Warray-bounds-85.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-85.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-85.c b/gcc/testsuite/gcc.dg/Warray-bounds-85.c new file mode 100644 index 0000000..0ee7120 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-85.c @@ -0,0 +1,30 @@ +/* PR middle-end/101601 - [12 Regression] -Warray-bounds triggers error: + arrays of functions are not meaningful + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef void Fvv (void); + +extern Fvv* pf; // { dg-message "'pf'" } + +void f (void*); + +void test_funptr (void) +{ + f (&pf); + f (&pf + 1); + f (&pf + 2); // { dg-warning "subscript 2 is outside array bounds of 'void \\\(\\\*\\\[1]\\\)\\\(void\\\)'" } +} + +typedef int Fii_ (int, ...); + +extern Fii_* pfa[3]; // { dg-message "'pfa'" } + +void test_funptr_array (void) +{ + f (pfa); + f (pfa + 1); + f (pfa + 2); + f (pfa + 3); + f (pfa + 4); // { dg-warning "subscript 4 is outside array bounds of 'int \\\(\\\*\\\[3]\\\)\\\(int, ...\\\)'" } +} -- cgit v1.1 From 1121e495b70105deeb82295f8210e30f2080bc37 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Jul 2021 16:25:40 -0600 Subject: Correct uninitialized object offset and size computation [PR101494]. Resolves: PR middle-end/101494 - -Wuninitialized false alarm with memrchr of size 0 gcc/ChangeLog: PR middle-end/101494 * tree-ssa-uninit.c (maybe_warn_operand): Correct object offset and size computation. gcc/testsuite/ChangeLog: PR middle-end/101494 * gcc.dg/uninit-pr101494.c: New test. --- gcc/testsuite/gcc.dg/uninit-pr101494.c | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-pr101494.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pr101494.c b/gcc/testsuite/gcc.dg/uninit-pr101494.c new file mode 100644 index 0000000..d3267b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr101494.c @@ -0,0 +1,60 @@ +/* PR middle-end/101494 - bogus -Wmaybe-uninitialized on memrchr of size 0 + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +void* alloca (size_t); + +__attribute__ ((malloc, alloc_size (1))) void* alloc (size_t); + +__attribute__ ((access (read_only, 1, 2))) void* sink (void*, size_t); + +void test_alloca_zero (size_t i) +{ + char *p = alloca (0); + sink (p, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + +void test_alloca_zero_pi (size_t i) +{ + char *p = alloca (0); + sink (p + i, 0); +} + +void test_alloca_cst (void) +{ + char *p = alloca (7); + sink (p, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + +void test_alloca_cst_p1 (void) +{ + char *p = alloca (7); + sink (p + 1, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + +void test_alloca_cst_p7 (void) +{ + char *p = alloca (7); + sink (p + 7, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + +void test_alloca_var (size_t n) +{ + char *p = alloca (n); + sink (p, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + +void test_alloca_var_p1 (size_t n) +{ + char *p = alloca (n); + sink (p + 1, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + +void test_alloca_var_pn (size_t n) +{ + char *p = alloca (n); + sink (p + n, 0); // { dg-bogus "\\\[-Wuninitialized" } +} + -- cgit v1.1 From e63d76234d18cac731c4f3610d513bd8b39b5520 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 21 Jul 2021 09:14:24 +0200 Subject: c/101512 - fix missing address-taking in c_common_mark_addressable_vec c_common_mark_addressable_vec fails to look through C_MAYBE_CONST_EXPR in the case it isn't at the toplevel. 2021-07-21 Richard Biener PR c/101512 gcc/c-family/ * c-common.c (c_common_mark_addressable_vec): Look through C_MAYBE_CONST_EXPR even if not at the toplevel. gcc/testsuite/ * gcc.dg/torture/pr101512.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101512.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101512.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr101512.c b/gcc/testsuite/gcc.dg/torture/pr101512.c new file mode 100644 index 0000000..a25da2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101512.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-w -Wno-psabi" } */ + +int n(); +typedef unsigned long V __attribute__ ((vector_size (64))); +V +foo (int i, V v) +{ + i = ((V)(V){n()})[n()]; + return v + i; +} -- cgit v1.1 From 2e96b5f14e4025691b57d2301d71aa6092ed44bc Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 15 Jun 2021 12:32:51 +0200 Subject: Backwards jump threader rewrite with ranger. This is a rewrite of the backwards threader with a ranger based solver. The code is divided into two parts: the path solver in gimple-range-path.*, and the path discovery bits in tree-ssa-threadbackward.c. The legacy code is still available with --param=threader-mode=legacy, but will be removed shortly after. gcc/ChangeLog: * Makefile.in (tree-ssa-loop-im.o-warn): New. * flag-types.h (enum threader_mode): New. * params.opt: Add entry for --param=threader-mode. * tree-ssa-threadbackward.c (THREADER_ITERATIVE_MODE): New. (class back_threader): New. (back_threader::back_threader): New. (back_threader::~back_threader): New. (back_threader::maybe_register_path): New. (back_threader::find_taken_edge): New. (back_threader::find_taken_edge_switch): New. (back_threader::find_taken_edge_cond): New. (back_threader::resolve_def): New. (back_threader::resolve_phi): New. (back_threader::find_paths_to_names): New. (back_threader::find_paths): New. (dump_path): New. (debug): New. (thread_jumps::find_jump_threads_backwards): Call ranger threader. (thread_jumps::find_jump_threads_backwards_with_ranger): New. (pass_thread_jumps::execute): Abstract out code... (try_thread_blocks): ...here. * tree-ssa-threadedge.c (jump_threader::thread_outgoing_edges): Abstract out threading candidate code to... (single_succ_to_potentially_threadable_block): ...here. * tree-ssa-threadedge.h (single_succ_to_potentially_threadable_block): New. * tree-ssa-threadupdate.c (register_jump_thread): Return boolean. * tree-ssa-threadupdate.h (class jump_thread_path_registry): Return bool from register_jump_thread. libgomp/ChangeLog: * testsuite/libgomp.graphite/force-parallel-4.c: Adjust for threader. * testsuite/libgomp.graphite/force-parallel-8.c: Same. gcc/testsuite/ChangeLog: * g++.dg/debug/dwarf2/deallocator.C: Adjust for threader. * gcc.c-torture/compile/pr83510.c: Same. * dg.dg/analyzer/pr94851-2.c: Same. * gcc.dg/loop-unswitch-2.c: Same. * gcc.dg/old-style-asm-1.c: Same. * gcc.dg/pr68317.c: Same. * gcc.dg/pr97567-2.c: Same. * gcc.dg/predict-9.c: Same. * gcc.dg/shrink-wrap-loop.c: Same. * gcc.dg/sibcall-1.c: Same. * gcc.dg/tree-ssa/builtin-sprintf-3.c: Same. * gcc.dg/tree-ssa/pr21001.c: Same. * gcc.dg/tree-ssa/pr21294.c: Same. * gcc.dg/tree-ssa/pr21417.c: Same. * gcc.dg/tree-ssa/pr21458-2.c: Same. * gcc.dg/tree-ssa/pr21563.c: Same. * gcc.dg/tree-ssa/pr49039.c: Same. * gcc.dg/tree-ssa/pr61839_1.c: Same. * gcc.dg/tree-ssa/pr61839_3.c: Same. * gcc.dg/tree-ssa/pr77445-2.c: Same. * gcc.dg/tree-ssa/split-path-4.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-11.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-12.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-14.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-18.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Same. * gcc.dg/tree-ssa/ssa-fre-48.c: Same. * gcc.dg/tree-ssa/ssa-thread-11.c: Same. * gcc.dg/tree-ssa/ssa-thread-12.c: Same. * gcc.dg/tree-ssa/ssa-thread-14.c: Same. * gcc.dg/tree-ssa/vrp02.c: Same. * gcc.dg/tree-ssa/vrp03.c: Same. * gcc.dg/tree-ssa/vrp05.c: Same. * gcc.dg/tree-ssa/vrp06.c: Same. * gcc.dg/tree-ssa/vrp07.c: Same. * gcc.dg/tree-ssa/vrp09.c: Same. * gcc.dg/tree-ssa/vrp19.c: Same. * gcc.dg/tree-ssa/vrp20.c: Same. * gcc.dg/tree-ssa/vrp33.c: Same. * gcc.dg/uninit-pred-9_b.c: Same. * gcc.dg/uninit-pr61112.c: Same. * gcc.dg/vect/bb-slp-16.c: Same. * gcc.target/i386/avx2-vect-aggressive.c: Same. * gcc.dg/tree-ssa/ranger-threader-1.c: New test. * gcc.dg/tree-ssa/ranger-threader-2.c: New test. * gcc.dg/tree-ssa/ranger-threader-3.c: New test. * gcc.dg/tree-ssa/ranger-threader-4.c: New test. * gcc.dg/tree-ssa/ranger-threader-5.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr94851-2.c | 2 +- gcc/testsuite/gcc.dg/loop-unswitch-2.c | 2 +- gcc/testsuite/gcc.dg/old-style-asm-1.c | 5 +- gcc/testsuite/gcc.dg/pr68317.c | 4 +- gcc/testsuite/gcc.dg/pr97567-2.c | 2 +- gcc/testsuite/gcc.dg/predict-9.c | 4 +- gcc/testsuite/gcc.dg/shrink-wrap-loop.c | 53 +++++++++++++++ gcc/testsuite/gcc.dg/sibcall-1.c | 10 +++ gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-3.c | 25 ++++++- gcc/testsuite/gcc.dg/tree-ssa/pr21001.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/pr21294.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/pr21417.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr21458-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr21563.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr49039.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-1.c | 20 ++++++ gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-2.c | 39 +++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-3.c | 41 +++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c | 83 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-5.c | 80 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-11.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-12.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-14.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c | 5 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-48.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/vrp02.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp03.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp05.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp06.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp07.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp09.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp19.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp20.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp33.c | 2 +- gcc/testsuite/gcc.dg/uninit-pr61112.c | 6 +- gcc/testsuite/gcc.dg/uninit-pred-9_b.c | 1 + gcc/testsuite/gcc.dg/vect/bb-slp-16.c | 7 ++ 46 files changed, 408 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-3.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-5.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c b/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c index b837451..0acf488 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr94851-2.c @@ -45,7 +45,7 @@ int pamark(void) { if (curbp->b_amark == (AMARK *)NULL) curbp->b_amark = p; else - last->m_next = p; /* { dg-warning "dereference of NULL 'last'" } */ + last->m_next = p; /* { dg-warning "dereference of NULL 'last'" "deref" { xfail *-*-* } } */ } p->m_name = (char)c; /* { dg-bogus "leak of 'p'" "bogus leak" } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-2.c b/gcc/testsuite/gcc.dg/loop-unswitch-2.c index f8d314e..0931f6e 100644 --- a/gcc/testsuite/gcc.dg/loop-unswitch-2.c +++ b/gcc/testsuite/gcc.dg/loop-unswitch-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-details" } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-details -fdisable-tree-thread2 -fdisable-tree-thread3" } */ void foo (float **a, float **b, float *c, int n, int m, int l) { diff --git a/gcc/testsuite/gcc.dg/old-style-asm-1.c b/gcc/testsuite/gcc.dg/old-style-asm-1.c index 8af0077..f9406ff0 100644 --- a/gcc/testsuite/gcc.dg/old-style-asm-1.c +++ b/gcc/testsuite/gcc.dg/old-style-asm-1.c @@ -1,6 +1,9 @@ /* PR inline-asm/8832 */ /* { dg-do compile } */ -/* { dg-options "-O2 -dP" } */ +/* { dg-options "-O2 -dP -fdisable-tree-ethread -fdisable-tree-thread1 -fdisable-tree-thread2 -fdisable-tree-thread3 -fdisable-tree-thread4" } */ + +/* Note: Threader will duplicate BBs and replace one conditional branch by an + unconditional one. */ /* Verify that GCC doesn't optimize old style asm instructions. */ diff --git a/gcc/testsuite/gcc.dg/pr68317.c b/gcc/testsuite/gcc.dg/pr68317.c index 891d129..bd053a7 100644 --- a/gcc/testsuite/gcc.dg/pr68317.c +++ b/gcc/testsuite/gcc.dg/pr68317.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -fdisable-tree-ethread" } */ + +/* Note: Threader will collapse loop. */ typedef int int32_t __attribute__((mode (__SI__))); diff --git a/gcc/testsuite/gcc.dg/pr97567-2.c b/gcc/testsuite/gcc.dg/pr97567-2.c index dee31c6..c3ead54 100644 --- a/gcc/testsuite/gcc.dg/pr97567-2.c +++ b/gcc/testsuite/gcc.dg/pr97567-2.c @@ -1,5 +1,5 @@ /* { dg-do compile} */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp -fdisable-tree-ethread" } */ char a[2]; diff --git a/gcc/testsuite/gcc.dg/predict-9.c b/gcc/testsuite/gcc.dg/predict-9.c index f491c51..cb68a21 100644 --- a/gcc/testsuite/gcc.dg/predict-9.c +++ b/gcc/testsuite/gcc.dg/predict-9.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-profile_estimate -fno-finite-loops" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-profile_estimate -fno-finite-loops -fdisable-tree-ethread" } */ + +/* Note: Threader causes removal of for loop. */ extern int global; extern int global2; diff --git a/gcc/testsuite/gcc.dg/shrink-wrap-loop.c b/gcc/testsuite/gcc.dg/shrink-wrap-loop.c index 52dfc27..ba872fa 100644 --- a/gcc/testsuite/gcc.dg/shrink-wrap-loop.c +++ b/gcc/testsuite/gcc.dg/shrink-wrap-loop.c @@ -1,5 +1,58 @@ /* { dg-do compile { target { { { i?86-*-* x86_64-*-* } && lp64 } || { arm_thumb2 } } } } */ /* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */ +// { dg-additional-options "-fdisable-tree-ethread" } + +/* +Our new threader is threading things a bit too early, and causing the +testcase in gcc.dg/shrink-wrap-loop.c to fail. + + The gist is this BB inside a loop: + + : + # p_2 = PHI + if (p_2 != 0B) + goto ; [INV] + else + goto ; [INV] + +Our threader can move this check outside of the loop (good). This is +done before branch probabilities are calculated and causes the probs +to be calculated as: + + [local count: 216361238]: + if (p2_6(D) != 0B) + goto ; [54.59%] + else + goto ; [45.41%] + +Logically this seems correct to me. A simple check outside of a loop +should slightly but not overwhelmingly favor a non-zero value. + +Interestingly however, the old threader couldn't get this, but the IL +ended up identical, albeit with different probabilities. What happens +is that, because the old code could not thread this, the p2 != 0 check +would remain inside the loop and probs would be calculated thusly: + + [local count: 1073741824]: + # p_2 = PHI + if (p_2 != 0B) + goto ; [94.50%] + else + goto ; [5.50%] + +Then when the loop header copying pass ("ch") shuffled things around, +the IL would end up identical to my early threader code, but with the +probabilities would remain as 94.5/5.5. + +The above discrepancy causes the RTL ifcvt pass to generate different +code, and by the time we get to the shrink wrapping pass, things look +sufficiently different such that the legacy code can actually shrink +wrap, whereas our new code does not. + +IMO, if the loop-ch pass moves conditionals outside of a loop, the +probabilities should be adjusted, but that does mean the shrink wrap +won't happen for this contrived testcase. + */ int foo (int *p1, int *p2); diff --git a/gcc/testsuite/gcc.dg/sibcall-1.c b/gcc/testsuite/gcc.dg/sibcall-1.c index e8a9551..367ee43 100644 --- a/gcc/testsuite/gcc.dg/sibcall-1.c +++ b/gcc/testsuite/gcc.dg/sibcall-1.c @@ -7,6 +7,9 @@ /* { dg-do run } */ /* { dg-options "-O2 -foptimize-sibling-calls" } */ +/* See note in recurser_void() as to why we disable threading. */ +/* { dg-additional-options "-fdisable-tree-thread1" } */ + /* The option -foptimize-sibling-calls is the default, but serves as marker. Self-recursion tail calls are optimized for all targets, regardless of presence of sibcall patterns. */ @@ -26,6 +29,13 @@ int main () void recurser_void (int n) { + /* In some architectures like ppc64*, jump threading may thread + paths such that there are two calls into track(), one for + track(0) and one for track(7). The track(7) call can be + transformed into a jump instead of a call, which means that + different calls into track() may end up with a different + &stackpos. This is the reason we disable jump threading for this + test. */ if (n == 0 || n == 7) track (n); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-3.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-3.c index fae2a1b..ec55f26 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-3.c @@ -15,7 +15,7 @@ extern void string_lt_0_fail (); extern void string_eq_0_fail (); extern void string_gt_0_fail (); -void test_string (char *d, const char *s) +void test_string_eq_min (char *d, const char *s) { int n = __builtin_sprintf (d, "%-s", s); @@ -23,13 +23,36 @@ void test_string (char *d, const char *s) or INT_MAX. (This is a white box test based on knowing that the optimization computes its own values of the two constants.) */ if (n == INT_MIN) string_eq_min_fail (); +} + +void test_string_eq_max (char *d, const char *s) +{ + int n = __builtin_sprintf (d, "%-s", s); + if (n == INT_MAX) string_eq_max_fail (); +} + +void test_string_lt_0 (char *d, const char *s) +{ + int n = __builtin_sprintf (d, "%-s", s); /* The return value could be negative when strlen(s) is in excess of 4095 (the maximum number of bytes a single directive is required to handle). */ if (n < 0) string_lt_0_fail (); +} + +void test_string_eq_0 (char *d, const char *s) +{ + int n = __builtin_sprintf (d, "%-s", s); + if (n == 0) string_eq_0_fail (); +} + +void test_string_gt_0 (char *d, const char *s) +{ + int n = __builtin_sprintf (d, "%-s", s); + if (n > 0) string_gt_0_fail (); } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c index 719360a..4ea5f21 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c @@ -6,6 +6,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fno-tree-dominator-opts -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1-details" } */ +/* { dg-additional-options "-fdisable-tree-ethread -fdisable-tree-thread1" } */ int foo (int a) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21294.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21294.c index cc7d4cd..b9edabc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21294.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21294.c @@ -5,6 +5,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp -fdump-tree-vrp1-details" } */ +/* { dg-additional-options "-fdisable-tree-ethread -fdisable-tree-thread1" } */ struct f { int i; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c index 4845119..fc14af4 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-thread4-details" } */ +/* { dg-options "-O2 -fdisable-tree-thread3 -fdump-tree-thread4-details" } */ struct tree_common { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21458-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21458-2.c index 2aee42f..f8d7353 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21458-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21458-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp-details" } */ +/* { dg-options "-O2 -fdump-tree-evrp-details -fdisable-tree-ethread" } */ extern void g (void); extern void bar (int); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c index 9c67a3a..72dce83 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21563.c @@ -2,7 +2,7 @@ Make sure VRP folds the second "if" statement. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp -fdump-tree-vrp1-details" } */ +/* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp -fdump-tree-vrp1-details -fdisable-tree-ethread -fdisable-tree-thread1" } */ int foo (int a) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c b/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c index 4bc0a81..a2044d0 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr49039.c @@ -1,6 +1,6 @@ /* PR tree-optimization/49039 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdisable-tree-ethread -fdisable-tree-thread1" } */ extern void bar (void); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c index d44c7dc..ddc53fb 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c @@ -1,6 +1,6 @@ /* PR tree-optimization/61839. */ /* { dg-do run } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdisable-tree-evrp -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fdisable-tree-evrp -fdump-tree-optimized -fdisable-tree-ethread -fdisable-tree-thread1" } */ /* { dg-require-effective-target int32plus } */ __attribute__ ((noinline)) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c index 5ceb073..cc322d6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c @@ -1,6 +1,6 @@ /* PR tree-optimization/61839. */ /* { dg-do run } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-optimized -fdisable-tree-ethread -fdisable-tree-thread1" } */ __attribute__ ((noinline)) int foo (int a, unsigned b) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c index cf74e15..f9fc212 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c @@ -124,7 +124,7 @@ enum STATES FMS( u8 **in , u32 *transitions) { to change decisions in switch expansion which in turn can expose new jump threading opportunities. Skip the later tests on aarch64. */ /* { dg-final { scan-tree-dump "Jumps threaded: 1\[1-9\]" "thread1" } } */ -/* { dg-final { scan-tree-dump-times "Invalid sum" 3 "thread1" } } */ +/* { dg-final { scan-tree-dump-times "Invalid sum" 4 "thread1" } } */ /* { dg-final { scan-tree-dump-not "optimizing for size" "thread1" } } */ /* { dg-final { scan-tree-dump-not "optimizing for size" "thread2" } } */ /* { dg-final { scan-tree-dump-not "optimizing for size" "thread3" { target { ! aarch64*-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-1.c new file mode 100644 index 0000000..c3ccb5d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-thread1-details --param logical-op-non-short-circuit=1" } */ + +// Copied from ssa-dom-thread-11.c + +static int *bb_ticks; +extern void frob (void); +void +mark_target_live_regs (int b, int block, int bb_tick) +{ + if (b == block && b != -1 && bb_tick == bb_ticks[b]) + return; + if (b != -1) + frob (); +} + +/* When the first two conditionals in the first IF are true, but + the third conditional is false, then there's a jump threading + opportunity to bypass the second IF statement. */ +/* { dg-final { scan-tree-dump-times "Registering.*jump thread" 1 "thread1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-2.c new file mode 100644 index 0000000..d2689b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-2.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-thread2-details -w" } */ + +// Copied from ssa-dom-thread-12.c. + +typedef long unsigned int size_t; +union tree_node; +typedef union tree_node *tree; +typedef union gimple_statement_d *gimple; +typedef const union gimple_statement_d *const_gimple; +union gimple_statement_d +{ + unsigned num_ops; + tree exp; +}; + +unsigned int x; +static inline tree +gimple_op (const_gimple gs, unsigned i) +{ + if (!(i < gs->num_ops)) + abort (); + return gs->exp; +} + +unsigned char +scan_function (gimple stmt) +{ + unsigned i; + for (i = 0; i < stmt->num_ops - 3 ; i++) + gimple_call_arg (stmt, i); + gimple_op (stmt, 1); +} + +/* The test which bypasses the loop is simplified prior to DOM to check + that stmt->num_ops - 3 != 0. When that test is false, we can derive + a value for stmt->num_ops. That in turn allows us to thread the jump + for the conditional at the start of the call to gimple_op. */ +/* { dg-final { scan-tree-dump-times "Registering.*jump thread" 1 "thread2"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-3.c new file mode 100644 index 0000000..79ec067 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-3.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ethread-details -w --param logical-op-non-short-circuit=1" } */ + +// Copied from ssa-dom-thread-14.c + +enum optab_methods +{ + OPTAB_DIRECT, + OPTAB_LIB, + OPTAB_WIDEN, + OPTAB_LIB_WIDEN, + OPTAB_MUST_WIDEN +}; +struct optab_d { }; +typedef struct optab_d *optab; +void +expand_shift_1 (int code, int unsignedp, int rotate, + optab lshift_optab, optab rshift_arith_optab) +{ + int left = (code == 42 || code == 0xde); + int attempt; + enum optab_methods methods; + if (attempt == 0) + methods = OPTAB_DIRECT; + else if (attempt == 1) + methods = OPTAB_WIDEN; + if ((!unsignedp || (!left && methods == OPTAB_WIDEN))) + { + enum optab_methods methods1 = methods; + if (unsignedp) + methods1 = OPTAB_MUST_WIDEN; + expand_binop (left ? lshift_optab : rshift_arith_optab, + unsignedp, methods1); + } +} + +/* When UNSIGNEDP is true, LEFT is false and METHOD == OPTAB_WIDEN + we will enter the TRUE arm of the conditional and we can thread + the test to compute the first first argument of the expand_binop + call if we look backwards through the boolean logicals. */ +/* { dg-final { scan-tree-dump-times "Registering.*jump thread" 1 "ethread"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c new file mode 100644 index 0000000..e8d1cfc --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2 -fdump-tree-vrp-details -fdump-tree-thread1-details --param logical-op-non-short-circuit=1" } */ +/* { dg-final { scan-tree-dump-times "Registering FSM jump" 8 "thread1" } } */ + +/* Copied from ssa-thread-14. */ + +void foo (void); +void bar (void); +void blah (void); + +/* One jump threaded here. */ + +void +baz_1 (int a, int b, int c) +{ + if (a && b) + foo (); + if (!b && c) + bar (); +} + +/* One jump threaded here. */ + +void +baz_2 (int a, int b, int c) +{ + if (a && b) + foo (); + if (b || c) + bar (); +} + +/* One jump threaded here. */ + +void +baz_3 (int a, int b, int c) +{ + if (a && b > 10) + foo (); + if (b < 5 && c) + bar (); +} + +/* Two jumps threaded here. */ + +void +baz_4 (int a, int b, int c) +{ + if (a && b) + { + foo (); + if (c) + bar (); + } + if (b && c) + blah (); +} + +/* Two jumps threaded here. */ + +void +baz_5 (int a, int b, int c) +{ + if (a && b) + { + foo (); + if (c) + bar (); + } + if (!b || !c) + blah (); +} + +/* One jump threaded here. */ + +void +baz_6 (int a, int b, int c) +{ + if (a == 39 && b == 41) + foo (); + if (c == 12 || b == 41) + bar (); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-5.c new file mode 100644 index 0000000..b7ca99a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-5.c @@ -0,0 +1,80 @@ +// { dg-do compile } +// { dg-options "-fgimple -O2 -fdump-tree-thread1-details" } + +/* This tests that we can thread BB4->BB999 coming in through the + following path: + + latch many insns + | | + V V + 6 -> 7 -> 3 -> 4 -> 999 + + The ranger based threader cannot thread this because BB4 has too + many instructions so it gives up looking back. However, if we were + able to looking further, we would notice that a profitable path + passing through the loop latch (BB7) exists. + + That is, 3->4->N in isolation is not profitable, but 6->7->3->4->N is. + + It is not clear whether handling this case in the backwards + threader is profitable, as it would increase the search space + considerably. The test is being added to note a regression from + the old backward threader code. + + This test has been distilled from libphobos/src/std/net/isemail.d. + + The ranger threader stops at the 3->4 subpath with: "did not thread + around loop and would copy too many statements". */ + + +extern void bar(); +extern int random(); + +int __GIMPLE (ssa,startwith("thread1")) +foo (int key) +{ + int context; + int _1454; + + __BB(2): + goto __BB3; + + // Loop header. + __BB(3): + context_448 = __PHI (__BB2: 0, __BB7: context_450); + if (key_5(D) > 0) + goto __BB999; + else + goto __BB4; + + __BB(4): + bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); + bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); + bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); + bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); + bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); + bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); bar(); + switch (context_448) {default: L5; case 0: L999; } + + __BB(5): + L5: + goto __BB6; + + __BB(6): + context_450 = __PHI (__BB5: 0); + _1454 = random (); + if (_1454 > 0) + goto __BB999; + else + goto __BB7; + + // Loop latch. + __BB(7): + goto __BB3; + + __BB(999): + L999: + return 5; +} + +// { dg-final { scan-tree-dump-times "Registering.*jump thread.*incoming edge; \\(6, 7\\) \\(7, 3\\) \\(3, 4\\) \\(4, 999\\) nocopy" 1 "thread1" { xfail *-*-* } } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c index dac931c..8ef7646 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w" } */ +/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w -fdisable-tree-thread1 -fdisable-tree-thread2" } */ + +/* Note: Threader causes the infinite loop in val & 1 sooner. */ powi_cost (long n) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-11.c index 5f90613..856ab38 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-11.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-dom2-details --param logical-op-non-short-circuit=1" } */ +/* { dg-options "-O2 -fdump-tree-dom2-details --param logical-op-non-short-circuit=1 -fdisable-tree-thread1 -fdisable-tree-thread2" } */ static int *bb_ticks; extern void frob (void); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-12.c index 63bd12a..bad5e0a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-dom2-details -w" } */ +/* { dg-options "-O2 -fdump-tree-dom2-details -w -fdisable-tree-thread2" } */ typedef long unsigned int size_t; union tree_node; typedef union tree_node *tree; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-14.c index 4e6a911..3bc4b37 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-14.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-14.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-dom2-details -w --param logical-op-non-short-circuit=1" } */ +/* { dg-additional-options "-fdisable-tree-thread1 -fdisable-tree-ethread -fdisable-tree-thread2" } */ enum optab_methods { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c index d4759b8..03872e7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1-details -fdump-tree-dom2-details -std=gnu89 --param logical-op-non-short-circuit=0" } */ +/* { dg-options "-O2 -fdump-tree-vrp1-details -fdump-tree-thread1-details -std=gnu89 --param logical-op-non-short-circuit=0" } */ #include "ssa-dom-thread-4.c" @@ -21,4 +21,5 @@ condition. All the cases are picked up by VRP1 as jump threads. */ -/* { dg-final { scan-tree-dump-times "Threaded" 4 "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "Registering FSM jump" 6 "thread1" } } */ +/* { dg-final { scan-tree-dump-times "Threaded" 2 "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c index 16a9ef4..c7bf867 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c @@ -34,8 +34,8 @@ SWITCH_BB -> BBx -> BBy -> BBz -> PHI We now know the value of the switch index at PHI. */ -/* { dg-final { scan-tree-dump-times "FSM" 6 "thread1" } } */ -/* { dg-final { scan-tree-dump-times "FSM" 1 "thread2" } } */ +/* { dg-final { scan-tree-dump-times "Registering FSM jump" 6 "thread1" } } */ +/* { dg-final { scan-tree-dump-times "Registering FSM jump" 1 "thread2" } } */ int sum0, sum1, sum2, sum3; int foo (char *s, char **ret) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index bad5bc1..1c2d12a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-dom2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */ +/* { dg-additional-options "--param=threader-mode=legacy" } */ /* Here we have the same issue as was commented in ssa-dom-thread-6.c. The PHI coming into the threader has a lot more constants, so the diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-48.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-48.c index b3d6102..5e74c78 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-48.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-48.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fdump-tree-fre1-details" } */ +/* { dg-options "-O -fdump-tree-fre1-details -fdisable-tree-ethread" } */ int foo (int i) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c index 67e1e89..672a54e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-11.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-vrp2-details --param logical-op-non-short-circuit=1" } */ +/* { dg-additional-options "-fdisable-tree-ethread -fdisable-tree-thread1 -fdisable-tree-thread2" } */ /* { dg-final { scan-tree-dump-not "IRREDUCIBLE_LOOP" "vrp2" } } */ void abort (void); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c index fb9840e..8f55464 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c @@ -2,7 +2,7 @@ /* { dg-options "-O2 -fdump-tree-thread2-details -fdump-tree-thread3-details -fdump-tree-thread4-details -fno-finite-loops --param early-inlining-insns=14 -fno-inline-functions" } */ /* { dg-final { scan-tree-dump "FSM" "thread2" } } */ /* { dg-final { scan-tree-dump "FSM" "thread3" } } */ -/* { dg-final { scan-tree-dump "FSM" "thread4" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump "FSM" "thread4" } } */ typedef struct bitmap_head_def *bitmap; typedef const struct bitmap_head_def *const_bitmap; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c index 38661c8..f9152b9 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-additional-options "-O2 -fdump-tree-vrp-details --param logical-op-non-short-circuit=1" } */ +/* { dg-additional-options "-fdisable-tree-thread1" } */ /* { dg-final { scan-tree-dump-times "Threaded jump" 8 "vrp1" } } */ void foo (void); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c index 4be538f..2285c55 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks -fdisable-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks -fdisable-tree-evrp -fdisable-tree-ethread -fdisable-tree-thread1" } */ struct A { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp03.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp03.c index bafb65a..1d7ea4e8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp03.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp03.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdisable-tree-ethread -fdisable-tree-thread1" } */ struct A { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c index 8c611e9..c17cd1b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdisable-tree-ethread -fdisable-tree-thread1" } */ inline int ten() diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c index a872bc4..acb03c2 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdisable-tree-ethread -fdisable-tree-thread1" } */ int baz (void); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c index 0f3f280..31a5415 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */ +/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks -fdisable-tree-ethread -fdisable-tree-thread1" } */ int foo (int i, int *p) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c index 56cc50c..fad0051 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1 -std=gnu89" } */ +/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1 -std=gnu89 -fdisable-tree-ethread -fdisable-tree-thread1" } */ foo (int *p) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c index 40373fd..98a8da6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp19.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fwrapv -O1 -ftree-vrp -fdisable-tree-evrp -fdump-tree-vrp1" } */ +/* { dg-options "-fwrapv -O1 -ftree-vrp -fdisable-tree-evrp -fdump-tree-vrp1 -fdisable-tree-ethread -fdisable-tree-thread1" } */ #include extern void abort (); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c index 4a3b0d7..f9df67f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fwrapv -O1 -fno-tree-fre -fdisable-tree-evrp -ftree-vrp -fdump-tree-vrp1" } */ +/* { dg-options "-fwrapv -O1 -fno-tree-fre -fdisable-tree-evrp -ftree-vrp -fdump-tree-vrp1 -fdisable-tree-ethread -fdisable-tree-thread1" } */ extern void abort (); extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c index f1d3863..88833eb 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre -fdisable-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre -fdisable-tree-evrp -fdisable-tree-ethread -fdisable-tree-thread1" } */ /* This is from PR14052. */ diff --git a/gcc/testsuite/gcc.dg/uninit-pr61112.c b/gcc/testsuite/gcc.dg/uninit-pr61112.c index 1dbf756..d8f9c80 100644 --- a/gcc/testsuite/gcc.dg/uninit-pr61112.c +++ b/gcc/testsuite/gcc.dg/uninit-pr61112.c @@ -29,7 +29,7 @@ void foo_c5_1_1 (int x, int y, int z, int a) w = __LINE__; if (x || y || a) - p = w; // { dg-bogus "-Wmaybe-uninitialized" "pr61112" { xfail *-*-* } } + p = w; } void foo_c5_1_2 (int x, int y, int z, int a) @@ -43,7 +43,7 @@ void foo_c5_1_2 (int x, int y, int z, int a) w = __LINE__; if (x || a || y) - p = w; // { dg-bogus "-Wmaybe-uninitialized" "pr61112" { xfail *-*-* } } + p = w; } void foo_c5_1_3 (int x, int y, int z, int a) @@ -57,7 +57,7 @@ void foo_c5_1_3 (int x, int y, int z, int a) w = __LINE__; if (a || x || y) - p = w; // { dg-bogus "-Wmaybe-uninitialized" "pr61112" { xfail *-*-* } } + p = w; } void foo_c5_2 (int x, int y, int z, int a) diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c index d9ae75e..d46d665 100644 --- a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c +++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-Wuninitialized -O2" } */ +/* { dg-xfail-if "threading shuffles things around" { ppc64*-*-* } } */ int g; void bar(); diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c index e68a9b6..664e93e 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c @@ -1,5 +1,8 @@ /* { dg-require-effective-target vect_int } */ +/* See note below as to why we disable threading. */ +/* { dg-additional-options "-fdisable-tree-thread1" } */ + #include #include "tree-vect.h" @@ -27,6 +30,10 @@ main1 (int dummy) *pout++ = *pin++ + a; *pout++ = *pin++ + a; *pout++ = *pin++ + a; + /* In some architectures like ppc64, jump threading may thread + the iteration where i==0 such that we no longer optimize the + BB. Another alternative to disable jump threading would be + to wrap the read from `i' into a function returning i. */ if (arr[i] = i) a = i; else -- cgit v1.1 From 0829ab79d37be6c59072af0c4f54043f7e9d23ea Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 2 Mar 2021 04:20:11 -0800 Subject: [OpenACC] Extract 'pass_oacc_loop_designation' out of 'pass_oacc_device_lower' This really is a separate step -- and another pass to be added between the two, later on. gcc/ * omp-offload.c (oacc_loop_xform_head_tail, oacc_loop_process): 'update_stmt' after modification. (pass_oacc_loop_designation): New function, extracted out of... (pass_oacc_device_lower): ... this. (pass_data_oacc_loop_designation, pass_oacc_loop_designation) (make_pass_oacc_loop_designation): New * passes.def: Add it. * tree-parloops.c (create_parallel_loop): Adjust. * tree-pass.h (make_pass_oacc_loop_designation): New. gcc/testsuite/ * c-c++-common/goacc/classify-kernels-unparallelized.c: 's%oaccdevlow%oaccloops%g'. * c-c++-common/goacc/classify-kernels.c: Likewise. * c-c++-common/goacc/classify-parallel.c: Likewise. * c-c++-common/goacc/classify-routine-nohost.c: Likewise. * c-c++-common/goacc/classify-routine.c: Likewise. * c-c++-common/goacc/classify-serial.c: Likewise. * c-c++-common/goacc/routine-nohost-1.c: Likewise. * g++.dg/goacc/template.C: Likewise. * gcc.dg/goacc/loop-processing-1.c: Likewise. * gfortran.dg/goacc/classify-kernels-unparallelized.f95: Likewise. * gfortran.dg/goacc/classify-kernels.f95: Likewise. * gfortran.dg/goacc/classify-parallel.f95: Likewise. * gfortran.dg/goacc/classify-routine-nohost.f95: Likewise. * gfortran.dg/goacc/classify-routine.f95: Likewise. * gfortran.dg/goacc/classify-serial.f95: Likewise. * gfortran.dg/goacc/routine-multiple-directives-1.f90: Likewise. libgomp/ * testsuite/libgomp.oacc-c-c++-common/pr85486-2.c: 's%oaccdevlow%oaccloops%g'. * testsuite/libgomp.oacc-c-c++-common/pr85486-3.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/pr85486.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-2.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-4.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-5.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-6.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/vector-length-128-7.c: Likewise. * testsuite/libgomp.oacc-fortran/routine-nohost-1.f90: Likewise. Co-Authored-By: Julian Brown Co-Authored-By: Kwok Cheung Yeung --- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/goacc/loop-processing-1.c b/gcc/testsuite/gcc.dg/goacc/loop-processing-1.c index bd4c07e..78b9aed 100644 --- a/gcc/testsuite/gcc.dg/goacc/loop-processing-1.c +++ b/gcc/testsuite/gcc.dg/goacc/loop-processing-1.c @@ -1,5 +1,5 @@ /* Make sure that OpenACC loop processing happens. */ -/* { dg-additional-options "-O2 -fdump-tree-oaccdevlow" } */ +/* { dg-additional-options "-O2 -fdump-tree-oaccloops" } */ extern int place (); @@ -15,4 +15,4 @@ void vector_1 (int *ary, int size) } } -/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */ +/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccloops" } } */ -- cgit v1.1 From 2f6bdd51cfe15403085b69c133065ebda4af9bb9 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 29 Jul 2021 10:11:18 -0600 Subject: Xfail just the failing assertion and correct target. Related to: PR middle-end/101674 - gcc.dg/uninit-pred-9_b.c fails after jump threading rewrite gcc/testsuite: PR middle-end/101674 * gcc.dg/uninit-pred-9_b.c: Xfail just the failing assertion and correct target. --- gcc/testsuite/gcc.dg/uninit-pred-9_b.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c index d46d665..e0dc214 100644 --- a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c +++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c @@ -1,7 +1,5 @@ - /* { dg-do compile } */ /* { dg-options "-Wuninitialized -O2" } */ -/* { dg-xfail-if "threading shuffles things around" { ppc64*-*-* } } */ int g; void bar(); @@ -22,7 +20,7 @@ int foo (int n, int l, int m, int r) blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ if ( (n <= 8) && (m < 99) && (r < 19) ) - blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail powerpc64*-*-* } } */ return 0; } -- cgit v1.1 From 2730aa7809b47dce47ca0b5e51a6af2164335cf1 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 30 Jul 2021 12:28:21 +0200 Subject: Mark gcc.dg/shrink-wrap-loop.c as XFAIL. It occurs to me that I should not have disabled early jump threading in this test, as it may hide an actual defect. I have reverted my change and XFAILed the test instead. I have also opened a PR101690 to keep track of this problem. gcc/testsuite/ChangeLog: * gcc.dg/shrink-wrap-loop.c: Enable early jump threading. Mark as XFAIL. --- gcc/testsuite/gcc.dg/shrink-wrap-loop.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/shrink-wrap-loop.c b/gcc/testsuite/gcc.dg/shrink-wrap-loop.c index ba872fa..6e1be893 100644 --- a/gcc/testsuite/gcc.dg/shrink-wrap-loop.c +++ b/gcc/testsuite/gcc.dg/shrink-wrap-loop.c @@ -1,6 +1,5 @@ /* { dg-do compile { target { { { i?86-*-* x86_64-*-* } && lp64 } || { arm_thumb2 } } } } */ /* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */ -// { dg-additional-options "-fdisable-tree-ethread" } /* Our new threader is threading things a bit too early, and causing the @@ -69,4 +68,4 @@ test (int *p1, int *p2) return 1; } -/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" } } */ +/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { xfail *-*-* } } } */ -- cgit v1.1 From d68d275a00573be49f5e83eba52ce3f26d11db9e Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Thu, 29 Jul 2021 12:56:18 -0700 Subject: Add testcases that got lost when tree-ssa was merged So I was looking at some older PRs (PR 16016 in this case), I noticed that some of the testcases were removed when the tree-ssa branch was merged. This adds them back in. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Thanks, Andrew Pinski gcc/testsuite/ChangeLog: PR testsuite/101517 * g++.dg/warn/Wunused-18.C: New test. * gcc.c-torture/compile/20030405-2.c: New test. * gcc.c-torture/compile/20040304-2.c: New test. * gcc.dg/20030612-2.c: New test. --- gcc/testsuite/gcc.dg/20030612-2.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/20030612-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/20030612-2.c b/gcc/testsuite/gcc.dg/20030612-2.c new file mode 100644 index 0000000..f9f212c --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030612-2.c @@ -0,0 +1,20 @@ +/* Derived from PR middle-end/168. */ + +/* { dg-do compile } */ +/* { dg-options "-W" } */ + +extern void foo (); + +unsigned char uc; +unsigned short int usi; +unsigned int ui; + + +void bar() +{ + if (uc + usi >= ui) /* { dg-bogus "between signed and unsigned" } */ + foo (); + if (uc * usi >= ui) /* { dg-bogus "between signed and unsigned" } */ + foo (); +} + -- cgit v1.1 From 0b3560d3a9f2b55ba4807f2b0f8cbbf6cee9e6e3 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 30 Jul 2021 11:41:02 -0600 Subject: Move failed part of a test to a new file [PR101671] Related: PR middle-end/101671 - pr83510 fails with -Os because threader confuses -Warray-bounds gcc/testsuite: PR middle-end/101671 * gcc.c-torture/compile/pr83510.c: Move test functions... * gcc.dg/Warray-bounds-87.c: ...to this file. --- gcc/testsuite/gcc.dg/Warray-bounds-87.c | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-87.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-87.c b/gcc/testsuite/gcc.dg/Warray-bounds-87.c new file mode 100644 index 0000000..a49874d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-87.c @@ -0,0 +1,48 @@ +/* PR middle-end/101671 - pr83510 fails with -Os because threader confuses + -Warray-bounds + { dg-do compile } + { dg-options "-Os -Wall" } */ + +extern int f (void); +extern void sink (unsigned int); + +unsigned int a[10]; + +static unsigned int g (int i, int j) +{ + if (i == 9) + return j; + else if (i == 10) + return a[i]; // no warning here + return 0; +} + +void test_g (int j) +{ + for (int i = 0; i < 10; i++) + { + if (f ()) + sink (g (i, j)); + } +} + +static unsigned int h (int i, int j) +{ + switch (i) + { + case 9: + return j; + case 10: + return a[i]; // { dg-bogus "-Warray-bounds" "pr101671" { xfail *-*-* } } + } + return 0; +} + +void test_h (int j) +{ + for (int i = 0; i < 10; i++) + { + if (f ()) + sink (h (i, j)); + } +} -- cgit v1.1 From ebbcdd7fae1f802763850e4afedfdfa09cf10e1a Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 28 Jul 2021 13:14:22 -0400 Subject: Change integral divide by zero to produce UNDEFINED. Instead of VARYING, we can get better results by treating divide by zero as producing an undefined result. gcc/ * range-op.cc (operator_div::wi_fold): Return UNDEFINED for [0, 0] divisor. gcc/testsuite/ * gcc.dg/tree-ssa/pr61839_2.c: Adjust. --- gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c index cfec54d..f1b8feb 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c @@ -45,9 +45,8 @@ int bar2 () return 0; } - /* Dont optimize 972195717 / 0 in function foo. */ -/* { dg-final { scan-tree-dump-times "972195717 / " 1 "evrp" } } */ +/* { dg-final { scan-tree-dump-times "972195717 / " 0 "evrp" } } */ /* Dont optimize 972195717 % 0 in function bar. */ /* { dg-final { scan-tree-dump-times "972195717 % " 1 "evrp" } } */ /* May optimize in function bar2, but EVRP doesn't perform this yet. */ -- cgit v1.1 From 145bc41dae7c7bfa093d61e77346f98e6a595a0e Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 29 Jul 2021 11:22:28 -0400 Subject: Handle constants in wi_fold for trunc_mod. Handle const % const, as wi_fold_in_parts may now provide this. Before this [10, 10] % [4, 4] would produce [0, 3] instead of [2, 2]. gcc/ * range-op.cc (operator_trunc_mod::wi_fold): Fold constants. gcc/testsuite/ * gcc.dg/tree-ssa/pr61839_2.c: Adjust. Add new const fold test. --- gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c | 39 +++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c index f1b8feb..0e0f4c0 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c @@ -45,9 +45,40 @@ int bar2 () return 0; } -/* Dont optimize 972195717 / 0 in function foo. */ +/* Ensure we are folding modulus sub-ranges properly. */ +__attribute__ ((noinline)) +int mod (int a, int b) +{ + int v1, v2; + v1 = (a < 10) ? 12 : 24; + v2 = (b > 20) ? 3 : 6; + + if (a > 20) + v1 = v1 * 2; + if (b > 20) + v2 = v2 * 2; + + if (a == b) + v2 = 0; + + /* v1 == 12, 24, or 48. v2 == 0, 3, 6, or 12. */ + int c = v1 % v2; + if (c == 0) + ; + else + __builtin_abort (); + return 0; +} + +/* EVRP now makes transformations in all functions, leaving a single + * builtin_abort call in bar2. */ +/* { dg-final { scan-tree-dump-times "__builtin_abort" 1 "evrp" } } */ + +/* Make sure to optimize 972195717 / 0 in function foo. */ /* { dg-final { scan-tree-dump-times "972195717 / " 0 "evrp" } } */ -/* Dont optimize 972195717 % 0 in function bar. */ -/* { dg-final { scan-tree-dump-times "972195717 % " 1 "evrp" } } */ -/* May optimize in function bar2, but EVRP doesn't perform this yet. */ +/* Make sure to optimize 972195717 % 0 in function bar. */ +/* { dg-final { scan-tree-dump-times "972195717 % " 0 "evrp" } } */ +/* Make sure to optimize 972195717 % [1,2] function bar2. */ /* { dg-final { scan-tree-dump-times "972195715 % " 0 "evrp" } } */ +/* [12,12][24,24][48,48] % [0,0][3,3][6,6][12,12] == [0,0] */ +/* { dg-final { scan-tree-dump-times "%" 0 "evrp" } } */ -- cgit v1.1 From 309ddde04f2335f51062690328f03ce889be7e22 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Sat, 31 Jul 2021 01:23:20 +0200 Subject: gcc.dg/uninit-pred-9_b.c: Xfail for MMIX too Looks like MMIX is the "correct target" too (cf. 2f6bdd51cfe15) and from https://gcc.gnu.org/pipermail/gcc-testresults/2021-July/710188.html it seems powerpc-ibm-aix7.2.3.0 is too, but I've not found other targets failing. gcc/testsuite: PR middle-end/101674 * gcc.dg/uninit-pred-9_b.c: Xfail for mmix-*-* too. --- gcc/testsuite/gcc.dg/uninit-pred-9_b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c index e0dc214..9383c55 100644 --- a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c +++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c @@ -20,7 +20,7 @@ int foo (int n, int l, int m, int r) blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ if ( (n <= 8) && (m < 99) && (r < 19) ) - blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail powerpc64*-*-* } } */ + blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail powerpc64*-*-* mmix-*-* } } */ return 0; } -- cgit v1.1 From cfd60b39cdc576177c4a327897be55f3bf3f449e Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Sat, 31 Jul 2021 02:08:36 +0200 Subject: gcc.dg/tree-ssa/ssa-dse-26.c: Skip on mmix-knuth-mmixware Commit r12-432, rewriting the dg-stuff, reverted the adjustment for mmix-knuth-mmixware that I added in r11-2335. (See those commits for context.) Hopefully this variant will age better, just skipping it with a trivial extra line less prone to pile-on. (Not much is won by covering this generic case for MMIX too; might as well skip it.) Beware that the dg-skip-if text can't say "temporary variables are not x and y but x::3 and y::4" because that leads to (on one line): ERROR: gcc.dg/tree-ssa/ssa-dse-26.c: can't set "{temporary variables are not x and y but x::3 and y::4} { mmix-knuth-mmixware }": parent namespace doesn't exist for " dg-skip-if 4 "temporary variables are not x and y but x::3 and y::4" { mmix-knuth-mmixware } " gcc/testsuite: * gcc.dg/tree-ssa/ssa-dse-26.c: Skip on mmix-knuth-mmixware. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index 5eabfb4..e3c33f49 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-dse1-details -fno-short-enums -fno-tree-fre" } */ /* { dg-skip-if "we want a BIT_FIELD_REF from fold_truth_andor" { ! lp64 } } */ +/* { dg-skip-if "temporary variable names are not x and y" { mmix-knuth-mmixware } } */ enum constraint_expr_type { -- cgit v1.1 From f9fcf754825a1e01033336f84c18690aaa971a6f Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 2 Aug 2021 13:27:53 +0100 Subject: Optimize x ? bswap(x) : 0 in tree-ssa-phiopt Many thanks again to Jakub Jelinek for a speedy fix for PR 101642. Interestingly, that test case "bswap16(x) ? : x" also reveals a missed optimization opportunity. The resulting "x ? bswap(x) : 0" can be further simplified to just bswap(x). Conveniently, tree-ssa-phiopt.c already recognizes/optimizes the related "x ? popcount(x) : 0", so this patch simply makes that transformation make general, additionally handling bswap, parity, ffs and clrsb. All of the required infrastructure is already present thanks to Jakub previously adding support for clz/ctz. To reflect this generalization, the name of the function is changed from cond_removal_in_popcount_clz_ctz_pattern to the hopefully equally descriptive cond_removal_in_builtin_zero_pattern. 2021-08-02 Roger Sayle gcc/ChangeLog * tree-ssa-phiopt.c (cond_removal_in_builtin_zero_pattern): Renamed from cond_removal_in_popcount_clz_ctz_pattern. Add support for BSWAP, FFS, PARITY and CLRSB builtins. (tree_ssa_phiop_worker): Update call to function above. gcc/testsuite/ChangeLog * gcc.dg/tree-ssa/phi-opt-25.c: New test case. --- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c | 83 ++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c new file mode 100644 index 0000000..c52c92e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +unsigned short test_bswap16(unsigned short x) +{ + return x ? __builtin_bswap16(x) : 0; +} + +unsigned int test_bswap32(unsigned int x) +{ + return x ? __builtin_bswap32(x) : 0; +} + +unsigned long long test_bswap64(unsigned long long x) +{ + return x ? __builtin_bswap64(x) : 0; +} + +int test_clrsb(int x) +{ + return x ? __builtin_clrsb(x) : (__SIZEOF_INT__*8-1); +} + +int test_clrsbl(long x) +{ + return x ? __builtin_clrsbl(x) : (__SIZEOF_LONG__*8-1); +} + +int test_clrsbll(long long x) +{ + return x ? __builtin_clrsbll(x) : (__SIZEOF_LONG_LONG__*8-1); +} + +#if 0 +/* BUILT_IN_FFS is transformed by match.pd */ +int test_ffs(unsigned int x) +{ + return x ? __builtin_ffs(x) : 0; +} + +int test_ffsl(unsigned long x) +{ + return x ? __builtin_ffsl(x) : 0; +} + +int test_ffsll(unsigned long long x) +{ + return x ? __builtin_ffsll(x) : 0; +} +#endif + +int test_parity(int x) +{ + return x ? __builtin_parity(x) : 0; +} + +int test_parityl(long x) +{ + return x ? __builtin_parityl(x) : 0; +} + +int test_parityll(long long x) +{ + return x ? __builtin_parityll(x) : 0; +} + +int test_popcount(int x) +{ + return x ? __builtin_popcount(x) : 0; +} + +int test_popcountl(long x) +{ + return x ? __builtin_popcountl(x) : 0; +} + +int test_popcountll(long long x) +{ + return x ? __builtin_popcountll(x) : 0; +} + +/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */ + -- cgit v1.1 From 1a830c0636472e47a7503a5ed879725149e2e728 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 3 Aug 2021 12:44:17 +0200 Subject: analyzer: Fix ICE on MD builtin [PR101721] The following testcase ICEs because DECL_FUNCTION_CODE asserts the builtin is BUILT_IN_NORMAL, but it sees a backend (MD) builtin instead. The FE, normal and MD builtin numbers overlap, so one should always check what kind of builtin it is before looking at specific codes. On the other side, region-model.cc has: if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL) && gimple_builtin_call_types_compatible_p (call, callee_fndecl)) switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl)) which IMO should use DECL_FUNCTION_CODE instead, it checked first it is a normal builtin... 2021-08-03 Jakub Jelinek PR analyzer/101721 * sm-malloc.cc (known_allocator_p): Only check DECL_FUNCTION_CODE on BUILT_IN_NORMAL builtins. * gcc.dg/analyzer/pr101721.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr101721.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101721.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101721.c b/gcc/testsuite/gcc.dg/analyzer/pr101721.c new file mode 100644 index 0000000..07ef2d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101721.c @@ -0,0 +1,8 @@ +/* PR analyzer/101721 */ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ + +void +foo () +{ + __builtin_ia32_pause (); +} -- cgit v1.1 From f9ad3d5339faaaed6e15a7b27d90fbc66eb72f37 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Mon, 2 Aug 2021 17:12:04 -0700 Subject: Fixes for AutoFDO tests * Changed several tests to use -fdump-ipa-afdo-optimized instead of -fdump-ipa-afdo in dg-options so that the expected output can be found * Increased the number of iterations in several tests so that perf can have enough sampling events Contributes to fixing PR gcov-profile/71672. gcc/testsuite/ChangeLog: * g++.dg/tree-prof/indir-call-prof.C: Fix options, increase the number of iterations. * g++.dg/tree-prof/morefunc.C: Fix options, increase the number of iterations. * g++.dg/tree-prof/reorder.C: Fix options, increase the number of iterations. * gcc.dg/tree-prof/indir-call-prof-2.c: Fix options, increase the number of iterations. * gcc.dg/tree-prof/indir-call-prof.c: Fix options. --- gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c index bbba052..2585326 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c @@ -22,7 +22,7 @@ int main (void) { int i, val = 0; - for (i = 0; i < 100000; i++) + for (i = 0; i < 10000000; i++) { val = do_op (val, add1); val = do_op (val, sub1); diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c index 138b85a..7020452 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c +++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized -fdump-ipa-afdo" } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized -fdump-ipa-afdo-optimized" } */ static int a1 (void) { -- cgit v1.1 From 0ed093c7c3f755bc1cd80e5186abeb2f5c50ee0c Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Mon, 2 Aug 2021 17:22:34 -0700 Subject: Fix indir-call-prof-2.c with AutoFDO indir-call-prof-2.c has -fno-early-inlining but AutoFDO can't work without early inlining (it needs to match the inlining of the profiled binary). I changed profopt.exp to always pass -fearly-inlining for AutoFDO. With that change the indirect call inlining in indir-call-prof-2.c happens in the early inliner so I changed the dg-final-use-autofdo. Contributes to fixing PR gcov-profile/71672 gcc/testsuite/ChangeLog: * gcc.dg/tree-prof/indir-call-prof-2.c: Fix dg-final-use-autofdo. * lib/profopt.exp: Pass -fearly-inlining when compiling with AutoFDO. --- gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c index 2585326..594c3f3 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fno-early-inlining -fdump-ipa-profile-optimized -fdump-ipa-afdo" } */ +/* { dg-options "-O2 -fno-early-inlining -fdump-ipa-profile-optimized -fdump-tree-einline-optimized" } */ volatile int one; static int add1 (int val) @@ -31,5 +31,5 @@ main (void) } /* { dg-final-use-not-autofdo { scan-ipa-dump "Indirect call -> direct call.* add1 .will resolve by ipa-profile" "profile"} } */ /* { dg-final-use-not-autofdo { scan-ipa-dump "Indirect call -> direct call.* sub1 .will resolve by ipa-profile" "profile"} } */ -/* { dg-final-use-autofdo { scan-ipa-dump "Indirect call -> direct call.* add1 .will resolve by ipa-profile" "afdo"} } */ -/* { dg-final-use-autofdo { scan-ipa-dump "Indirect call -> direct call.* sub1 .will resolve by ipa-profile" "afdo"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Inlining add1/1 into main/4." "einline"} } */ +/* { dg-final-use-autofdo { scan-tree-dump "Inlining sub1/2 into main/4." "einline"} } */ -- cgit v1.1 From 87a0b607e40f8122c7fc45d496ef48799fe11550 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 4 Aug 2021 11:42:41 +0200 Subject: tree-optimization/101756 - avoid vectorizing boolean MAX reductions The following avoids vectorizing MIN/MAX reductions on bools which, when ending up as vector(2) would need to be adjusted because of the sign change. The fix instead avoids any reduction vectorization where the result isn't compatible to the original scalar type since we don't compensate for that either. 2021-08-04 Richard Biener PR tree-optimization/101756 * tree-vect-slp.c (vectorizable_bb_reduc_epilogue): Make sure the result of the reduction epilogue is compatible to the original scalar result. * gcc.dg/vect/bb-slp-pr101756.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c new file mode 100644 index 0000000..9420e77 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +__attribute__ ((simd)) int +tq (long int ea, int of, int kk) +{ + int bc; + + for (bc = 0; bc < 2; ++bc) + { + ++ea; + of |= !!kk < !!ea; + } + + return of; +} -- cgit v1.1 From 96146e61cd7aee62c21c2845916ec42152918ab7 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 4 Aug 2021 14:19:14 +0100 Subject: Fold (X< Marc Glisse gcc/ChangeLog * match.pd (bit_ior, bit_xor): Canonicalize (X*C1)|(X*C2) and (X*C1)^(X*C2) as X*(C1+C2), and related variants, using tree_nonzero_bits to ensure that operands are bit-wise disjoint. gcc/testsuite/ChangeLog * gcc.dg/fold-ior-4.c: New test. --- gcc/testsuite/gcc.dg/fold-ior-4.c | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-ior-4.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/fold-ior-4.c b/gcc/testsuite/gcc.dg/fold-ior-4.c new file mode 100644 index 0000000..8f7213e --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-ior-4.c @@ -0,0 +1,61 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +unsigned int test_ior(unsigned char i) +{ + return i | (i<<8) | (i<<16) | (i<<24); +} + +unsigned int test_xor(unsigned char i) +{ + return i ^ (i<<8) ^ (i<<16) ^ (i<<24); +} + +unsigned int test_ior_1s(unsigned char i) +{ + return i | (i<<8); +} + +unsigned int test_ior_1u(unsigned char i) +{ + unsigned int t = i; + return t | (t<<8); +} + +unsigned int test_xor_1s(unsigned char i) +{ + return i ^ (i<<8); +} + +unsigned int test_xor_1u(unsigned char i) +{ + unsigned int t = i; + return t ^ (t<<8); +} + +unsigned int test_ior_2s(unsigned char i) +{ + return (i<<8) | (i<<16); +} + +unsigned int test_ior_2u(unsigned char i) +{ + unsigned int t = i; + return (t<<8) | (t<<16); +} + +unsigned int test_xor_2s(unsigned char i) +{ + return (i<<8) ^ (i<<16); +} + +unsigned int test_xor_2u(unsigned char i) +{ + unsigned int t = i; + return (t<<8) ^ (t<<16); +} + +/* { dg-final { scan-tree-dump-not " \\^ " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \\* 16843009" 2 "optimized" } } */ + -- cgit v1.1 From ded2c2c068f6f2825474758cb03a05070a5837e8 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 4 Aug 2021 18:21:21 -0400 Subject: analyzer: initial implementation of asm support [PR101570] gcc/ChangeLog: PR analyzer/101570 * Makefile.in (ANALYZER_OBJS): Add analyzer/region-model-asm.o. gcc/analyzer/ChangeLog: PR analyzer/101570 * analyzer.cc (maybe_reconstruct_from_def_stmt): Add GIMPLE_ASM case. * analyzer.h (class asm_output_svalue): New forward decl. (class reachable_regions): New forward decl. * complexity.cc (complexity::from_vec_svalue): New. * complexity.h (complexity::from_vec_svalue): New decl. * engine.cc (feasibility_state::maybe_update_for_edge): Handle asm stmts by calling on_asm_stmt. * region-model-asm.cc: New file. * region-model-manager.cc (region_model_manager::maybe_fold_asm_output_svalue): New. (region_model_manager::get_or_create_asm_output_svalue): New. (region_model_manager::log_stats): Log m_asm_output_values_map. * region-model.cc (region_model::on_stmt_pre): Handle GIMPLE_ASM. * region-model.h (visitor::visit_asm_output_svalue): New. (region_model_manager::get_or_create_asm_output_svalue): New decl. (region_model_manager::maybe_fold_asm_output_svalue): New decl. (region_model_manager::asm_output_values_map_t): New typedef. (region_model_manager::m_asm_output_values_map): New field. (region_model::on_asm_stmt): New. * store.cc (binding_cluster::on_asm): New. * store.h (binding_cluster::on_asm): New decl. * svalue.cc (svalue::cmp_ptr): Handle SK_ASM_OUTPUT. (asm_output_svalue::dump_to_pp): New. (asm_output_svalue::dump_input): New. (asm_output_svalue::input_idx_to_asm_idx): New. (asm_output_svalue::accept): New. * svalue.h (enum svalue_kind): Add SK_ASM_OUTPUT. (svalue::dyn_cast_asm_output_svalue): New. (class asm_output_svalue): New. (is_a_helper ::test): New. (struct default_hash_traits): New. gcc/testsuite/ChangeLog: PR analyzer/101570 * gcc.dg/analyzer/asm-x86-1.c: New test. * gcc.dg/analyzer/asm-x86-lp64-1.c: New test. * gcc.dg/analyzer/asm-x86-lp64-2.c: New test. * gcc.dg/analyzer/pr101570.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c: New test. * gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c: New test. Signed-off-by: David Malcolm --- gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c | 69 +++++ gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-1.c | 131 +++++++++ gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c | 34 +++ gcc/testsuite/gcc.dg/analyzer/pr101570.c | 5 + .../asm-x86-linux-array_index_mask_nospec.c | 74 +++++ .../torture/asm-x86-linux-cpuid-paravirt-1.c | 81 ++++++ .../torture/asm-x86-linux-cpuid-paravirt-2.c | 135 +++++++++ .../gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c | 46 +++ .../torture/asm-x86-linux-rdmsr-paravirt.c | 210 ++++++++++++++ .../gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c | 33 +++ .../asm-x86-linux-wfx_get_ps_timeout-full.c | 319 +++++++++++++++++++++ .../asm-x86-linux-wfx_get_ps_timeout-reduced.c | 77 +++++ 12 files changed, 1214 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101570.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c new file mode 100644 index 0000000..f6026b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/asm-x86-1.c @@ -0,0 +1,69 @@ +/* { dg-do assemble { target x86_64-*-* } } */ + +#include "analyzer-decls.h" + +int test_out (void) +{ + int dst_a, dst_b; + asm ("mov 42, %0" + : "=r" (dst_a)); + asm ("mov 42, %0" + : "=r" (dst_b)); + __analyzer_eval (dst_a == dst_b); /* { dg-warning "TRUE" } */ + return dst_a; +} + +int test_out_in (int src_a) +{ + int dst_a, dst_b; + asm ("mov %1, %0" + : "=r" (dst_a) + : "r" (src_a)); + asm ("mov %1, %0" + : "=r" (dst_b) + : "r" (src_a)); + __analyzer_eval (dst_a == dst_b); /* { dg-warning "TRUE" } */ + return dst_a; +} + +int test_out_in_in (int src_a, int src_b) +{ + int dst_a, dst_b; + asm ("mov %1, %0;\n" + "add %2, %0" + : "=r" (dst_a) + : "r" (src_a), + "r" (src_b)); + asm ("mov %1, %0;\n" + "add %2, %0" + : "=r" (dst_b) + : "r" (src_a), + "r" (src_b)); + __analyzer_eval (dst_a == dst_b); /* { dg-warning "TRUE" } */ + return dst_a; +} + +void test_inout_1 (int v) +{ + int saved = v; + int result_a, result_b; + asm ("dec %0" + : "+r" (v)); + result_a = v; + + asm ("dec %0" + : "+r" (v)); + result_b = v; + + __analyzer_eval (v == saved); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (v == result_a); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (v == result_b); /* { dg-warning "TRUE" } */ +} + +void test_inout_2 (void) +{ + int v; + int result_a, result_b; + asm ("dec %0" /* { dg-warning "use of uninitialized value 'v'" } */ + : "+r" (v)); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-1.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-1.c new file mode 100644 index 0000000..c235e22 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-1.c @@ -0,0 +1,131 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ + +#include "analyzer-decls.h" + +#include + +int test_1 (int src) +{ + int dst; + asm ("mov %1, %0\n\t" + "add $1, %0" + : "=r" (dst) + : "r" (src)); + return dst; +} + +uint32_t test_2 (uint32_t Mask) +{ + uint32_t Index; + asm ("bsfl %[aMask], %[aIndex]" + : [aIndex] "=r" (Index) + : [aMask] "r" (Mask) + : "cc"); + return Index; +} + +int test_3a (int p1, int p2) +{ + asm goto ("btl %1, %0\n\t" + "jc %l2" + : // No outputs + : "r" (p1), "r" (p2) + : "cc" + : carry); + + return 0; + + carry: + return 1; +} + +int test_3b (int p1, int p2) +{ + asm goto ("btl %1, %0\n\t" + "jc %l[carry]" + : // No outputs + : "r" (p1), "r" (p2) + : "cc" + : carry); + + return 0; + + carry: + return 1; +} + +uint64_t test_4 (void) +{ + uint64_t start_time, end_time; + + // Get start time + asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX. + "shl $32, %%rdx\n\t" // Shift the upper bits left. + "or %%rdx, %0" // 'Or' in the lower bits. + : "=a" (start_time) + : + : "rdx"); + + // could do other work here + + // Get end time + asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX. + "shl $32, %%rdx\n\t" // Shift the upper bits left. + "or %%rdx, %0" // 'Or' in the lower bits. + : "=a" (end_time) + : + : "rdx"); + + __analyzer_eval (start_time == end_time); /* { dg-warning "UNKNOWN" } */ + + // Get elapsed time + return end_time - start_time; +} + +static uint64_t get_time (void) +{ + uint64_t result; + asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX. + "shl $32, %%rdx\n\t" // Shift the upper bits left. + "or %%rdx, %0" // 'Or' in the lower bits. + : "=a" (result) + : + : "rdx"); + return result; +} + +uint64_t test_4a (void) +{ + uint64_t start_time, end_time; + + start_time = get_time (); + // could do other work here + end_time = get_time (); + + __analyzer_eval (start_time == end_time); /* { dg-warning "UNKNOWN" } */ + + // Get elapsed time + return end_time - start_time; +} + +asm ("\t.pushsection .text\n" + "\t.globl add_asm\n" + "\t.type add_asm, @function\n" + "add_asm:\n" + "\tmovq %rdi, %rax\n" + "\tadd %rsi, %rax\n" + "\tret\n" + "\t.popsection\n"); + +int test_5 (int count) +{ + asm goto ("dec %0; jb %l[stop]" + : "+r" (count) + : + : + : stop); + return count; +stop: + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c new file mode 100644 index 0000000..fa50739 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c @@ -0,0 +1,34 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ + +/* Adapted from Linux x86: page_ref_dec_and_test.c (GPL-2.0). */ + +typedef _Bool bool; + +typedef struct { + int counter; +} atomic_t; + +bool +arch_atomic_dec_and_test(atomic_t *v) { + return ({ + bool c; + asm volatile(".pushsection .smp_locks,\"a\"\n" + ".balign 4\n" + ".long 671f - .\n" + ".popsection\n" + "671:" + "\n\tlock; " + "decl" + " " + "%[var]" + "\n\t/* output condition code " + "e" + "*/\n" + : [ var ] "+m"(v->counter), "=@cc" + "e"(c) + : + : "memory"); + c; + }); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101570.c b/gcc/testsuite/gcc.dg/analyzer/pr101570.c new file mode 100644 index 0000000..809bad6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101570.c @@ -0,0 +1,5 @@ +void +test2 (_Complex double f) +{ + __asm__ ("" : "=r" (__real f)); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c new file mode 100644 index 0000000..6201fdb --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c @@ -0,0 +1,74 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#include "../analyzer-decls.h" + +/* Copied from linux: arch/x86/include/asm/barrier.h (GPL-2.0) */ + +static inline unsigned long array_index_mask_nospec(unsigned long index, + unsigned long size) +{ + unsigned long mask; + + asm volatile ("cmp %1,%2; sbb %0,%0;" + :"=r" (mask) + :"g"(size),"r" (index) + :"cc"); + return mask; +} + +/* The analyzer ought to treat array_index_mask_nospec as being + effectively pure. */ + +void test_1 (unsigned long index, unsigned long size) +{ + unsigned long a = array_index_mask_nospec (index, size); + unsigned long b = array_index_mask_nospec (index, size); + __analyzer_eval (a == b); /* { dg-warning "TRUE" } */ +} + +void test_2 (unsigned long index_a, unsigned long size_a, + unsigned long index_b, unsigned long size_b) +{ + unsigned long aa_1 = array_index_mask_nospec (index_a, size_a); + unsigned long ab_1 = array_index_mask_nospec (index_a, size_b); + unsigned long ba_1 = array_index_mask_nospec (index_b, size_a); + unsigned long bb_1 = array_index_mask_nospec (index_b, size_b); + + unsigned long aa_2 = array_index_mask_nospec (index_a, size_a); + unsigned long ab_2 = array_index_mask_nospec (index_a, size_b); + unsigned long ba_2 = array_index_mask_nospec (index_b, size_a); + unsigned long bb_2 = array_index_mask_nospec (index_b, size_b); + + __analyzer_eval (aa_1 == aa_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (ab_1 == ab_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (ba_1 == ba_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (bb_1 == bb_2); /* { dg-warning "TRUE" } */ + + __analyzer_eval (aa_1 == ab_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (aa_1 == ba_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (aa_1 == bb_1); /* { dg-warning "UNKNOWN" } */ + + __analyzer_eval (ab_1 == ba_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (ab_1 == bb_1); /* { dg-warning "UNKNOWN" } */ + + __analyzer_eval (ba_1 == bb_1); /* { dg-warning "UNKNOWN" } */ +} + +/* Equivalent asm strings should be treated the same, rather + than requiring the results to come from the same stmt. */ + +void test_3 (unsigned long index, unsigned long size) +{ + unsigned long a = array_index_mask_nospec (index, size); + unsigned long b; + + /* Copy of the asm from array_index_mask_nospec. */ + asm volatile ("cmp %1,%2; sbb %0,%0;" + :"=r" (b) + :"g"(size),"r" (index) + :"cc"); + + __analyzer_eval (a == b); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c new file mode 100644 index 0000000..cf5cf97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c @@ -0,0 +1,81 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +/* Adapted/reduced from linux kernel (GPL-2.0). */ + +register unsigned long current_stack_pointer asm("rsp"); + +struct pv_cpu_ops { + /* snip */ + void (*cpuid)(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx); + /* snip */ +}; +struct paravirt_patch_template { + struct pv_cpu_ops cpu; + /* snip */ +}; +extern struct paravirt_patch_template pv_ops; + +/* snip */ +static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx) { + unsigned long __edi = __edi, __esi = __esi, __edx = __edx, __ecx = __ecx, + __eax = __eax; + asm volatile( + "771:\n\t" + "999:\n\t" + ".pushsection .discard.retpoline_safe\n\t" + " " + ".quad" + " " + " 999b\n\t" + ".popsection\n\t" + "call *%c[paravirt_opptr];" + "\n" + "772:\n" + ".pushsection .parainstructions,\"a\"\n" + " " + ".balign 8" + " " + "\n" + " " + ".quad" + " " + " 771b\n" + " .byte " + "%c[paravirt_typenum]" + "\n" + " .byte 772b-771b\n" + " .short " + "%c[paravirt_clobber]" + "\n" + ".popsection\n" + : "=D"(__edi), "=S"(__esi), "=d"(__edx), "=c"(__ecx), + "+r"(current_stack_pointer) + : [ paravirt_typenum ] "i"( + (__builtin_offsetof(struct paravirt_patch_template, cpu.cpuid) / + sizeof(void *))), + [ paravirt_opptr ] "i"(&(pv_ops.cpu.cpuid)), + [ paravirt_clobber ] "i"(((1 << 9) - 1)), "D"((unsigned long)(eax)), + "S"((unsigned long)(ebx)), "d"((unsigned long)(ecx)), + "c"((unsigned long)(edx)) + : "memory", "cc", "rax", "r8", "r9", "r10", "r11"); +} + +extern void check_init_int(int v); + +void test(unsigned int op) { + unsigned int eax, ebx, ecx, edx; + + eax = op; + ecx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + + check_init_int(eax); + check_init_int(ebx); /* { dg-bogus "use of uninitialized value 'ebx'" } */ + check_init_int(ecx); + check_init_int(edx); /* { dg-bogus "use of uninitialized value 'edx'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c new file mode 100644 index 0000000..c4b365f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c @@ -0,0 +1,135 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +/* Adapted/reduced from linux kernel (GPL-2.0). */ + +typedef __SIZE_TYPE__ size_t; + +#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER) + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) +#define __ASM_FORM(x, ...) " " __stringify(x,##__VA_ARGS__) " " +#define __ASM_FORM_RAW(x, ...) __stringify(x,##__VA_ARGS__) +#define __ASM_SEL(a,b) __ASM_FORM(b) +#define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b) +#define __ASM_REG(reg) __ASM_SEL_RAW(e##reg, r##reg) +#define _ASM_PTR __ASM_SEL(.long, .quad) +#define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8) +#define _ASM_SP __ASM_REG(sp) + + +register unsigned long current_stack_pointer asm(_ASM_SP); +#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) + +#define ANNOTATE_RETPOLINE_SAFE \ + "999:\n\t" \ + ".pushsection .discard.retpoline_safe\n\t" \ + _ASM_PTR " 999b\n\t" \ + ".popsection\n\t" + +/* Adapted from Linux arch/x86/include/asm/paravirt.h */ + +struct pv_cpu_ops { + /* snip */ + void (*cpuid)(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx); + /* snip */ +}; + +struct paravirt_patch_template { + struct pv_cpu_ops cpu; + /* snip */ +}; +extern struct paravirt_patch_template pv_ops; + +#define PARAVIRT_PATCH(x) \ + (offsetof(struct paravirt_patch_template, x) / sizeof(void *)) + +#define paravirt_type(op) \ + [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ + [paravirt_opptr] "i" (&(pv_ops.op)) +#define paravirt_clobber(clobber) \ + [paravirt_clobber] "i" (clobber) + +#define CLBR_ANY ((1 << 9) - 1) + +#define _paravirt_alt(insn_string, type, clobber) \ + "771:\n\t" insn_string "\n" "772:\n" \ + ".pushsection .parainstructions,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR " 771b\n" \ + " .byte " type "\n" \ + " .byte 772b-771b\n" \ + " .short " clobber "\n" \ + ".popsection\n" + +#define paravirt_alt(insn_string) \ + _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") + +#define PARAVIRT_CALL \ + ANNOTATE_RETPOLINE_SAFE \ + "call *%c[paravirt_opptr];" + +#define PVOP_CALL_ARGS \ + unsigned long __edi = __edi, __esi = __esi, \ + __edx = __edx, __ecx = __ecx, __eax = __eax; + +#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) +#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x)) +#define PVOP_CALL_ARG3(x) "d" ((unsigned long)(x)) +#define PVOP_CALL_ARG4(x) "c" ((unsigned long)(x)) + +#define PVOP_VCALL_CLOBBERS "=D" (__edi), \ + "=S" (__esi), "=d" (__edx), \ + "=c" (__ecx) +/* void functions are still allowed [re]ax for scratch */ +#define PVOP_VCALLEE_CLOBBERS "=a" (__eax) + +#define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" + +#define PVOP_TEST_NULL(op) ((void)pv_ops.op) + +#define ____PVOP_CALL(ret, op, clbr, call_clbr, extra_clbr, ...) \ + ({ \ + PVOP_CALL_ARGS; \ + PVOP_TEST_NULL(op); \ + asm volatile(paravirt_alt(PARAVIRT_CALL) \ + : call_clbr, ASM_CALL_CONSTRAINT \ + : paravirt_type(op), \ + paravirt_clobber(clbr), \ + ##__VA_ARGS__ \ + : "memory", "cc" extra_clbr); \ + ret; \ + }) + +#define __PVOP_VCALL(op, ...) \ + (void)____PVOP_CALL(, op, CLBR_ANY, PVOP_VCALL_CLOBBERS, \ + VEXTRA_CLOBBERS, ##__VA_ARGS__) + +#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ + __PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ + PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) + +static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx) +{ + PVOP_VCALL4(cpu.cpuid, eax, ebx, ecx, edx); +} + +extern void check_init_int(int v); + +void test(unsigned int op) { + unsigned int eax, ebx, ecx, edx; + + eax = op; + ecx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + + check_init_int(eax); + check_init_int(ebx); /* { dg-bogus "use of uninitialized value 'ebx'" } */ + check_init_int(ecx); + check_init_int(edx); /* { dg-bogus "use of uninitialized value 'edx'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c new file mode 100644 index 0000000..243931a --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c @@ -0,0 +1,46 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ + +#include "../analyzer-decls.h" + +typedef unsigned __INT32_TYPE__ u32; +typedef unsigned __INT64_TYPE__ u64; + +extern void check_init_u32 (u32 v); +extern void check_init_u64 (u32 v); + +/* Adapted from linux kernel: arch/x86/include/asm/processor.h (GPL-2.0). */ + +static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + /* ecx is often an input as well as an output. */ + asm volatile("cpuid" + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), + "=d" (*edx) + : "0" (*eax), "2" (*ecx) + : "memory"); +} + +static inline void cpuid(unsigned int op, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + *eax = op; + *ecx = 0; + native_cpuid(eax, ebx, ecx, edx); +} + +void test_1 (void) +{ + u32 eax, ebx, ecx, edx; + cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); /* from "amd_get_topology". */ + + /* Verify that they are now initialized. */ + check_init_u32 (eax); + check_init_u32 (ebx); + check_init_u32 (ecx); + check_init_u32 (edx); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c new file mode 100644 index 0000000..d994787 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c @@ -0,0 +1,210 @@ +/* Adapted from Linux: arch/x86/include/asm/paravirt.h */ + +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +/* Adapted/reduced from linux kernel (GPL-2.0). */ + +#include "../analyzer-decls.h" + +typedef unsigned char u8; +typedef unsigned __INT32_TYPE__ u32; +typedef unsigned __INT64_TYPE__ u64; +typedef __SIZE_TYPE__ size_t; + +#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER) + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +# define __ASM_FORM(x, ...) " " __stringify(x,##__VA_ARGS__) " " +# define __ASM_FORM_RAW(x, ...) __stringify(x,##__VA_ARGS__) + +#ifndef __x86_64__ +/* 32 bit */ +# define __ASM_SEL(a,b) __ASM_FORM(a) +# define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(a) +#else +/* 64 bit */ +# define __ASM_SEL(a,b) __ASM_FORM(b) +# define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b) +#endif + +#define __ASM_REG(reg) __ASM_SEL_RAW(e##reg, r##reg) + +#define _ASM_PTR __ASM_SEL(.long, .quad) +#define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8) + +#define _ASM_SP __ASM_REG(sp) + + +register unsigned long current_stack_pointer asm(_ASM_SP); +#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) + +#define ANNOTATE_RETPOLINE_SAFE \ + "999:\n\t" \ + ".pushsection .discard.retpoline_safe\n\t" \ + _ASM_PTR " 999b\n\t" \ + ".popsection\n\t" + +/* Adapted from Linux arch/x86/include/asm/paravirt.h */ + + +/* snip */ + +/* ./arch/x86/include/asm/paravirt.h I think; was: + PVOP_VCALL4(cpu.cpuid, eax, ebx, ecx, edx); + +*/ + +#ifndef __x86_64__ +#define CLBR_ANY ((1 << 4) - 1) +#else +#define CLBR_ANY ((1 << 9) - 1) +#endif /* X86_64 */ + +struct pv_cpu_ops { + /* snip */ + u64 (*read_msr_safe)(unsigned int msr, int *err); + /* snip */ +}; + +struct paravirt_patch_template { + struct pv_cpu_ops cpu; + /* snip */ +}; +extern struct paravirt_patch_template pv_ops; + +#define PARAVIRT_PATCH(x) \ + (offsetof(struct paravirt_patch_template, x) / sizeof(void *)) + +#define paravirt_type(op) \ + [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ + [paravirt_opptr] "i" (&(pv_ops.op)) +#define paravirt_clobber(clobber) \ + [paravirt_clobber] "i" (clobber) + +/* + * Generate some code, and mark it as patchable by the + * apply_paravirt() alternate instruction patcher. + */ +#define _paravirt_alt(insn_string, type, clobber) \ + "771:\n\t" insn_string "\n" "772:\n" \ + ".pushsection .parainstructions,\"a\"\n" \ + _ASM_ALIGN "\n" \ + _ASM_PTR " 771b\n" \ + " .byte " type "\n" \ + " .byte 772b-771b\n" \ + " .short " clobber "\n" \ + ".popsection\n" + +/* Generate patchable code, with the default asm parameters. */ +#define paravirt_alt(insn_string) \ + _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") + +#define PARAVIRT_CALL \ + ANNOTATE_RETPOLINE_SAFE \ + "call *%c[paravirt_opptr];" + +#ifndef __x86_64__ + +/* 32-bit. */ + +#define PVOP_CALL_ARGS \ + unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; + +#define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) +#define PVOP_CALL_ARG2(x) "d" ((unsigned long)(x)) + +#define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \ + "=c" (__ecx) +#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS + +#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx) +#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS + +#define EXTRA_CLOBBERS + +#else + +/* 64-bit. */ + +/* [re]ax isn't an arg, but the return val */ +#define PVOP_CALL_ARGS \ + unsigned long __edi = __edi, __esi = __esi, \ + __edx = __edx, __ecx = __ecx, __eax = __eax; + +#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) +#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x)) + +#define PVOP_VCALL_CLOBBERS "=D" (__edi), \ + "=S" (__esi), "=d" (__edx), \ + "=c" (__ecx) +#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) +#define PVOP_VCALLEE_CLOBBERS "=a" (__eax) +#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS + +#define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11" +#endif /* CONFIG_X86_32 */ + +#define PVOP_TEST_NULL(op) ((void)pv_ops.op) + +#define PVOP_RETVAL(rettype) \ + ({ unsigned long __mask = ~0UL; \ + switch (sizeof(rettype)) { \ + case 1: __mask = 0xffUL; break; \ + case 2: __mask = 0xffffUL; break; \ + case 4: __mask = 0xffffffffUL; break; \ + default: break; \ + } \ + __mask & __eax; \ + }) + +#define ____PVOP_CALL(ret, op, clbr, call_clbr, extra_clbr, ...) \ + ({ \ + PVOP_CALL_ARGS; \ + PVOP_TEST_NULL(op); \ + asm volatile(paravirt_alt(PARAVIRT_CALL) \ + : call_clbr, ASM_CALL_CONSTRAINT \ + : paravirt_type(op), \ + paravirt_clobber(clbr), \ + ##__VA_ARGS__ \ + : "memory", "cc" extra_clbr); \ + ret; \ + }) + +#define __PVOP_CALL(rettype, op, ...) \ + ____PVOP_CALL(PVOP_RETVAL(rettype), op, CLBR_ANY, \ + PVOP_CALL_CLOBBERS, EXTRA_CLOBBERS, ##__VA_ARGS__) + +#define PVOP_CALL2(rettype, op, arg1, arg2) \ + __PVOP_CALL(rettype, op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2)) + +static inline u64 paravirt_read_msr_safe(unsigned msr, int *err) +{ + return PVOP_CALL2(u64, cpu.read_msr_safe, msr, err); +} + +#define rdmsr_safe(msr, a, b) \ +({ \ + int _err; \ + u64 _l = paravirt_read_msr_safe(msr, &_err); \ + (*a) = (u32)_l; \ + (*b) = _l >> 32; \ + _err; \ +}) + + +void check_init_int(int); +void check_init_u32(u32); + +void test(void) +{ + int err; + u32 eax, edx; + err = rdmsr_safe(0, &eax, &edx); + check_init_int(err); + check_init_u32(eax); + check_init_u32(edx); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c new file mode 100644 index 0000000..0a1c48f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c @@ -0,0 +1,33 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#include "../analyzer-decls.h" + +/* Adapted from Linux: arch/x86/include/asm/msr.h (GPL-2.0) */ + +#ifdef __x86_64__ +#define DECLARE_ARGS(val, low, high) unsigned long low, high +#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +static unsigned long long __rdmsr(unsigned int msr) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("1: rdmsr\n" + "2:\n" + : EAX_EDX_RET(val, low, high) : "c" (msr)); + + return EAX_EDX_VAL(val, low, high); +} + +void test (void) +{ + __analyzer_eval (__rdmsr (0)); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (__rdmsr (1)); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c new file mode 100644 index 0000000..e90dccf5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c @@ -0,0 +1,319 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-additional-options "-fsanitize=bounds -fno-analyzer-call-summaries" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +/* Reduced from linux kernel: drivers/staging/wfx/sta.c (GPL-2.0) + on x86_64 with "allyesconfig" + + This test is deliberately not fully reduced, as an integration test + that the analyzer doesn't emit bogus "dereference of NULL" warnings + on the repeated wdev_to_wvif calls. */ + +#define NULL ((void *)0) + +/* Types. */ + +typedef unsigned char __u8; +typedef unsigned short __u16; +__extension__ typedef unsigned long long __u64; + +typedef __u8 u8; +typedef __u16 u16; +typedef __u64 u64; + +enum { false = 0, true = 1 }; +typedef _Bool bool; + +struct device; + +typedef struct { + int counter; +} atomic_t; + +struct static_key { + atomic_t enabled; + union { + unsigned long type; + struct jump_entry *entries; + struct static_key_mod *next; + }; +}; + +struct static_key_true { + struct static_key key; +}; + +struct static_key_false { + struct static_key key; +}; + +struct _ddebug { + const char *modname; + const char *function; + const char *filename; + const char *format; + unsigned int lineno : 18; + unsigned int flags : 8; + + union { + struct static_key_true dd_key_true; + struct static_key_false dd_key_false; + } key; + +} __attribute__((aligned(8))); + +enum nl80211_iftype { + /* [...snip...] */ + NL80211_IFTYPE_AP, + /* [...snip...] */ + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 +}; + +struct ieee80211_channel { + /* [...snip...] */ + u16 hw_value; + /* [...snip...] */ +}; + +struct cfg80211_chan_def { + struct ieee80211_channel *chan; + /* [...snip...] */ +}; + +struct ieee80211_bss_conf { + /* [...snip...] */ + bool assoc, ibss_joined; + /* [...snip...] */ + struct cfg80211_chan_def chandef; + /* [...snip...] */ + bool ps; + /* [...snip...] */ +}; + +struct ieee80211_conf { + /* [...snip...] */ + int power_level, dynamic_ps_timeout; + /* [...snip...] */ +}; + +struct ieee80211_vif { + enum nl80211_iftype type; + struct ieee80211_bss_conf bss_conf; + /* [...snip...] */ + u8 drv_priv[] __attribute__((__aligned__(sizeof(void *)))); +}; + +struct ieee80211_hw { + struct ieee80211_conf conf; + /* [...snip...] */ +}; + +struct wfx_dev { + /* [...snip...] */ + struct device *dev; + struct ieee80211_hw *hw; + struct ieee80211_vif *vif[2]; + /* [...snip...] */ + int force_ps_timeout; +}; + +struct wfx_vif { + struct wfx_dev *wdev; + struct ieee80211_vif *vif; + /* [...snip...] */ +}; + +/* Function decls. */ + +extern __attribute__((__format__(printf, 1, 2))) void +__warn_printk(const char *fmt, ...); + +extern bool ____wrong_branch_error(void); + +extern __attribute__((__format__(printf, 3, 4))) void +__dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev, + const char *fmt, ...); + +bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor); + +/* Function defns. */ + +static inline unsigned long array_index_mask_nospec(unsigned long index, + unsigned long size) { + unsigned long mask; + + asm volatile("cmp %1,%2; sbb %0,%0;" + : "=r"(mask) + : "g"(size), "r"(index) + : "cc"); + return mask; +} + +static inline __attribute__((__always_inline__)) bool +arch_static_branch(struct static_key *key, bool branch) { + asm goto("1:" + "jmp %l[l_yes] # objtool NOPs this \n\t" + ".pushsection __jump_table, \"aw\" \n\t" + " " + ".balign 8" + " " + "\n\t" + ".long 1b - . \n\t" + ".long %l[l_yes] - . \n\t" + " " + ".quad" + " " + "%c0 + %c1 - .\n\t" + ".popsection \n\t" + : + : "i"(key), "i"(2 | branch) + : + : l_yes); + asm(""); + + return false; +l_yes: + return true; +} + +static inline __attribute__((__always_inline__)) bool +arch_static_branch_jump(struct static_key *const key, const bool branch) { + asm goto("1:" + "jmp %l[l_yes]\n\t" + ".pushsection __jump_table, \"aw\" \n\t" + " " + ".balign 8" + " " + "\n\t" + ".long 1b - . \n\t" + ".long %l[l_yes] - . \n\t" + " " + ".quad" + " " + "%c0 + %c1 - .\n\t" + ".popsection \n\t" + : + : "i"(key), "i"(branch) + : + : l_yes); + asm(""); + + return false; +l_yes: + return true; +} + +static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id) { + if (vif_id >= + (sizeof(wdev->vif) / sizeof((wdev->vif)[0]) + ((int)(sizeof(struct { + int : (-!!(__builtin_types_compatible_p(typeof((wdev->vif)), + typeof(&(wdev->vif)[0])))); + }))))) { + static struct _ddebug __attribute__((__aligned__(8))) + __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug1678 = { + .modname = "wfx", + .function = __func__, + .filename = "drivers/staging/wfx/wfx.h", + .format = ("requesting non-existent vif: %d\n"), + .lineno = 97, + .flags = 0, + .key.dd_key_false = ((struct static_key_false){ + .key = {.enabled = {0}, {.entries = (void *)0UL}}, + })}; + if (({ + bool branch; + if (__builtin_types_compatible_p( + typeof(*&__UNIQUE_ID_ddebug1678.key.dd_key_false), + struct static_key_true)) + branch = arch_static_branch_jump( + &(&__UNIQUE_ID_ddebug1678.key.dd_key_false)->key, false); + else if (__builtin_types_compatible_p( + typeof(*&__UNIQUE_ID_ddebug1678.key.dd_key_false), + struct static_key_false)) + branch = arch_static_branch( + &(&__UNIQUE_ID_ddebug1678.key.dd_key_false)->key, false); + else + branch = ____wrong_branch_error(); + __builtin_expect(!!(branch), 0); + })) + __dynamic_dev_dbg(&__UNIQUE_ID_ddebug1678, wdev->dev, + "requesting non-existent vif: %d\n", vif_id); + return NULL; + } + typeof(vif_id) _i = (vif_id); + typeof((sizeof(wdev->vif) / sizeof((wdev->vif)[0]) + ((int)(sizeof(struct { + int : (-!!(__builtin_types_compatible_p(typeof((wdev->vif)), + typeof(&(wdev->vif)[0])))); + }))))) _s = + ((sizeof(wdev->vif) / sizeof((wdev->vif)[0]) + ((int)(sizeof(struct { + int : (-!!(__builtin_types_compatible_p(typeof((wdev->vif)), + typeof(&(wdev->vif)[0])))); + }))))); + unsigned long _mask = array_index_mask_nospec(_i, _s); + vif_id = (typeof(_i))(_i & _mask); + if (!wdev->vif[vif_id]) { + static struct _ddebug __attribute__((__aligned__(8))) + __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug1681 = { + .modname = "wfx", + .function = __func__, + .filename = "drivers/staging/wfx/wfx.h", + .format = ("requesting non-allocated vif: %d\n"), + .lineno = 102, + .flags = 0, + .key.dd_key_false = ((struct static_key_false){ + .key = {.enabled = {0}, {.entries = (void *)0UL}}, + })}; + if (({ + bool branch; + if (__builtin_types_compatible_p( + typeof(*&__UNIQUE_ID_ddebug1681.key.dd_key_false), + struct static_key_true)) + branch = arch_static_branch_jump( + &(&__UNIQUE_ID_ddebug1681.key.dd_key_false)->key, false); + else if (__builtin_types_compatible_p( + typeof(*&__UNIQUE_ID_ddebug1681.key.dd_key_false), + struct static_key_false)) + branch = arch_static_branch( + &(&__UNIQUE_ID_ddebug1681.key.dd_key_false)->key, false); + else + branch = ____wrong_branch_error(); + __builtin_expect(!!(branch), 0); + })) + __dynamic_dev_dbg(&__UNIQUE_ID_ddebug1681, wdev->dev, + "requesting non-allocated vif: %d\n", vif_id); + return NULL; + } + return (struct wfx_vif *)wdev->vif[vif_id]->drv_priv; +} + +int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps) { + struct ieee80211_channel *chan0 = NULL, *chan1 = NULL; + struct ieee80211_conf *conf = &wvif->wdev->hw->conf; + + if (wdev_to_wvif(wvif->wdev, 0)) + chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan; /* { dg-bogus "dereference of NULL" } */ + if (wdev_to_wvif(wvif->wdev, 1)) + chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan; /* { dg-bogus "dereference of NULL" } */ + if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && + wvif->vif->type != NL80211_IFTYPE_AP) { + + if (enable_ps) + *enable_ps = true; + if (wvif->wdev->force_ps_timeout > -1) + return wvif->wdev->force_ps_timeout; + else if (wfx_api_older_than(wvif->wdev, 3, 2)) + return 0; + else + return 30; + } + if (enable_ps) + *enable_ps = wvif->vif->bss_conf.ps; + if (wvif->wdev->force_ps_timeout > -1) + return wvif->wdev->force_ps_timeout; + else if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps) + return conf->dynamic_ps_timeout; + else + return -1; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c new file mode 100644 index 0000000..a18c58c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c @@ -0,0 +1,77 @@ +/* { dg-do assemble { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ + +/* Reproducer for false positive from -Wanalyzer-null-dereference seen + in Linux kernel (drivers/staging/wfx/sta.c; GPL-2.0) due to + the analyzer not grokking that array_index_mask_nospec is + effectively pure, and thus not realizing that array_index_no_spec + is also pure, leading to wdev_to_wvif not being treated as pure, + and thus able to return non-NULL and then NULL. */ + +typedef unsigned char u8; +#define NULL ((void *)0) + +/* Types. */ + +struct ieee80211_vif { + int placeholder; + /* snip */ + u8 drv_priv[]; +}; + +struct wfx_dev { + /* snip */ + struct ieee80211_vif *vif[2]; + /* snip */ +}; + +struct wfx_vif { + struct wfx_dev *wdev; + struct ieee80211_vif *vif; + /* snip */ +}; + +/* Copied from arch/x86/include/asm/barrier.h */ + +static inline unsigned long array_index_mask_nospec(unsigned long index, + unsigned long size) +{ + unsigned long mask; + + asm volatile ("cmp %1,%2; sbb %0,%0;" + :"=r" (mask) + :"g"(size),"r" (index) + :"cc"); + return mask; +} + +/* Simplified from include/linux/kernel.h */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/* Simplified from include/linux/nospec.h */ + +#define array_index_nospec(index, size) \ +({ \ + typeof(index) _i = (index); \ + typeof(size) _s = (size); \ + unsigned long _mask = array_index_mask_nospec(_i, _s); \ + /* snip */ \ + (typeof(_i)) (_i & _mask); \ +}) + +/* Simplified from drivers/staging/wfx/wfx.h */ + +static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id) { + vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif)); + if (!wdev->vif[vif_id]) { + return NULL; + } + return (struct wfx_vif *)wdev->vif[vif_id]->drv_priv; +} + +struct ieee80211_vif *test (struct wfx_vif *wvif) { + if (wdev_to_wvif(wvif->wdev, 1)) + return wdev_to_wvif(wvif->wdev, 1)->vif; /* { dg-bogus "dereference of NULL" } */ + else + return NULL; +} -- cgit v1.1 From 4e3129b0caceec008a940aa5eada253cd0f0b3ec Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 5 Aug 2021 10:21:30 +0200 Subject: Fix oversight in handling of reverse SSO in SRA pass The scalar storage order does not apply to pointer and vector components. gcc/ PR tree-optimization/101626 * tree-sra.c (propagate_subaccesses_from_rhs): Do not set the reverse scalar storage order on a pointer or vector component. gcc/testsuite/ * gcc.dg/sso-15.c: New test. --- gcc/testsuite/gcc.dg/sso-15.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sso-15.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-15.c b/gcc/testsuite/gcc.dg/sso-15.c new file mode 100644 index 0000000..d8a711d --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-15.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) +#else +#define REV_ENDIANNESS __attribute__((scalar_storage_order("little-endian"))) +#endif + +struct X { int *p; } REV_ENDIANNESS; + +struct X x; + +struct X __attribute__((noinline)) foo (int *p) +{ + struct X x; + x.p = p; + return x; +} + +void __attribute((noinline)) bar (void) +{ + *x.p = 1; +} + +extern void abort (void); + +int main (void) +{ + int i = 0; + x = foo(&i); + bar(); + if (i != 1) + abort (); + return 0; +} -- cgit v1.1 From f0fc1e66238e2e9fe0cbc6e5b77fd163bf887b2c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 5 Aug 2021 11:39:50 +0200 Subject: Adjust gcc.dg/vect/bb-slp-pr101756.c This adjusts the testcase for excess diagnostics emitted by some targets because of the attribute simd usage like warning: GCC does not currently support mixed size types for 'simd' functions on aarch64. 2021-08-05 Richard Biener * gcc.dg/vect/bb-slp-pr101756.c: Add -w. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c index 9420e77..de7f180 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101756.c @@ -1,4 +1,6 @@ /* { dg-do compile } */ +/* SIMD support can emit additional diagnostics. */ +/* { dg-additional-options "-w" } */ __attribute__ ((simd)) int tq (long int ea, int of, int kk) -- cgit v1.1 From 9124bbe1857f0d3a3015d6461d5f8d04f07cab85 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sat, 14 Nov 2020 13:51:09 +0100 Subject: gcov: Add __gcov_info_to_gdca() Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda info in a freestanding environment. It is intended to be used with the -fprofile-info-section option. A crude test program which doesn't use a linker script is (use "gcc -coverage -fprofile-info-section -lgcov test.c" to compile it): #include #include #include extern const struct gcov_info *my_info; static void filename (const char *f, void *arg) { printf("filename: %s\n", f); } static void dump (const void *d, unsigned n, void *arg) { const unsigned char *c = d; for (unsigned i = 0; i < n; ++i) printf ("%02x", c[i]); } static void * allocate (unsigned length, void *arg) { return malloc (length); } int main() { __asm__ volatile (".set my_info, .LPBX2"); __gcov_info_to_gcda (my_info, filename, dump, allocate, NULL); return 0; } With this patch, is included in libgcov-driver.c even if inhibit_libc is defined. This header file should be also available for freestanding environments. If this is not the case, then we have to define intptr_t somehow. The patch removes one use of memset() which makes the include superfluous. gcc/ * gcov-io.h (gcov_write): Declare. * gcov-io.c (gcov_write): New. (gcov_write_counter): Remove. (gcov_write_tag_length): Likewise. (gcov_write_summary): Replace gcov_write_tag_length() with calls to gcov_write_unsigned(). * doc/invoke.texi (fprofile-info-section): Mention __gcov_info_to_gdca(). gcc/testsuite/ * gcc.dg/gcov-info-to-gcda.c: New test. libgcc/ * Makefile.in (LIBGCOV_DRIVER): Add _gcov_info_to_gcda. * gcov.h (gcov_info): Declare. (__gcov_info_to_gdca): Likewise. * libgcov.h (gcov_write_counter): Remove. (gcov_write_tag_length): Likewise. * libgcov-driver.c (#include ): New. (#include ): Remove. (NEED_L_GCOV): Conditionally define. (NEED_L_GCOV_INFO_TO_GCDA): Likewise. (are_all_counters_zero): New. (gcov_dump_handler): Likewise. (gcov_allocate_handler): Likewise. (dump_unsigned): Likewise. (dump_counter): Likewise. (write_topn_counters): Add dump_fn, allocate_fn, and arg parameters. Use dump_unsigned() and dump_counter(). (write_one_data): Add dump_fn, allocate_fn, and arg parameters. Use dump_unsigned(), dump_counter(), and are_all_counters_zero(). (__gcov_info_to_gcda): New. --- gcc/testsuite/gcc.dg/gcov-info-to-gcda.c | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c new file mode 100644 index 0000000..a42a768 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ +/* { dg-skip-if "profile-info-section" { powerpc-ibm-aix* } } */ +/* { dg-options "-fprofile-arcs -fprofile-info-section" } */ + +#define assert(expr) \ + ((expr) \ + ? (void)0 \ + : (__builtin_printf ("%s:%i: Assertion `%s' failed.\n", \ + __FILE__, __LINE__, #expr), \ + __builtin_abort ())) + +struct gcov_info; + +extern void +__gcov_info_to_gcda (const struct gcov_info *__info, + void (*__filename_fn) (const char *, void *), + void (*__dump_fn) (const void *, unsigned, void *), + void *(*__allocate_fn) (unsigned, void *), + void *__arg); + +extern const struct gcov_info *my_info; + +static unsigned counter; + +static void +filename (const char *f, void *arg) +{ + assert (arg == &counter); + assert (__builtin_strstr (f, "gcov-info-to-gcda.c") == 0); +} + +static void +dump (const void *d, unsigned n, void *arg) +{ + unsigned *m = (unsigned *)arg; + assert (arg == &counter); + + if (*m == 0) + { + const unsigned *u = d; + assert (*u == 0x67636461); + } + + *m += n; +} + +static void * +allocate (unsigned length, void *arg) +{ + assert (arg == &counter); + return __builtin_malloc (length); +} + +int main() +{ + __asm__ volatile (".set my_info, .LPBX2"); + __gcov_info_to_gcda (my_info, filename, dump, allocate, &counter); + assert (counter > 4); + return 0; +} -- cgit v1.1 From 81d6cdd335ffc60c216a020d5c99306f659377a2 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 6 Aug 2021 15:29:33 -0600 Subject: Move more code to new gimple-ssa-warn-access pass. gcc/ChangeLog: * builtins.c (expand_builtin_memchr): Move to gimple-ssa-warn-access.cc. (expand_builtin_strcat): Same. (expand_builtin_stpncpy): Same. (expand_builtin_strncat): Same. (check_read_access): Same. (check_memop_access): Same. (expand_builtin_strlen): Move checks to gimple-ssa-warn-access.cc. (expand_builtin_strnlen): Same. (expand_builtin_memcpy): Same. (expand_builtin_memmove): Same. (expand_builtin_mempcpy): Same. (expand_builtin_strcpy): Same. (expand_builtin_strcpy_args): Same. (expand_builtin_stpcpy_1): Same. (expand_builtin_strncpy): Same. (expand_builtin_memset): Same. (expand_builtin_bzero): Same. (expand_builtin_strcmp): Same. (expand_builtin_strncmp): Same. (expand_builtin): Remove handlers. (fold_builtin_strlen): Add a comment. * builtins.h (check_access): Move to gimple-ssa-warn-access.cc. * calls.c (maybe_warn_nonstring_arg): Same. * diagnostic-spec.c (nowarn_spec_t::nowarn_spec_t): Add warning option. * gimple-fold.c (gimple_fold_builtin_strcpy): Pass argument to callee. (gimple_fold_builtin_stpcpy): Same. * gimple-ssa-warn-access.cc (has_location): New function. (get_location): Same. (get_callee_fndecl): Same. (call_nargs): Same. (call_arg): Same. (warn_string_no_nul): Define. (unterminated_array): Same. (check_nul_terminated_array): Same. (maybe_warn_nonstring_arg): Same. (maybe_warn_for_bound): Same. (warn_for_access): Same. (check_access): Same. (check_memop_access): Same. (check_read_access): Same. (warn_dealloc_offset): Use helper functions. (maybe_emit_free_warning): Same. (class pass_waccess): Add members. (check_strcat): New function. (check_strncat): New function. (check_stxcpy): New function. (check_stxncpy): New function. (check_strncmp): New function. (pass_waccess::check_builtin): New function. (pass_waccess::check): Call it. * gimple-ssa-warn-access.h (warn_string_no_nul): Move here from builtins.h. (maybe_warn_for_bound): Same. (check_access): Same. (check_memop_access): Same. (check_read_access): Same. * pointer-query.h (struct access_data): Define a ctor overload. gcc/testsuite/ChangeLog: * c-c++-common/Wsizeof-pointer-memaccess1.c: Also disable -Wstringop-overread. * c-c++-common/attr-nonstring-3.c: Adjust pattern of expected message. * gcc.dg/Warray-bounds-39.c: Add an xfail due to a known bug. * gcc.dg/Wstring-compare-3.c: Also disable -Wstringop-overread. * gcc.dg/attr-nonstring-2.c: Adjust pattern of expected message. * gcc.dg/attr-nonstring-4.c: Same. * gcc.dg/Wstringop-overread-6.c: New test. * gcc.dg/sso-14.c: Fix typos to avoid buffer overflow. --- gcc/testsuite/gcc.dg/Warray-bounds-39.c | 49 +-- gcc/testsuite/gcc.dg/Wstring-compare-3.c | 2 +- gcc/testsuite/gcc.dg/Wstringop-overread-6.c | 574 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/attr-nonstring-2.c | 22 +- gcc/testsuite/gcc.dg/attr-nonstring-4.c | 4 +- gcc/testsuite/gcc.dg/sso-14.c | 4 +- 6 files changed, 616 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overread-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-39.c b/gcc/testsuite/gcc.dg/Warray-bounds-39.c index 8317656..cb00fa9 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-39.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-39.c @@ -5,6 +5,8 @@ { dg-do compile } { dg-options "-O2 -Wall" } */ +#define NOIPA __attribute__ ((noipa)) + typedef __SIZE_TYPE__ size_t; extern void* memcpy (void*, const void*, size_t); @@ -19,65 +21,65 @@ const char s1_0[1][0] = { }; char d[4]; -void* test_memcpy_s0_1 (void *d) +NOIPA void* test_memcpy_s0_1 (void *d) { return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s0_2 (void *d) +NOIPA void* test_memcpy_s0_2 (void *d) { return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s0_0_1 (void *d) +NOIPA void* test_memcpy_s0_0_1 (void *d) { return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s0_0_2 (void *d) +NOIPA void* test_memcpy_s0_0_2 (void *d) { return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s0_1_1 (void *d) +NOIPA void* test_memcpy_s0_1_1 (void *d) { return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s0_1_2 (void *d) +NOIPA void* test_memcpy_s0_1_2 (void *d) { return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s1_0_1 (void *d) +NOIPA void* test_memcpy_s1_0_1 (void *d) { return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_s1_0_2 (void *d) +NOIPA void* test_memcpy_s1_0_2 (void *d) { return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memmove_s0_1 (void *d) +NOIPA void* test_memmove_s0_1 (void *d) { return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memmove_s0_2 (void *d) +NOIPA void* test_memmove_s0_2 (void *d) { return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memmove_s0_0_1 (void *d) +NOIPA void* test_memmove_s0_0_1 (void *d) { return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memmove_s0_0_2 (void *d) +NOIPA void* test_memmove_s0_0_2 (void *d) { return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } @@ -90,59 +92,60 @@ const struct Empty e0_0[0][0] = { }; const struct Empty e0_1[0][1] = { }; const struct Empty e1_0[1][0] = { }; -void* test_memcpy_e_1 (void *d) +NOIPA void* test_memcpy_e_1 (void *d) { return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_e0_1 (void *d) +NOIPA void* test_memcpy_e0_1 (void *d) { return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_e0_0_1 (void *d) +NOIPA void* test_memcpy_e0_0_1 (void *d) { return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_e0_1_1 (void *d) +NOIPA void* test_memcpy_e0_1_1 (void *d) { return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -void* test_memcpy_e1_0_1 (void *d) +NOIPA void* test_memcpy_e1_0_1 (void *d) { return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -char* test_strcpy_s0 (char *d) +NOIPA char* +test_strcpy_s0 (char *d) /* { dg-bogus "-Warray-bounds" "pr101679" { xfail *-*-* } } */ { return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -char* test_strcpy_s0_0 (char *d) +NOIPA char* test_strcpy_s0_0 (char *d) { return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -char* test_strncpy_s0_1 (char *d) +NOIPA char* test_strncpy_s0_1 (char *d) { return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -char* test_strncpy_s0_2 (char *d) +NOIPA char* test_strncpy_s0_2 (char *d) { return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -char* test_strncpy_s0_0_1 (char *d) +NOIPA char* test_strncpy_s0_0_1 (char *d) { return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } -char* test_strncpy_s0_0_2 (char *d) +NOIPA char* test_strncpy_s0_0_2 (char *d) { return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */ } diff --git a/gcc/testsuite/gcc.dg/Wstring-compare-3.c b/gcc/testsuite/gcc.dg/Wstring-compare-3.c index d4d7121..6d0d5be 100644 --- a/gcc/testsuite/gcc.dg/Wstring-compare-3.c +++ b/gcc/testsuite/gcc.dg/Wstring-compare-3.c @@ -1,6 +1,6 @@ /* PR middle-end/95673 - missing -Wstring-compare for an impossible strncmp test { dg-do compile } - { dg-options "-O2 -Wall -Wstring-compare -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Wall -Wstring-compare -Wno-stringop-overread -ftrack-macro-expansion=0" } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread-6.c b/gcc/testsuite/gcc.dg/Wstringop-overread-6.c new file mode 100644 index 0000000..a8177a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overread-6.c @@ -0,0 +1,574 @@ +/* Verify -Wstringop-overread is issued appropriately for calls to string + functions at -O0 and without -Wall. + { dg-do compile } + { dg-options "-O0 -ftrack-macro-expansion=0" } */ + +typedef __SIZE_TYPE__ size_t; + +#define S2 "12" +#define S9 "123456789" + +// functions. + +char* gettext (const char *); + +// functions. + +typedef struct FILE FILE; + +int fputs (const char*, FILE*); +int fputs_unlocked (const char*, FILE*); + +int puts (const char*); +int puts_unlocked (const char*); + +// functions. + +void* memchr (const void*, int, size_t); +int memcmp (const void*, const void*, size_t); +void* memcpy (void*, const void*, size_t); +void* mempcpy (void*, const void*, size_t); +void* memmove (void*, const void*, size_t); + +char* strchr (const char*, int); +char* strrchr (const char*, int); + +int strcmp (const char*, const char*); +int strncmp (const char*, const char*, size_t); + +char* strcat (char*, const char*); +char* stpcpy (char*, const char*); +char* strcpy (char*, const char*); +char* stpncpy (char*, const char*, size_t); +char* strncpy (char*, const char*, size_t); +char* strdup (const char*); +char* strndup (const char*, size_t); + +char* strpbrk (const char*, const char*); +size_t strcspn (const char*, const char*); +size_t strspn (const char*, const char*); +char* strstr (const char*, const char*); + +size_t strlen (const char*); +size_t strnlen (const char*, size_t); + + +extern void* malloc (size_t); + +void sink (void*); + + +extern char *d; +extern char a0[0]; + +const char arr[7] = "abc\0def"; + +/* Unterminated array at the end of ARR above. */ +#define unterm (arr + __builtin_strlen (arr) + 1) + +/* Size of the unterminated array - 1. */ +#define unterm_size (sizeof arr - __builtin_strlen (arr) - 1) + +const void* nowarn_memchr (int x) +{ + const char *p1 = unterm; + return memchr (p1, x, unterm_size); +} + +const void* warn_memchr (int x) +{ + const char *p1 = unterm; + return memchr (p1, x, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + + +void* nowarn_memcpy (void) +{ + const char *s = unterm; + return memcpy (d, s, unterm_size); +} + +void* warn_memcpy (void) +{ + const char *s = unterm; + /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform + from defeating the warning (for now). */ + return memcpy (d, s, unterm_size + 2 | 1); // { dg-warning "-Wstringop-overread" } +} + + +void* nowarn_mempcpy (void) +{ + const char *s = unterm; + return mempcpy (d, s, unterm_size); +} + +void* warn_mempcpy (void) +{ + const char *s = unterm; + /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform + from defeating the warning (for now). */ + return mempcpy (d, s, unterm_size + 2 | 1); // { dg-warning "-Wstringop-overread" } +} + + +void* nowarn_memmove (void) +{ + const char *s = unterm; + return memmove (d, s, unterm_size); +} + +void* warn_memmove (void) +{ + const char *s = unterm; + /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform + from defeating the warning (for now). */ + return memmove (d, s, unterm_size + 2); // { dg-warning "-Wstringop-overread" } +} + + +int nowarn_memcmp_1 (const char *p2) +{ + const char *p1 = unterm; + return memcmp (p1, p2, unterm_size); +} + +int warn_memcmp_1 (const char *p2) +{ + const char *p1 = unterm; + return memcmp (p1, p2, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +int nowarn_memcmp_2 (const char *p1) +{ + const char *p2 = unterm; + return memcmp (p1, p2, unterm_size); +} + +int warn_memcmp_2 (const char *p1) +{ + const char *p2 = unterm; + return memcmp (p1, p2, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + + +void warn_strcat (void) +{ + strcat (d, unterm); // { dg-warning "-Wstringop-overread" } +} + +void warn_strcat_a0 (void) +{ + strcat (d, a0); // { dg-warning "-Wstringop-overread" } +} + +void warn_strcat_end (void) +{ + const char *s = arr + sizeof arr; + strcat (d, s); // { dg-warning "-Wstringop-overread" } +} + +char* warn_stpcpy (void) +{ + return stpcpy (d, unterm); // { dg-warning "-Wstringop-overread" } +} + +char* warn_stpcpy_a0 (void) +{ + return stpcpy (d, a0); // { dg-warning "-Wstringop-overread" } +} + +char* warn_stpcpy_end (void) +{ + const char *s = arr + sizeof arr; + return stpcpy (d, s); // { dg-warning "-Wstringop-overread" } +} + +char* warn_stpcpy_malloc0 (void) +{ + char *s = malloc (0); + sink (s); + return stpcpy (d, s); // { dg-warning "-Wstringop-overread" } +} + + +void warn_strcpy (void) +{ + strcpy (d, unterm); // { dg-warning "-Wstringop-overread" } +} + +void warn_strcpy_a0 (void) +{ + strcpy (d, a0); // { dg-warning "-Wstringop-overread" } +} + +void warn_strcpy_end (void) +{ + const char *s = arr + sizeof arr; + strcpy (d, s); // { dg-warning "-Wstringop-overread" } +} + +void warn_strcpy_malloc0 (void) +{ + char *s = malloc (0); + sink (s); + strcpy (d, s); // { dg-warning "-Wstringop-overread" } +} + + +char* nowarn_stpncpy (void) +{ + const char *s = unterm; + return stpncpy (d, s, unterm_size); +} + +char* warn_stpncpy (void) +{ + const char *s = unterm; + return stpncpy (d, s, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +char* warn_stpncpy_a0 (void) +{ + return stpncpy (d, a0, 3); // { dg-warning "-Wstringop-overread" } +} + +char* warn_stpncpy_end (void) +{ + const char *s = arr + sizeof arr; + return stpncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" } +} + + +void nowarn_strncpy (void) +{ + const char *s = unterm; + strncpy (d, s, unterm_size); +} + +void warn_strncpy (void) +{ + const char *s = unterm; + strncpy (d, s, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +void warn_strncpy_a0 (void) +{ + const char *s = a0; + strncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" } +} + +void warn_strncpy_end (void) +{ + const char *s = arr + sizeof arr; + strncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" } +} + + +int warn_strlen (void) +{ + return strlen (unterm); // { dg-warning "-Wstringop-overread" } +} + +int warn_strlen_a0 (void) +{ + return strlen (a0); // { dg-warning "-Wstringop-overread" } +} + +int warn_strlen_end (void) +{ + const char *s = arr + sizeof arr; + return strlen (s); // { dg-warning "-Wstringop-overread" } +} + +int warn_strlen_malloc0 (void) +{ + char *s = malloc (0); + sink (s); + return strlen (s); // { dg-warning "-Wstringop-overread" } +} + + +int nowarn_strnlen (void) +{ + return strnlen (unterm, unterm_size); +} + +int warn_strnlen (void) +{ + return strnlen (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +int warn_strnlen_end (void) +{ + const char *s = arr + sizeof arr; + return strnlen (s, 2); // { dg-warning "-Wstringop-overread" } +} + + +int warn_strcmp_1 (const char *s) +{ + return strcmp (unterm, s); // { dg-warning "-Wstringop-overread" } +} + +int warn_strcmp_2 (const char *s) +{ + return strcmp (s, unterm); // { dg-warning "-Wstringop-overread" } +} + +int warn_strcmp_2_end (const char *s) +{ + const char *t = arr + sizeof arr; + return strcmp (s, t); // { dg-warning "-Wstringop-overread" } +} + + +int nowarn_strncmp_1 (const char *s2) +{ + const char *s1 = unterm; + return strncmp (s1, s2, unterm_size); +} + +int warn_strncmp_1 (const char *s2) +{ + const char *s1 = unterm; + return strncmp (s1, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +int nowarn_strncmp_2 (const char *s1) +{ + const char *s2 = unterm; + return strncmp (s1, s2, unterm_size); +} + +int warn_strncmp_2 (const char *s1) +{ + const char *s2 = unterm; + return strncmp (s1, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +int warn_strncmp_2_end (const char *s1) +{ + const char *s2 = arr + sizeof arr;; + return strncmp (s1, s2, sizeof arr); // { dg-warning "-Wstringop-overread" } +} + + +int nowarn_strncmp_1_s2 (void) +{ + /* Since the read is also bounded by the length of the S2 literal + and so safe, expect no warning. */ + const char *s = unterm; + return strncmp (s, S2, unterm_size + 1); // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } } +} + +int warn_strncmp_2_s2 (void) +{ + /* Same as above. */ + const char *t = unterm; + return strncmp (S2, t, unterm_size + 1); // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } } +} + + +int warn_strncmp_1_s9 (void) +{ + /* Since both the bound and the length of the S9 literal are greater + than the size of UNNTERM the call reads past the end of the array. + Expect a warning. */ + const char *s1 = unterm; + return strncmp (s1, S9, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +int warn_strncmp_2_s9 (void) +{ + /* Same as above. */ + const char *s2 = unterm; + return strncmp (S9, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + + +const char* warn_strchr (int x) +{ + return strchr (unterm, x); // { dg-warning "-Wstringop-overread" } +} + +const char* warn_strchr_end (int x) +{ + const char *s = arr + sizeof arr; + return strchr (s, x); // { dg-warning "-Wstringop-overread" } +} + + +const char* warn_strrchr (int x) +{ + return strrchr (unterm, x); // { dg-warning "-Wstringop-overread" } +} + +const char* warn_strrchr_end (int x) +{ + const char *s = arr + sizeof arr; + return strrchr (s, x); // { dg-warning "-Wstringop-overread" } +} + + +char* warn_strdup (void) +{ + return strdup (unterm); // { dg-warning "-Wstringop-overread" } +} + +char* warn_strdup_end (void) +{ + const char *s = arr + sizeof arr; + return strdup (s); // { dg-warning "-Wstringop-overread" } +} + + +char* nowarn_strndup (void) +{ + return strndup (unterm, unterm_size); +} + +char* warn_strndup (void) +{ + return strndup (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" } +} + +char* warn_strndup_end (void) +{ + const char *s = arr + sizeof arr; + return strndup (s, sizeof arr); // { dg-warning "-Wstringop-overread" } +} + + +const char* warn_strpbrk_1 (const char *s2) +{ + return strpbrk (unterm, s2); // { dg-warning "-Wstringop-overread" } +} + +const char* warn_strpbrk_2 (const char *s1) +{ + return strpbrk (s1, unterm); // { dg-warning "-Wstringop-overread" } +} + + +size_t warn_strspn_1 (const char *s2) +{ + return strspn (unterm, s2); // { dg-warning "-Wstringop-overread" } +} + +size_t warn_strspn_1_end (const char *s2) +{ + const char *s1 = arr + sizeof arr; + return strspn (s1, s2); // { dg-warning "-Wstringop-overread" } +} + +size_t warn_strspn_2 (const char *s1) +{ + return strspn (s1, unterm); // { dg-warning "-Wstringop-overread" } +} + +size_t warn_strspn_2_end (const char *s1) +{ + const char *s2 = arr + sizeof arr; + return strspn (s1, s2); // { dg-warning "-Wstringop-overread" } +} + + +size_t warn_strcspn_1 (const char *s2) +{ + return strcspn (unterm, s2); // { dg-warning "-Wstringop-overread" } +} + +size_t warn_strcspn_1_end (const char *s2) +{ + const char *s1 = arr + sizeof arr; + return strcspn (s1, s2); // { dg-warning "-Wstringop-overread" } +} + +size_t warn_strcspn_2 (const char *s1) +{ + return strcspn (s1, unterm); // { dg-warning "-Wstringop-overread" } +} + +size_t warn_strcspn_2_end (const char *s1) +{ + const char *s2 = arr + sizeof arr; + return strcspn (s1, s2); // { dg-warning "-Wstringop-overread" } +} + + +const char* warn_strstr_1 (const char *s2) +{ + return strstr (unterm, s2); // { dg-warning "-Wstringop-overread" } +} + +const char* warn_strstr_1_end (const char *s2) +{ + const char *s1 = arr + sizeof arr; + return strstr (s1, s2); // { dg-warning "-Wstringop-overread" } +} + + +const char* warn_strstr_2 (const char *s1) +{ + return strstr (s1, unterm); // { dg-warning "-Wstringop-overread" } +} + +const char* warn_strstr_2_end (const char *s1) +{ + const char *s2 = arr + sizeof arr; + return strstr (s1, s2); // { dg-warning "-Wstringop-overread" } +} + + +void warn_puts (void) +{ + puts (unterm); // { dg-warning "-Wstringop-overread" } +} + +void warn_puts_end (void) +{ + const char *s = arr + sizeof arr; + puts (s); // { dg-warning "-Wstringop-overread" } +} + + +void warn_fputs (FILE *f) +{ + fputs (unterm, f); // { dg-warning "-Wstringop-overread" } +} + +void warn_fputs_end (FILE *f) +{ + const char *s = arr + sizeof arr; + fputs (s, f); // { dg-warning "-Wstringop-overread" } +} + + +void warn_puts_unlocked (void) +{ + puts_unlocked (unterm); // { dg-warning "-Wstringop-overread" } +} + +void warn_puts_unlocked_end (void) +{ + const char *s = arr + sizeof arr; + puts_unlocked (s); // { dg-warning "-Wstringop-overread" } +} + +void warn_fputs_unlocked (FILE *f) +{ + fputs_unlocked (unterm, f); // { dg-warning "-Wstringop-overread" } +} + + +const char* warn_gettext (void) +{ + return gettext (unterm); // { dg-warning "-Wstringop-overread" } +} + +const char* warn_gettext_end (void) +{ + const char *s = arr + sizeof arr; + return gettext (s); // { dg-warning "-Wstringop-overread" } +} diff --git a/gcc/testsuite/gcc.dg/attr-nonstring-2.c b/gcc/testsuite/gcc.dg/attr-nonstring-2.c index ba4757d..44a102c 100644 --- a/gcc/testsuite/gcc.dg/attr-nonstring-2.c +++ b/gcc/testsuite/gcc.dg/attr-nonstring-2.c @@ -26,8 +26,8 @@ void test_strnlen_array_cst (void) T (strnlen (ns3, 1)); T (strnlen (ns3, 2)); T (strnlen (ns3, 3)); - T (strnlen (ns3, 4)); /* { dg-warning "specified bound 4 exceeds source size 3" } */ - T (strnlen (ns3, DIFF_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds source size" } */ + T (strnlen (ns3, 4)); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 4|specified bound 4 exceeds source size 3" } */ + T (strnlen (ns3, DIFF_MAX)); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound|specified bound \[0-9\]+ exceeds source size" } */ T (strnlen (ns3, SIZE_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ NONSTRING char ns5[5]; @@ -37,8 +37,8 @@ void test_strnlen_array_cst (void) T (strnlen (ns5, 1)); T (strnlen (ns5, 2)); T (strnlen (ns5, 3)); - T (strnlen (ns5, 6)); /* { dg-warning "specified bound 6 exceeds source size 5" } */ - T (strnlen (ns5, DIFF_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds source size 5" } */ + T (strnlen (ns5, 6)); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 6|specified bound 6 exceeds source size 5" } */ + T (strnlen (ns5, DIFF_MAX)); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound|specified bound \[0-9\]+ exceeds source size 5" } */ T (strnlen (ns5, SIZE_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ } @@ -52,8 +52,8 @@ void test_strnlen_array_range (void) T (strnlen (ns3, UR (0, 9))); T (strnlen (ns3, UR (3, 4))); T (strnlen (ns3, UR (3, DIFF_MAX))); - T (strnlen (ns3, UR (4, 5))); /* { dg-warning "specified bound \\\[4, 5] exceeds source size 3" } */ - T (strnlen (ns3, UR (DIFF_MAX, SIZE_MAX))); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 3 " } */ + T (strnlen (ns3, UR (4, 5))); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[4, 5]|specified bound \\\[4, 5] exceeds source size 3" } */ + T (strnlen (ns3, UR (DIFF_MAX, SIZE_MAX))); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[\[0-9\]+, \[0-9\]+] |specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 3 " } */ } @@ -73,8 +73,8 @@ void test_strnlen_string_cst (void) T (3, "12", 3, 1); T (3, "12", 3, 9); T (3, "123", 3, 1); - T (3, "123", 3, 4); /* { dg-warning "specified bound 4 exceeds source size 3" } */ - T (3, "123", 3, 9); /* { dg-warning "specified bound 9 exceeds source size 3" } */ + T (3, "123", 3, 4); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 4|specified bound 4 exceeds source size 3" } */ + T (3, "123", 3, 9); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 9|specified bound 9 exceeds source size 3" } */ T (5, "1", 2, 1); T (5, "1", 2, 2); @@ -84,7 +84,7 @@ void test_strnlen_string_cst (void) T (5, "12", 3, 9); T (5, "123", 3, 1); T (5, "123", 3, 5); - T (5, "123", 3, 6); /* { dg-warning "specified bound 6 exceeds source size 5" } */ + T (5, "123", 3, 6); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 6|specified bound 6 exceeds source size 5" } */ /* Strnlen shouldn't trigger a warning for arrays of unknown size (except for accesses to uninitialized elements when those are @@ -110,6 +110,6 @@ void test_strnlen_string_range (void) { T (3, "1", 2, UR (0, 1)); T (3, "1", 2, UR (3, 9)); - T (3, "123", 3, UR (4, 5)); /* { dg-warning "specified bound \\\[4, 5] exceeds source size 3" } */ - T (3, "123", 3, UR (5, 9)); /* { dg-warning "specified bound \\\[5, 9] exceeds source size 3" } */ + T (3, "123", 3, UR (4, 5)); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[4, 5]|specified bound \\\[4, 5] exceeds source size 3" } */ + T (3, "123", 3, UR (5, 9)); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[5, 9]|specified bound \\\[5, 9] exceeds source size 3" } */ } diff --git a/gcc/testsuite/gcc.dg/attr-nonstring-4.c b/gcc/testsuite/gcc.dg/attr-nonstring-4.c index f2416c1..6f03a56 100644 --- a/gcc/testsuite/gcc.dg/attr-nonstring-4.c +++ b/gcc/testsuite/gcc.dg/attr-nonstring-4.c @@ -40,7 +40,7 @@ void strnlen_cst (void) T (NS, /* [] */, n); T (NS, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ - T (NS, 9, n); /* { dg-warning "specified bound \[0-9\]+ exceeds source size 9" } */ + T (NS, 9, n); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\d+|specified bound \\d+ exceeds source size 9" } */ T (NS, 10, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ } @@ -59,6 +59,6 @@ void strnlen_range (void) T (NS, /* [] */, n); T (NS, /* [] */, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */ - T (NS, 9, n); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 9" } */ + T (NS, 9, n); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[\\d+, \\d+]|specified bound \\\[\\d+, \\d+] exceeds source size 9" } */ T (NS, 10, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */ } diff --git a/gcc/testsuite/gcc.dg/sso-14.c b/gcc/testsuite/gcc.dg/sso-14.c index 8941946..aeff3fb 100644 --- a/gcc/testsuite/gcc.dg/sso-14.c +++ b/gcc/testsuite/gcc.dg/sso-14.c @@ -46,10 +46,10 @@ int main(void) int same; msg1 = malloc (sizeof (t_s12)); - msg2 = malloc (sizeof (t_u12)); + msg2 = malloc (sizeof (t_s12)); memset (msg1, 0, sizeof (t_s12)); - memcpy (msg2, &msg1, sizeof (t_s12)); + memcpy (msg2, msg1, sizeof (t_s12)); same = memcmp (msg1, msg2, sizeof (t_s12)); return 0; -- cgit v1.1 From 848bcda52d7431c3be9c33c9803928ae7c54583a Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 9 Aug 2021 12:02:53 +0100 Subject: Improve handling of unknown sign bit in CCP. This middle-end patch implements several related improvements to tree-ssa's conditional (bit) constant propagation pass. The current code handling ordered comparisons contains the comment "If the most significant bits are not known we know nothing" which is not entirely true [this test even prevents this pass understanding these comparisons always have a zero or one result]. This patch introduces a new value_mask_to_min_max helper function, that understands the different semantics of the most significant bit on signed vs. unsigned values. This allows us to generalize ordered comparisons, GE_EXPR, GT_EXPR, LE_EXPR and LT_EXPR, where to code is tweaked to correctly handle the potential equal cases. Then finally support is added for the related tree codes MIN_EXPR, MAX_EXPR, ABS_EXPR and ABSU_EXPR. Regression testing revealed three test cases in the testsuite that were checking for specific optimizations that are now being performed earlier than expected. These tests can continue to check their original transformations by explicitly adding -fno-tree-ccp to their dg-options (some already specify -fno-ipa-vrp or -fno-tree-forwprop for the same reason). 2021-08-09 Roger Sayle gcc/ChangeLog * tree-ssa-ccp.c (value_mask_to_min_max): Helper function to determine the upper and lower bounds from a mask-value pair. (bit_value_unop) [ABS_EXPR, ABSU_EXPR]: Add support for absolute value and unsigned absolute value expressions. (bit_value_binop): Initialize *VAL's precision. [LT_EXPR, LE_EXPR]: Use value_mask_to_min_max to determine upper and lower bounds of operands. Add LE_EXPR/GE_EXPR support when the operands are unknown but potentially equal. [MIN_EXPR, MAX_EXPR]: Support minimum/maximum expressions. gcc/testsuite/ChangeLog * gcc.dg/pr68217.c: Add -fno-tree-ccp option. * gcc.dg/tree-ssa/vrp24.c: Add -fno-tree-ccp option. * g++.dg/ipa/pure-const-3.C: Add -fno-tree-ccp option. --- gcc/testsuite/gcc.dg/pr68217.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp24.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr68217.c b/gcc/testsuite/gcc.dg/pr68217.c index c5b0d1f..eb4f15e 100644 --- a/gcc/testsuite/gcc.dg/pr68217.c +++ b/gcc/testsuite/gcc.dg/pr68217.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fno-tree-ccp" } */ int foo (void) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c index dfe44b3..91015da 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-evrp-details -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-evrp-details -fdump-tree-optimized -fno-tree-ccp" } */ struct rtx_def; -- cgit v1.1 From d55d3f5b04e81b79f34ccf23f7e2c1e736ad3b0d Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 9 Aug 2021 17:35:39 +0200 Subject: ipa: Fix testsuite/gcc.dg/ipa/remref-6.c I forgot to add -fdump-ipa-inline to options of testsuite/gcc.dg/ipa/remref-6.c and so the dump scan test were not PASSing but ended up as UNRESOLVED. Fixing that revealed that the one of the dumps it was looking for had a double space, so I removed it too. gcc/ChangeLog: 2021-08-09 Martin Jambor PR testsuite/101654 * ipa-prop.c (propagate_controlled_uses): Removed a spurious space. gcc/testsuite/ChangeLog: 2021-08-09 Martin Jambor PR testsuite/101654 * gcc.dg/ipa/remref-6.c: Added missing -fdump-ipa-inline option. --- gcc/testsuite/gcc.dg/ipa/remref-6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/remref-6.c b/gcc/testsuite/gcc.dg/ipa/remref-6.c index de36493..7deae31 100644 --- a/gcc/testsuite/gcc.dg/ipa/remref-6.c +++ b/gcc/testsuite/gcc.dg/ipa/remref-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-early-inlining -fno-ipa-cp -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fno-early-inlining -fno-ipa-cp -fdump-ipa-inline -fdump-tree-optimized" } */ static double global = 0.0; -- cgit v1.1 From c86c95edd165d674614516cda0b1fcb6616c1096 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 9 Aug 2021 15:53:42 -0400 Subject: Ensure toupper and tolower follow the expected pattern. If the parameter is not compatible with the LHS, assume this is not really a builtin function to avoid a trap. gcc/ PR tree-optimization/101741 * gimple-range-fold.cc (fold_using_range::range_of_builtin_call): Check type of parameter for toupper/tolower. gcc/testsuite/ * gcc.dg/pr101741.c: New. --- gcc/testsuite/gcc.dg/pr101741.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101741.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101741.c b/gcc/testsuite/gcc.dg/pr101741.c new file mode 100644 index 0000000..6587dca --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101741.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/101741 */ +/* { dg-do compile } */ +/* { dg-options "-O2 " } */ + +int +foo (void); + +unsigned int +toupper (int c) +{ + c = foo (); + while (c) + c = toupper (c); + + return c; +} -- cgit v1.1 From 0631faf87a197145acd833249bf8f20a1c4aaabf Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Tue, 10 Aug 2021 07:42:51 +0200 Subject: Evaluate arguments of sizeof that are structs of variable size. Evaluate arguments of sizeof for all types of variable size and not just for VLAs. This fixes some issues related to [PR29970] where statement expressions need to be evaluated so that the size is well defined. 2021-08-10 Martin Uecker gcc/c/ PR c/29970 * c-typeck.c (c_expr_sizeof_expr): Evaluate size expressions for structs of variable size. gcc/testsuite/ PR c/29970 * gcc.dg/vla-stexp-1.c: New test. --- gcc/testsuite/gcc.dg/vla-stexp-1.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vla-stexp-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vla-stexp-1.c b/gcc/testsuite/gcc.dg/vla-stexp-1.c new file mode 100644 index 0000000..97d6693 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-stexp-1.c @@ -0,0 +1,18 @@ +/* PR29970*/ +/* { dg-do run } */ +/* { dg-options "-Wall -O0" } */ + +int foo(void) +{ + int n = 0; + return sizeof(*({ n = 10; struct foo { int x[n]; } x; &x; })); +} + + +int main() +{ + if (sizeof(struct foo { int x[10]; }) != foo()) + __builtin_abort(); + + return 0; +} -- cgit v1.1 From bb169406cdc9e044eaec500dd742c2fed40f5488 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 9 Aug 2021 10:19:10 +0200 Subject: middle-end/101824 - properly handle volatiles in nested fn lowering When we build the COMPONENT_REF of a formerly volatile local off the FRAME decl we have to make sure to mark the COMPONENT_REF as TREE_THIS_VOLATILE. While the GIMPLE operand scanner looks at the FIELD_DECL this is not how volatile GENERIC refs work. 2021-08-09 Richard Biener PR middle-end/101824 * tree-nested.c (get_frame_field): Mark the COMPONENT_REF as volatile in case the variable was. * gcc.dg/tree-ssa/pr101824.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/pr101824.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr101824.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101824.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101824.c new file mode 100644 index 0000000..d5987e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101824.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-pcom-details -fdump-tree-optimized" } */ + +int main() +{ + volatile int y; + void bar() + { + __builtin_printf ("%d", y); + } + while (y) + ; + return 0; +} + +/* Make sure the load from y is correctly interpreted as volatile, even + when going through FRAME. */ +/* { dg-final { scan-tree-dump-not "Executing predictive commoning" "pcom" } } */ +/* { dg-final { scan-tree-dump " ={v} FRAME" "optimized" } } */ -- cgit v1.1 From 92f7016940e5a7281e3fd7628fbf1360d900b581 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Wed, 11 Aug 2021 01:40:12 +0200 Subject: gcc.dg/uninit-pred-9_b.c: Xfail for CRIS too Adding to the growing list, for autotester accounting purposes. FWIW I see this fails for m68k too: https://gcc.gnu.org/pipermail/gcc-testresults/2021-August/712395.html and moxie: https://gcc.gnu.org/pipermail/gcc-testresults/2021-August/712389.html and pru: https://gcc.gnu.org/pipermail/gcc-testresults/2021-August/712366.html testsuite: PR middle-end/101674 * gcc.dg/uninit-pred-9_b.c: Xfail for cris-*-* too. --- gcc/testsuite/gcc.dg/uninit-pred-9_b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c index 9383c55..8c2d28c 100644 --- a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c +++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c @@ -20,7 +20,7 @@ int foo (int n, int l, int m, int r) blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ if ( (n <= 8) && (m < 99) && (r < 19) ) - blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail powerpc64*-*-* mmix-*-* } } */ + blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail powerpc64*-*-* mmix-*-* cris-*-* } } */ return 0; } -- cgit v1.1 From d7e91f4894f6a1a2daeec5cbe1e912bb896b9f7a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 11 Aug 2021 10:26:18 +0200 Subject: middle-end/101858 - avoid shift of pointer in folding This makes sure to not generate a shift of pointer types in simplification of X < (cast) (1 << Y). 2021-08-11 Richard Biener PR middle-end/101858 * fold-const.c (fold_binary_loc): Guard simplification of X < (cast) (1 << Y) to integer types. * gcc.dg/pr101858.c: New testcase. --- gcc/testsuite/gcc.dg/pr101858.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101858.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101858.c b/gcc/testsuite/gcc.dg/pr101858.c new file mode 100644 index 0000000..61fcca6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101858.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-w" } */ + +int foo(int a) +{ + if (a < (int*)((__INTPTR_TYPE__)1 << a)) + a = 0; + return a; +} -- cgit v1.1 From cba64d855df581cc26fa487162027138aef4dbe5 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 11 Aug 2021 16:28:33 +0200 Subject: Fix gcc.dg/lto/pr48622_0.c testcase This fixes the testcase to not rely on the reference to ashift_qi_1 being optimized out by RTL optimization via help of the initregs pass that changes comparisons of uninitialized data with a comparison that is always false. 2021-08-11 Richard Biener * gcc.dg/lto/pr48622_1.c: Provide non-LTO definition of ashift_qi_1. --- gcc/testsuite/gcc.dg/lto/pr48622_1.c | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/lto/pr48622_1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/lto/pr48622_1.c b/gcc/testsuite/gcc.dg/lto/pr48622_1.c new file mode 100644 index 0000000..4d05bae --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr48622_1.c @@ -0,0 +1,6 @@ +/* { dg-options "-fno-lto" } */ + +typedef unsigned int u8 __attribute__ ((mode (QI))); +u8 ashift_qi_1 (u8) +{ +} -- cgit v1.1 From 34cd97ff94bdb43e8c9de150f1d89527fc42138e Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 5 Aug 2021 08:01:47 +0200 Subject: Remove legacy back threader. At this point I don't see any use for the legacy mode, which I had originally left in place during the transition. This patch removes the legacy back threader, and cleans up the code a bit. There are no functional changes to the non-legacy code. Tested on x86-64 Linux. gcc/ChangeLog: * doc/invoke.texi: Remove docs for threader-mode param. * flag-types.h (enum threader_mode): Remove. * params.opt: Remove threader-mode param. * tree-ssa-threadbackward.c (class back_threader): Remove path_is_unreachable_p. Make find_paths private. Add maybe_thread and thread_through_all_blocks. Remove reference marker for m_registry. Remove reference marker for m_profit. (back_threader::back_threader): Adjust for registry and profit not being references. (dump_path): Move down. (debug): Move down. (class thread_jumps): Remove. (class back_threader_registry): Remove m_all_paths. Remove destructor. (thread_jumps::thread_through_all_blocks): Move to back_threader class. (fsm_find_thread_path): Remove (back_threader::maybe_thread): New. (back_threader::thread_through_all_blocks): Move from thread_jumps. (back_threader_registry::back_threader_registry): Remove m_all_paths. (back_threader_registry::~back_threader_registry): Remove. (thread_jumps::find_taken_edge): Remove. (thread_jumps::check_subpath_and_update_thread_path): Remove. (thread_jumps::maybe_register_path): Remove. (thread_jumps::handle_phi): Remove. (handle_assignment_p): Remove. (thread_jumps::handle_assignment): Remove. (thread_jumps::fsm_find_control_statement_thread_paths): Remove. (thread_jumps::find_jump_threads_backwards): Remove. (thread_jumps::find_jump_threads_backwards_with_ranger): Remove. (try_thread_blocks): Rename find_jump_threads_backwards to maybe_thread. (pass_early_thread_jumps::execute): Same. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Remove call into the legacy code and adjust for ranger threader. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index 1c2d12a..5fc2145 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-dom2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */ -/* { dg-additional-options "--param=threader-mode=legacy" } */ /* Here we have the same issue as was commented in ssa-dom-thread-6.c. The PHI coming into the threader has a lot more constants, so the @@ -17,7 +16,7 @@ $ diff clean/a.c.105t.mergephi2 a.c.105t.mergephi2 basically tracking the switch index better through multiple paths. */ -/* { dg-final { scan-tree-dump "Jumps threaded: 19" "thread1" } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread1" } } */ /* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" } } */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom2" } } */ -- cgit v1.1 From d2ba65ab6010f0d507bf5512a0223692e6653b23 Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Thu, 12 Aug 2021 20:32:16 +0200 Subject: Evaluate type arguments of sizeof that are structs of variable size [PR101838] Evaluate type arguments of sizeof for all types of variable size and not just for VLAs. This fixes PR101838 and some issues related to PR29970 where statement expressions need to be evaluated so that the size is well defined. 2021-08-12 Martin Uecker gcc/c/ PR c/101838 PR c/29970 * c-typeck.c (c_expr_sizeof_type): Evaluate size expressions for structs of variable size. gcc/testsuite/ PR c/101838 * gcc.dg/vla-stexp-2.c: New test. --- gcc/testsuite/gcc.dg/vla-stexp-2.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vla-stexp-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vla-stexp-2.c b/gcc/testsuite/gcc.dg/vla-stexp-2.c new file mode 100644 index 0000000..176f400 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-stexp-2.c @@ -0,0 +1,33 @@ +/* PR101838 */ +/* { dg-do run } */ +/* { dg-options "-Wpedantic -O0" } */ + + +int bar0( + int (*a)[*], + int (*b)[sizeof(*a)] +); + + +int bar( + struct f { /* { dg-warning "will not be visible outside of this definition" } */ + int a[*]; } v, /* { dg-warning "variably modified type" } */ + int (*b)[sizeof(struct f)] // should not warn about zero size +); + +int foo(void) +{ + int n = 0; + return sizeof(typeof(*({ n = 10; struct foo { /* { dg-warning "braced-groups" } */ + int x[n]; /* { dg-warning "variably modified type" } */ + } x; &x; }))); +} + + +int main() +{ + if (sizeof(struct foo { int x[10]; }) != foo()) + __builtin_abort(); + + return 0; +} -- cgit v1.1 From 408d88af60e3268f7fad59fa393ec7e28922c435 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Aug 2021 22:38:18 +0200 Subject: libcpp: Fix ICE with -Wtraditional preprocessing [PR101638] The following testcase ICEs in cpp_sys_macro_p, because cpp_sys_macro_p is called for a builtin macro which doesn't use node->value.macro union member but a different one and so dereferencing it ICEs. As the testcase is distilled from contemporary glibc headers, it means basically -Wtraditional now ICEs on almost everything. The fix can be either the patch below, return true for builtin macros, or we could instead return false for builtin macros, or the fix could be also (untested): --- libcpp/expr.c 2021-05-07 10:34:46.345122608 +0200 +++ libcpp/expr.c 2021-08-12 09:54:01.837556365 +0200 @@ -783,13 +783,13 @@ cpp_classify_number (cpp_reader *pfile, /* Traditional C only accepted the 'L' suffix. Suppress warning about 'LL' with -Wno-long-long. */ - if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile)) + if (CPP_WTRADITIONAL (pfile)) { int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY)); int large = (result & CPP_N_WIDTH) == CPP_N_LARGE && CPP_OPTION (pfile, cpp_warn_long_long); - if (u_or_i || large) + if ((u_or_i || large) && ! cpp_sys_macro_p (pfile)) cpp_warning_with_line (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL, virtual_location, 0, "traditional C rejects the \"%.*s\" suffix", The builtin macros at least currently don't add any suffixes or numbers -Wtraditional would like to warn about. For floating point suffixes, -Wtraditional calls cpp_sys_macro_p only right away before emitting the warning, but in the above case the ICE is because cpp_sys_macro_p is called even if the number doesn't have any suffixes (that is I think always for builtin macros right now). 2021-08-12 Jakub Jelinek PR preprocessor/101638 * macro.c (cpp_sys_macro_p): Return true instead of crashing on builtin macros. * gcc.dg/cpp/pr101638.c: New test. --- gcc/testsuite/gcc.dg/cpp/pr101638.c | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/cpp/pr101638.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/cpp/pr101638.c b/gcc/testsuite/gcc.dg/cpp/pr101638.c new file mode 100644 index 0000000..1030473 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr101638.c @@ -0,0 +1,7 @@ +/* PR preprocessor/101638 */ +/* { dg-do preprocess } */ +/* { dg-options "-Wtraditional" } */ + +#define foo(attr) __has_attribute(attr) +#if foo(__deprecated__) +#endif -- cgit v1.1 From d0befed793b94f3f407be44e6f69f81a02f5f073 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Aug 2021 22:41:17 +0200 Subject: openmp: Add support for OpenMP 5.1 masked construct This construct has been introduced as a replacement for master construct, but unlike that construct is slightly more general, has an optional clause which allows to choose which thread will be the one running the region, it can be some other thread than the master (primary) thread with number 0, or it could be no threads or multiple threads (then of course one needs to be careful about data races). It is way too early to deprecate the master construct though, we don't even have OpenMP 5.0 fully implemented, it has been deprecated in 5.1, will be also in 5.2 and removed in 6.0. But even then it will likely be a good idea to just -Wdeprecated warn about it and still accept it. The patch also contains something I should have done much earlier, for clauses that accept some integral expression where we only care about the value, forces during gimplification that value into either a min invariant (as before), SSA_NAME or a fresh temporary, but never e.g. a user VAR_DECL, so that for those clauses we don't need to worry about adjusting it. 2021-08-12 Jakub Jelinek gcc/ * tree.def (OMP_MASKED): New tree code. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_FILTER. * tree.h (OMP_MASKED_BODY, OMP_MASKED_CLAUSES, OMP_MASKED_COMBINED, OMP_CLAUSE_FILTER_EXPR): Define. * tree.c (omp_clause_num_ops): Add OMP_CLAUSE_FILTER entry. (omp_clause_code_name): Likewise. (walk_tree_1): Handle OMP_CLAUSE_FILTER. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Handle OMP_CLAUSE_FILTER. (convert_nonlocal_reference_stmt, convert_local_reference_stmt, convert_gimple_call): Handle GIMPLE_OMP_MASTER. * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_FILTER. (dump_generic_node): Handle OMP_MASTER. * gimple.def (GIMPLE_OMP_MASKED): New gimple code. * gimple.c (gimple_build_omp_masked): New function. (gimple_copy): Handle GIMPLE_OMP_MASKED. * gimple.h (gimple_build_omp_masked): Declare. (gimple_has_substatements): Handle GIMPLE_OMP_MASKED. (gimple_omp_masked_clauses, gimple_omp_masked_clauses_ptr, gimple_omp_masked_set_clauses): New inline functions. (CASE_GIMPLE_OMP): Add GIMPLE_OMP_MASKED. * gimple-pretty-print.c (dump_gimple_omp_masked): New function. (pp_gimple_stmt_1): Handle GIMPLE_OMP_MASKED. * gimple-walk.c (walk_gimple_stmt): Likewise. * gimple-low.c (lower_stmt): Likewise. * gimplify.c (is_gimple_stmt): Handle OMP_MASTER. (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_FILTER. For clauses that take one expression rather than decl or constant, force gimplification of that into a SSA_NAME or temporary unless min invariant. (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_FILTER. (gimplify_expr): Handle OMP_MASKED. * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_MASKED. (estimate_num_insns): Likewise. * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_FILTER. (check_omp_nesting_restrictions): Handle GIMPLE_OMP_MASKED. Adjust diagnostics for existence of masked construct. (scan_omp_1_stmt, lower_omp_master, lower_omp_1, diagnose_sb_1, diagnose_sb_2): Handle GIMPLE_OMP_MASKED. * omp-expand.c (expand_omp_synch, expand_omp, omp_make_gimple_edges): Likewise. gcc/c-family/ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_MASKED. (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_FILTER. * c-pragma.c (omp_pragmas_simd): Add masked construct. * c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_MASKED enumerator. (c_finish_omp_masked): Declare. * c-omp.c (c_finish_omp_masked): New function. (c_omp_split_clauses): Handle combined masked constructs. gcc/c/ * c-parser.c (c_parser_omp_clause_name): Parse filter clause name. (c_parser_omp_clause_filter): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER. (OMP_MASKED_CLAUSE_MASK): Define. (c_parser_omp_masked): New function. (c_parser_omp_parallel): Handle parallel masked. (c_parser_omp_construct): Handle PRAGMA_OMP_MASKED. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_FILTER. gcc/cp/ * parser.c (cp_parser_omp_clause_name): Parse filter clause name. (cp_parser_omp_clause_filter): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER. (OMP_MASKED_CLAUSE_MASK): Define. (cp_parser_omp_masked): New function. (cp_parser_omp_parallel): Handle parallel masked. (cp_parser_omp_construct, cp_parser_pragma): Handle PRAGMA_OMP_MASKED. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_FILTER. * pt.c (tsubst_omp_clauses): Likewise. (tsubst_expr): Handle OMP_MASKED. gcc/testsuite/ * c-c++-common/gomp/clauses-1.c (bar): Add tests for combined masked constructs with clauses. * c-c++-common/gomp/clauses-5.c (foo): Add testcase for filter clause. * c-c++-common/gomp/clause-dups-1.c (f1): Likewise. * c-c++-common/gomp/masked-1.c: New test. * c-c++-common/gomp/masked-2.c: New test. * c-c++-common/gomp/masked-combined-1.c: New test. * c-c++-common/gomp/masked-combined-2.c: New test. * c-c++-common/goacc/uninit-if-clause.c: Remove xfails. * g++.dg/gomp/block-11.C: New test. * g++.dg/gomp/tpl-masked-1.C: New test. * g++.dg/gomp/attrs-1.C (bar): Add tests for masked construct and combined masked constructs with clauses in attribute syntax. * g++.dg/gomp/attrs-2.C (bar): Likewise. * gcc.dg/gomp/nesting-1.c (f1, f2): Add tests for masked construct nesting. * gfortran.dg/goacc/host_data-tree.f95: Allow also SSA_NAMEs in if clause. * gfortran.dg/goacc/kernels-tree.f95: Likewise. libgomp/ * testsuite/libgomp.c-c++-common/masked-1.c: New test. --- gcc/testsuite/gcc.dg/gomp/nesting-1.c | 39 +++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/nesting-1.c b/gcc/testsuite/gcc.dg/gomp/nesting-1.c index 52fcda7..4a471c8 100644 --- a/gcc/testsuite/gcc.dg/gomp/nesting-1.c +++ b/gcc/testsuite/gcc.dg/gomp/nesting-1.c @@ -19,8 +19,10 @@ f1 (void) } #pragma omp single /* { dg-error "may not be closely nested" } */ ; - #pragma omp master /* { dg-error "may not be closely nested" } */ - ; + #pragma omp master /* { dg-error "may not be closely nested" } */ + ; + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } #pragma omp sections @@ -50,6 +52,11 @@ f1 (void) } #pragma omp sections { + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; + } + #pragma omp sections + { #pragma omp section ; } @@ -81,6 +88,9 @@ f1 (void) #pragma omp section #pragma omp master /* { dg-error "may not be closely nested" } */ ; + #pragma omp section + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; } #pragma omp single { @@ -97,6 +107,8 @@ f1 (void) ; #pragma omp master /* { dg-error "may not be closely nested" } */ ; + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } #pragma omp master @@ -116,6 +128,23 @@ f1 (void) ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } + #pragma omp masked filter (1) + { + #pragma omp for /* { dg-error "may not be closely nested" } */ + for (j = 0; j < 3; j++) + ; + #pragma omp sections /* { dg-error "may not be closely nested" } */ + { + ; + #pragma omp section + ; + } + #pragma omp single /* { dg-error "may not be closely nested" } */ + ; + #pragma omp master + ; + #pragma omp barrier /* { dg-error "may not be closely nested" } */ + } #pragma omp task { #pragma omp for /* { dg-error "may not be closely nested" } */ @@ -131,6 +160,8 @@ f1 (void) ; #pragma omp master /* { dg-error "may not be closely nested" } */ ; + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } #pragma omp parallel @@ -148,6 +179,8 @@ f1 (void) ; #pragma omp master ; + #pragma omp masked + ; #pragma omp barrier } } @@ -171,6 +204,8 @@ f2 (void) ; #pragma omp master ; + #pragma omp masked + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } } -- cgit v1.1 From 4341b1b165751e728692eec12405fc04b2c681aa Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 13 Aug 2021 10:04:52 +0200 Subject: Introduce EAF_NOREAD and cleanup EAF_UNUSED + ipa-modref this patch add EAF_NOREAD (as disucssed on IRC already) and fixes meaning of EAF_UNUSED to be really unused and not "does not escape, is not clobbered, read or returned" since we have separate flags for each of the properties now. Since number of flags has grown I refactored the code a bit to avoid repeated uses of complex flag combinations and also simplified the logic of merging. Merging is bit tricky since we have flags that implies other flags (like NOESCAPE implies NODIRECTESCAPE) but code that sets only NOESCAPE. Perhaps it would make sense to update fnspecs to always set flag along with all the implications, but for now I am handlingit in merge. I made only trivial update to tree-ssa-structalias to handle EAF_NORETURN in normal function handling, but not in pure functions. The problem is that the way constraints are generated for pure functions makes this difficult. I think logical step is to track whether function reads/stores global memory and rewrite the constraint generation so we can handle normal, pure and const in unified manner. Bootstrapped/regtested x86_64-linux, plan to commit it after furhter testing. The patch improves alias oracle stats for cc1plus somewhat. From: Alias oracle query stats: refs_may_alias_p: 72380497 disambiguations, 82649832 queries ref_maybe_used_by_call_p: 495184 disambiguations, 73366950 queries call_may_clobber_ref_p: 259312 disambiguations, 263253 queries nonoverlapping_component_refs_p: 0 disambiguations, 38006 queries nonoverlapping_refs_since_match_p: 21157 disambiguations, 65698 must overlaps, 87756 queries aliasing_component_refs_p: 63141 disambiguations, 2164695 queries TBAA oracle: 25975753 disambiguations 61449632 queries 12138220 are in alias set 0 11316663 queries asked about the same object 144 queries asked about the same alias set 0 access volatile 10472885 are dependent in the DAG 1545967 are aritificially in conflict with void * Modref stats: modref use: 23857 disambiguations, 754515 queries modref clobber: 1392162 disambiguations, 17753512 queries 3450241 tbaa queries (0.194341 per modref query) 534816 base compares (0.030125 per modref query) PTA query stats: pt_solution_includes: 12394915 disambiguations, 20235925 queries pt_solutions_intersect: 1365299 disambiguations, 14638068 queries To: Alias oracle query stats: refs_may_alias_p: 72629640 disambiguations, 82903333 queries ref_maybe_used_by_call_p: 502474 disambiguations, 73612186 queries call_may_clobber_ref_p: 261806 disambiguations, 265659 queries nonoverlapping_component_refs_p: 0 disambiguations, 38007 queries nonoverlapping_refs_since_match_p: 21139 disambiguations, 65772 must overlaps, 87816 queries aliasing_component_refs_p: 63144 disambiguations, 2164330 queries TBAA oracle: 26059018 disambiguations 61571714 queries 12158033 are in alias set 0 11326115 queries asked about the same object 144 queries asked about the same alias set 0 access volatile 10484493 are dependent in the DAG 1543911 are aritificially in conflict with void * Modref stats: modref use: 24008 disambiguations, 712712 queries modref clobber: 1395917 disambiguations, 17163694 queries 3465657 tbaa queries (0.201918 per modref query) 537591 base compares (0.031321 per modref query) PTA query stats: pt_solution_includes: 12468934 disambiguations, 20295402 queries pt_solutions_intersect: 1391917 disambiguations, 14665265 queries I think it is mostly due to better heandling of EAF_NODIRECTESCAPE. Honza gcc/ChangeLog: 2021-08-12 Jan Hubicka * ipa-modref.c (dump_eaf_flags): Dump EAF_NOREAD. (implicit_const_eaf_flags, implicit_pure_eaf_flags, ignore_stores_eaf_flags): New constants. (remove_useless_eaf_flags): New function. (eaf_flags_useful_p): Use it. (deref_flags): Add EAF_NOT_RETURNED if flag is unused; handle EAF_NOREAD. (modref_lattice::init): Add EAF_NOREAD. (modref_lattice::add_escape_point): Do not reacord escape point if result is unused. (modref_lattice::merge): EAF_NOESCAPE implies EAF_NODIRECTESCAPE; use remove_useless_eaf_flags. (modref_lattice::merge_deref): Use ignore_stores_eaf_flags. (modref_lattice::merge_direct_load): Add EAF_NOREAD (analyze_ssa_name_flags): Fix handling EAF_NOT_RETURNED (analyze_parms): Use remove_useless_eaf_flags. (ipa_merge_modref_summary_after_inlining): Use ignore_stores_eaf_flags. (modref_merge_call_site_flags): Add caller and ecf_flags parameter; use remove_useless_eaf_flags. (modref_propagate_flags_in_scc): Update. * ipa-modref.h: Turn eaf_flags_t back to char. * tree-core.h (EAF_NOT_RETURNED): Fix. (EAF_NOREAD): New constant * tree-ssa-alias.c: (ref_maybe_used_by_call_p_1): Check for EAF_NOREAD. * tree-ssa-structalias.c (handle_rhs_call): Handle new flags. (handle_pure_call): Likewise. gcc/testsuite/ChangeLog: 2021-08-12 Jan Hubicka * gcc.dg/tree-ssa/modref-6.c: Update. --- gcc/testsuite/gcc.dg/tree-ssa/modref-6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c index 8db9a1d..2d97a49 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-6.c @@ -32,6 +32,6 @@ int test2() /* Flags for pure call. */ /* { dg-final { scan-tree-dump "parm 0 flags: direct not_returned" "modref1" } } */ /* Flags for const call. */ -/* { dg-final { scan-tree-dump "parm 0 flags: unused not_returned" "modref1" } } */ +/* { dg-final { scan-tree-dump "parm 0 flags: not_returned" "modref1" } } */ /* Overall we want to make "int a" non escaping. */ /* { dg-final { scan-tree-dump "return 42" "optimized" } } */ -- cgit v1.1 From fb85d6eb6c392e829d1ee5b8a2e2b81c53c9840f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 13 Aug 2021 12:21:20 -0600 Subject: Warn for reads from write-only arguments [PR101734]. Resolves: PR middle-end/101734 - missing warning reading from a write-only object gcc/ChangeLog: PR middle-end/101734 * tree-ssa-uninit.c (maybe_warn_read_write_only): New function. (maybe_warn_operand): Call it. gcc/testsuite/ChangeLog: PR middle-end/101734 * gcc.dg/uninit-42.c: New test. --- gcc/testsuite/gcc.dg/uninit-42.c | 87 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/uninit-42.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/uninit-42.c b/gcc/testsuite/gcc.dg/uninit-42.c new file mode 100644 index 0000000..efaaacd --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-42.c @@ -0,0 +1,87 @@ +/* PR middle-end/101734 - missing warning reading from a write-only object + Verify that reading objects pointed to by arguments + declared with attribute access none or write-only is diagnosed by + -Wmaybe-uninitialized. + { dg-do compile } + { dg-options "-Wall" } */ + +#define A(mode, ...) __attribute__ ((access (mode, __VA_ARGS__))) + +void sink (void *, ...); + + +A (write_only, 1, 2) +int nowarn_wo_assign_r0 (int *p, int n) +{ + *p = n; + return *p; +} + +A (write_only, 1, 2) +int nowarn_wo_sink_r0 (int *p, int n) +{ + sink (p, p + 1, p + n); + return *p; +} + +A (write_only, 1, 2) +int warn_wo_r0 (int *p, int n) +{ + return *p; // { dg-warning "'\\*p' may be used uninitialized \\\[-Wmaybe-uninitialized" } +} + + +A (write_only, 1, 2) +int nowarn_wo_w1_r1 (int *p, int n) +{ + p[1] = n; + return p[1]; +} + +A (write_only, 1, 2) +int warn_wo_r1 (int *p, int n) +{ + return p[1]; // { dg-warning "'p\\\[1]' may be used uninitialized" } +} + + +A (write_only, 1, 2) +int nowarn_wo_rwi_rj (int *p, int n, int i, int j) +{ + p[i] = n; + return p[j]; +} + +A (write_only, 1, 2) + int warn_wo_ri (int *p, int n, int i) +{ + return p[i]; // { dg-warning " may be used uninitialized" } +} + + + +A (none, 1, 2) +int* nowarn_none_sink_return (int *p, int n) +{ + sink (p, p + 1, p + n); + return p; +} + +A (none, 1, 2) +int warn_none_r0 (int *p, int n) +{ + (void)&n; + return *p; // { dg-warning "'\\*p' may be used uninitialized" } +} + +A (none, 1, 2) +int warn_none_r1 (int *p, int n) +{ + return p[1]; // { dg-warning "'p\\\[1]' may be used uninitialized" } +} + +A (write_only, 1, 2) +int warn_none_ri (int *p, int n, int i) +{ + return p[i]; // { dg-warning " may be used uninitialized" } +} -- cgit v1.1 From b0de3ad2620d665ab481c2f24204f77f386ff6b2 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 13 Aug 2021 12:35:47 +0200 Subject: ipa: ICF should check SSA_NAME_IS_DEFAULT_DEF PR ipa/100600 gcc/ChangeLog: * ipa-icf-gimple.c (func_checker::compare_ssa_name): Do not consider equal SSA_NAMEs when one is a param. gcc/testsuite/ChangeLog: * gcc.dg/ipa/pr100600.c: New test. --- gcc/testsuite/gcc.dg/ipa/pr100600.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr100600.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/pr100600.c b/gcc/testsuite/gcc.dg/ipa/pr100600.c new file mode 100644 index 0000000..8a3d0e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr100600.c @@ -0,0 +1,22 @@ +/* PR ipa/100600 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int a, b, c; +long d(long x, long e, long f, long g) { + long h, i; + for (; h < e; h++) { + i = f; + for (; i < g; i++) + c = b + a; + } + return h + i; +} + +long j(long x, long e, long y, long g) { + long h, i; + for (; h < e; h++) + for (; i < g; i++) + c = b + a; + return h + i; +} -- cgit v1.1 From 0215b3559e55f39f38e10984a804c53907f7491c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 16 Aug 2021 15:17:08 +0200 Subject: tree-optimization/101925 - fix VN with reverse storage order This fixes value-numbering breaking reverse storage order accesses due to a missed check. It adds a new overload for reverse_storage_order_for_component_p and sets reversed on the VN IL ops for component and array accesses accordingly. It also compares the reversed reference ops flag on reference lookup. 2021-08-16 Richard Biener PR tree-optimization/101925 * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Set reverse on COMPONENT_REF and ARRAY_REF according to what reverse_storage_order_for_component_p does. (vn_reference_eq): Compare reversed on reference ops. (reverse_storage_order_for_component_p): New overload. (vn_reference_lookup_3): Check reverse_storage_order_for_component_p on the reference looked up. * gcc.dg/sso-16.c: New testcase. --- gcc/testsuite/gcc.dg/sso-16.c | 100 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/sso-16.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/sso-16.c b/gcc/testsuite/gcc.dg/sso-16.c new file mode 100644 index 0000000..7bf8938 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-16.c @@ -0,0 +1,100 @@ +/* { dg-do run } */ +/* { dg-require-effective-target int32plus } */ +/* { dg-options "-O3" } */ + +typedef __INT32_TYPE__ int32_t; + +#define BIG_ENDIAN __attribute__((scalar_storage_order("big-endian"))) + +/* host order version (little endian)*/ +struct _ip6_addr { + union { + char addr8[16]; + int32_t addr32[4]; + } u; +}; + +typedef struct _ip6_addr t_ip6_addr; + +struct _net_addr { + char is_v4; + union { + int32_t addr; + t_ip6_addr addr6; + } u; +}; + +typedef struct _net_addr t_net_addr; + +/* big endian version */ +struct _be_ip6_addr { + union { + char addr8[16]; + } BIG_ENDIAN u; +} BIG_ENDIAN; + +typedef struct _be_ip6_addr t_be_ip6_addr; + +struct _be_net_addr { + char is_v4; + union { + t_be_ip6_addr addr6; + int32_t addr; + } BIG_ENDIAN u; +} BIG_ENDIAN; + +typedef struct _be_net_addr t_be_net_addr; + +/* convert */ +t_be_ip6_addr be_ip6_addr(const t_ip6_addr ip6) +{ + t_be_ip6_addr rc = { + .u.addr8[0] = ip6.u.addr8[0], + .u.addr8[1] = ip6.u.addr8[1], + .u.addr8[2] = ip6.u.addr8[2], + .u.addr8[3] = ip6.u.addr8[3], + .u.addr8[4] = ip6.u.addr8[4], + .u.addr8[5] = ip6.u.addr8[5], + .u.addr8[6] = ip6.u.addr8[6], + .u.addr8[7] = ip6.u.addr8[7], + .u.addr8[8] = ip6.u.addr8[8], + .u.addr8[9] = ip6.u.addr8[9], + .u.addr8[10] = ip6.u.addr8[10], + .u.addr8[11] = ip6.u.addr8[11], + .u.addr8[12] = ip6.u.addr8[12], + .u.addr8[13] = ip6.u.addr8[13], + .u.addr8[14] = ip6.u.addr8[14], + .u.addr8[15] = ip6.u.addr8[15], + }; + return rc; +} + +t_be_net_addr __attribute__((noipa)) be_net_addr(const t_net_addr ip) +{ + t_be_net_addr rc = {.is_v4 = ip.is_v4 }; + if (ip.is_v4) { + rc.u.addr = ip.u.addr; + } else { + rc.u.addr6 = be_ip6_addr(ip.u.addr6); + } + return rc; +} + +int main(void) +{ + t_be_net_addr out = { }; + + t_net_addr in = { + .is_v4 = 0, + .u.addr6.u.addr8 = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } + }; + + out = be_net_addr(in); + + // actually first 4 bytes are swapped + if (in.u.addr6.u.addr8[0] != out.u.addr6.u.addr8[0]) + __builtin_abort(); + + return 0; +} -- cgit v1.1 From e45483c7c4badc4bf2d6ced22360ce1ab172967f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 17 Aug 2021 09:30:09 +0200 Subject: openmp: Implement OpenMP 5.1 scope construct This patch implements the OpenMP 5.1 scope construct, which is similar to worksharing constructs in many regards, but isn't one of them. The body of the construct is encountered by all threads though, it can be nested in itself or intermixed with taskgroup and worksharing etc. constructs can appear inside of it (but it can't be nested in worksharing etc. constructs). The main purpose of the construct is to allow reductions (normal and task ones) without the need to close the parallel and reopen another one. If it doesn't have task reductions, it can be implemented without any new library support, with nowait it just does the privatizations at the start if any and reductions before the end of the body, with without nowait emits a normal GOMP_barrier{,_cancel} at the end too. For task reductions, we need to ensure only one thread initializes the task reduction library data structures and other threads copy from that, so a new GOMP_scope_start routine is added to the library for that. It acts as if the start of the scope construct is a nowait worksharing construct (that is ok, it can't be nested in other worksharing constructs and all threads need to encounter the start in the same order) which does the task reduction initialization, but as the body can have other scope constructs and/or worksharing constructs, that is all where we use this dummy worksharing construct. With task reductions, the construct must not have nowait and ends with a GOMP_barrier{,_cancel}, followed by task reductions followed by GOMP_workshare_task_reduction_unregister. Only C/C++ FE support is done. 2021-08-17 Jakub Jelinek gcc/ * tree.def (OMP_SCOPE): New tree code. * tree.h (OMP_SCOPE_BODY, OMP_SCOPE_CLAUSES): Define. * tree-nested.c (convert_nonlocal_reference_stmt, convert_local_reference_stmt, convert_gimple_call): Handle GIMPLE_OMP_SCOPE. * tree-pretty-print.c (dump_generic_node): Handle OMP_SCOPE. * gimple.def (GIMPLE_OMP_SCOPE): New gimple code. * gimple.c (gimple_build_omp_scope): New function. (gimple_copy): Handle GIMPLE_OMP_SCOPE. * gimple.h (gimple_build_omp_scope): Declare. (gimple_has_substatements): Handle GIMPLE_OMP_SCOPE. (gimple_omp_scope_clauses, gimple_omp_scope_clauses_ptr, gimple_omp_scope_set_clauses): New inline functions. (CASE_GIMPLE_OMP): Add GIMPLE_OMP_SCOPE. * gimple-pretty-print.c (dump_gimple_omp_scope): New function. (pp_gimple_stmt_1): Handle GIMPLE_OMP_SCOPE. * gimple-walk.c (walk_gimple_stmt): Likewise. * gimple-low.c (lower_stmt): Likewise. * gimplify.c (is_gimple_stmt): Handle OMP_MASTER. (gimplify_scan_omp_clauses): For task reductions, handle OMP_SCOPE like ORT_WORKSHARE constructs. Adjust diagnostics for % allowing task reductions. Reject inscan reductions on scope. (omp_find_stores_stmt): Handle GIMPLE_OMP_SCOPE. (gimplify_omp_workshare, gimplify_expr): Handle OMP_SCOPE. * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_SCOPE. (estimate_num_insns): Likewise. * omp-low.c (build_outer_var_ref): Look through GIMPLE_OMP_SCOPE contexts if var isn't privatized there. (check_omp_nesting_restrictions): Handle GIMPLE_OMP_SCOPE. (scan_omp_1_stmt): Likewise. (maybe_add_implicit_barrier_cancel): Look through outer scope constructs. (lower_omp_scope): New function. (lower_omp_task_reductions): Handle OMP_SCOPE. (lower_omp_1): Handle GIMPLE_OMP_SCOPE. (diagnose_sb_1, diagnose_sb_2): Likewise. * omp-expand.c (expand_omp_single): Support also GIMPLE_OMP_SCOPE. (expand_omp): Handle GIMPLE_OMP_SCOPE. (omp_make_gimple_edges): Likewise. * omp-builtins.def (BUILT_IN_GOMP_SCOPE_START): New built-in. gcc/c-family/ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_SCOPE. * c-pragma.c (omp_pragmas): Add scope construct. * c-omp.c (omp_directives): Uncomment scope directive entry. gcc/c/ * c-parser.c (OMP_SCOPE_CLAUSE_MASK): Define. (c_parser_omp_scope): New function. (c_parser_omp_construct): Handle PRAGMA_OMP_SCOPE. gcc/cp/ * parser.c (OMP_SCOPE_CLAUSE_MASK): Define. (cp_parser_omp_scope): New function. (cp_parser_omp_construct, cp_parser_pragma): Handle PRAGMA_OMP_SCOPE. * pt.c (tsubst_expr): Handle OMP_SCOPE. gcc/testsuite/ * c-c++-common/gomp/nesting-2.c (foo): Add scope and masked construct tests. * c-c++-common/gomp/scan-1.c (f3): Add scope construct test.. * c-c++-common/gomp/cancel-1.c (f2): Add scope and masked construct tests. * c-c++-common/gomp/reduction-task-2.c (bar): Add scope construct test. Adjust diagnostics for the addition of scope. * c-c++-common/gomp/loop-1.c (f5): Add master, masked and scope construct tests. * c-c++-common/gomp/clause-dups-1.c (f1): Add scope construct test. * gcc.dg/gomp/nesting-1.c (f1, f2, f3): Add scope construct tests. * c-c++-common/gomp/scope-1.c: New test. * c-c++-common/gomp/scope-2.c: New test. * g++.dg/gomp/attrs-1.C (bar): Add scope construct tests. * g++.dg/gomp/attrs-2.C (bar): Likewise. * gfortran.dg/gomp/reduction4.f90: Adjust expected diagnostics. * gfortran.dg/gomp/reduction7.f90: Likewise. libgomp/ * Makefile.am (libgomp_la_SOURCES): Add scope.c * Makefile.in: Regenerated. * libgomp_g.h (GOMP_scope_start): Declare. * libgomp.map: Add GOMP_scope_start@@GOMP_5.1. * scope.c: New file. * testsuite/libgomp.c-c++-common/scope-1.c: New test. * testsuite/libgomp.c-c++-common/task-reduction-16.c: New test. --- gcc/testsuite/gcc.dg/gomp/nesting-1.c | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/nesting-1.c b/gcc/testsuite/gcc.dg/gomp/nesting-1.c index 4a471c8..ed457ce 100644 --- a/gcc/testsuite/gcc.dg/gomp/nesting-1.c +++ b/gcc/testsuite/gcc.dg/gomp/nesting-1.c @@ -24,6 +24,8 @@ f1 (void) #pragma omp masked /* { dg-error "may not be closely nested" } */ ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } #pragma omp sections { @@ -57,6 +59,11 @@ f1 (void) } #pragma omp sections { + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; + } + #pragma omp sections + { #pragma omp section ; } @@ -92,6 +99,12 @@ f1 (void) #pragma omp masked /* { dg-error "may not be closely nested" } */ ; } + #pragma omp sections + { + #pragma omp section + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; + } #pragma omp single { #pragma omp for /* { dg-error "may not be closely nested" } */ @@ -110,6 +123,8 @@ f1 (void) #pragma omp masked /* { dg-error "may not be closely nested" } */ ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } #pragma omp master { @@ -127,6 +142,8 @@ f1 (void) #pragma omp master ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } #pragma omp masked filter (1) { @@ -144,6 +161,8 @@ f1 (void) #pragma omp master ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } #pragma omp task { @@ -163,6 +182,8 @@ f1 (void) #pragma omp masked /* { dg-error "may not be closely nested" } */ ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } #pragma omp parallel { @@ -182,6 +203,39 @@ f1 (void) #pragma omp masked ; #pragma omp barrier + #pragma omp scope + ; + #pragma omp scope + { + #pragma omp scope + ; + } + } + #pragma omp scope + { + #pragma omp for + for (j = 0; j < 3; j++) + ; + #pragma omp sections + { + ; + #pragma omp section + ; + } + #pragma omp single + ; + #pragma omp master + ; + #pragma omp masked + ; + #pragma omp barrier + #pragma omp scope + ; + #pragma omp scope + { + #pragma omp scope + ; + } } } @@ -207,6 +261,8 @@ f2 (void) #pragma omp masked ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } } @@ -217,6 +273,8 @@ f3 (void) { #pragma omp ordered /* { dg-error "may not be closely nested" } */ ; + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } } @@ -227,6 +285,8 @@ f4 (void) { #pragma omp ordered /* { dg-error "may not be closely nested" } */ ; + #pragma omp scope /* { dg-error "may not be closely nested" } */ + ; } } -- cgit v1.1 From 3ed779689631ff8f398dcde06d5efa2a3c43ef27 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 17 Aug 2021 11:23:06 +0200 Subject: tree-optimization/101868 - avoid PRE of trapping mems across calls This adds the testcase from the fix for the PR. 2021-08-17 Richard Biener PR tree-optimization/101868 * gcc.dg/lto/pr101868_0.c: New testcase. * gcc.dg/lto/pr101868_1.c: Likewise. * gcc.dg/lto/pr101868_2.c: Likewise. * gcc.dg/lto/pr101868_3.c: Likewise. --- gcc/testsuite/gcc.dg/lto/pr101868_0.c | 33 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/lto/pr101868_1.c | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/lto/pr101868_2.c | 11 +++++++++++ gcc/testsuite/gcc.dg/lto/pr101868_3.c | 8 ++++++++ 4 files changed, 75 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/lto/pr101868_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr101868_1.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr101868_2.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr101868_3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/lto/pr101868_0.c b/gcc/testsuite/gcc.dg/lto/pr101868_0.c new file mode 100644 index 0000000..c84d19b --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr101868_0.c @@ -0,0 +1,33 @@ +/* { dg-lto-do run } */ +/* { dg-lto-options { "-O2 -fno-strict-aliasing -flto" } } */ + +typedef unsigned long VALUE; + +__attribute__ ((cold)) +void rb_check_type(VALUE, int); + +static VALUE +repro(VALUE dummy, VALUE hash) +{ + if (hash == 0) { + rb_check_type(hash, 1); + } + else if (*(long *)hash) { + rb_check_type(hash, 1); + } + + + return *(long *)hash; +} + +static VALUE (*that)(VALUE dummy, VALUE hash) = repro; + +int +main(int argc, char **argv) +{ + argc--; + that(0, argc); + + rb_check_type(argc, argc); + +} diff --git a/gcc/testsuite/gcc.dg/lto/pr101868_1.c b/gcc/testsuite/gcc.dg/lto/pr101868_1.c new file mode 100644 index 0000000..146c14a --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr101868_1.c @@ -0,0 +1,23 @@ +typedef unsigned long VALUE; + + +__attribute__ ((noreturn)) void rexc_raise(VALUE mesg); + +VALUE rb_donothing(VALUE klass); + +static void +funexpected_type(VALUE x, int xt, int t) +{ + rexc_raise(rb_donothing(0)); +} + +__attribute__ ((cold)) +void +rb_check_type(VALUE x, int t) +{ + int xt; + + if (x == 0) { + funexpected_type(x, xt, t); + } +} diff --git a/gcc/testsuite/gcc.dg/lto/pr101868_2.c b/gcc/testsuite/gcc.dg/lto/pr101868_2.c new file mode 100644 index 0000000..e6f01b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr101868_2.c @@ -0,0 +1,11 @@ +typedef unsigned long VALUE; + +static void thing(void) {} +static void (*ptr)(void) = &thing; + +VALUE +rb_donothing(VALUE klass) +{ + ptr(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr101868_3.c b/gcc/testsuite/gcc.dg/lto/pr101868_3.c new file mode 100644 index 0000000..6121762 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr101868_3.c @@ -0,0 +1,8 @@ +typedef unsigned long VALUE; + +__attribute__((noreturn)) +void +rexc_raise(VALUE mesg) +{ + __builtin_exit(0); +} -- cgit v1.1 From 891bdbf2b0432b4aa3d3e76923617fcb4fd33cf6 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 17 Aug 2021 10:50:56 +0200 Subject: Special case -TYPE_MIN_VALUE for flag_wrapv in operator_abs::op1_range. With flag_wrapv, -TYPE_MIN_VALUE = TYPE_MIN_VALUE which is unrepresentable. We currently special case this in the ABS folding routine, but are missing similar treatment in operator_abs::op1_range. Tested on x86-64 Linux. PR tree-optimization/101938 gcc/ChangeLog: * range-op.cc (operator_abs::op1_range): Special case -TYPE_MIN_VALUE for flag_wrapv. gcc/testsuite/ChangeLog: * gcc.dg/pr101938.c: New test. --- gcc/testsuite/gcc.dg/pr101938.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr101938.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr101938.c b/gcc/testsuite/gcc.dg/pr101938.c new file mode 100644 index 0000000..8277755 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101938.c @@ -0,0 +1,28 @@ +// { dg-do run } +// { dg-require-effective-target lp64 } +// { dg-options "-O2 -fwrapv" } + +typedef long long int int64; +#define INT64CONST(x) (x##LL) +/* -9223372036854775808ULL */ +#define INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) + +static void __attribute__((noipa)) foo(int64 arg1, int64 arg2) { + int64 a1 = -arg1; + int64 a2 = (arg2 < 0) ? arg2 : -arg2; + + if (a1 > a2) { + int64 swap = arg1; + arg1 = arg2; + arg2 = swap; + } + + if (arg1 == INT64_MIN && arg2 == -1) return; + + __builtin_abort(); +} + +int main() { + foo(-1, INT64_MIN); + return 0; +} -- cgit v1.1 From 408579c9c9b8fee20e1d8114489ce2b93872767c Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 17 Aug 2021 14:50:54 +0100 Subject: Improved handling of MULT_EXPR in bit CCP. This patch allows GCC to constant fold (i | (i<<16)) | ((i<<24) | (i<<8)), where i is an unsigned char, or the equivalent (i*65537) | (i*16777472), to i*16843009. The trick is to teach tree_nonzero_bits which bits may be set in the result of a multiplication by a constant given which bits are potentially set in the operands. This allows the optimizations recently added to match.pd to catch more cases. The required mask/value pair from a multiplication may be calculated using a classical shift-and-add algorithm, given we already have implementations for both addition and shift by constant. To keep this optimization "cheap", this functionality is only used if the constant multiplier has a few bits set (unless flag_expensive_optimizations), and we provide a special case fast-path implementation for the common case where the (non-constant) operand has no bits that are guaranteed to be set. I have no evidence that this functionality causes performance issues, it's just that sparse multipliers provide the largest benefit to CCP. 2021-08-17 Roger Sayle gcc/ChangeLog * tree-ssa-ccp.c (bit_value_mult_const): New helper function to calculate the mask-value pair result of a multiplication by an unsigned constant. (bit_value_binop) [MULT_EXPR]: Call it from here for multiplications by (sparse) non-negative constants. gcc/testsuite/ChangeLog * gcc.dg/fold-ior-5.c: New test case. --- gcc/testsuite/gcc.dg/fold-ior-5.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-ior-5.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/fold-ior-5.c b/gcc/testsuite/gcc.dg/fold-ior-5.c new file mode 100644 index 0000000..8de5697 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-ior-5.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +unsigned int test_ior(unsigned char i) +{ + return (i | (i<<16)) | ((i<<24) | (i<<8)); +} + +unsigned int test_xor(unsigned char i) +{ + return (i ^ (i<<16)) ^ ((i<<24) ^ (i<<8)); +} + +/* { dg-final { scan-tree-dump-not " \\^ " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \\* 16843009" 2 "optimized" } } */ + -- cgit v1.1 From 897a15f355632bdc31871554892eca5512b3c370 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 17 Aug 2021 14:59:14 +0100 Subject: Improved handling of MINUS_EXPR in bit CCP. This patch improves the bit bounds for MINUS_EXPR during tree-ssa's conditional constant propagation (CCP) pass (and as an added bonus adds support for POINTER_DIFF_EXPR). The pessimistic assumptions made by the current algorithm are demonstrated by considering 1 - (x&1). Intuitively this should have possible values 0 and 1, and therefore an unknown mask of 1. Alas by treating subtraction as a negation followed by addition, the second operand first becomes 0 or -1, with an unknown mask of all ones, which results in the addition containing no known bits. Improved bounds are achieved by using the same approach used for PLUS_EXPR, determining the result with the minimum number of borrows, the result from the maximum number of borrows, and examining the bits they have in common. One additional benefit of this approach is that it is applicable to POINTER_DIFF_EXPR, where previously the negation of a pointer didn't/doesn't make sense. A more convincing example, where a transformation missed by .032t.cpp isn't caught a few passes later by .038t.evrp, is the expression (7 - (x&5)) & 2, which (in the new test case) currently survives the tree-level optimizers but with this patch is now simplified to the constant value 2. 2021-08-17 Roger Sayle gcc/ChangeLog * tree-ssa-ccp.c (bit_value_binop) [MINUS_EXPR]: Use same algorithm as PLUS_EXPR to improve subtraction bit bounds. [POINTER_DIFF_EXPR]: Treat as synonymous with MINUS_EXPR. gcc/testsuite/ChangeLog * gcc.dg/tree-ssa/ssa-ccp-40.c: New test case. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c new file mode 100644 index 0000000..aa7349e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int foo(int x) +{ + int p = 7; + int q = p - (x & 5); + return q & 2; +} + +/* { dg-final { scan-tree-dump "return 2;" "optimized" } } */ -- cgit v1.1 From a42467bdb70650cd2f421e67b6c3418f74feaec2 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 17 Aug 2021 08:45:18 +0200 Subject: Restore 'gcc.dg/pr78213.c' testing ... after it had gotten disabled in r243681 (Git commit ecfc21ff34ddc6f8aa517251fb51494c68ff741f) "Introduce selftest::locate_file". gcc/testsuite/ * gcc.dg/pr78213.c: Restore testing. --- gcc/testsuite/gcc.dg/pr78213.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr78213.c b/gcc/testsuite/gcc.dg/pr78213.c index ebc2cce..40dd3c8 100644 --- a/gcc/testsuite/gcc.dg/pr78213.c +++ b/gcc/testsuite/gcc.dg/pr78213.c @@ -1,12 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fself-test" } */ - -/* When this test was written -fself-test took no argument, but it - has subsequently gained a mandatory argument, giving the path - to selftest support files (within the srcdir). - It's not clear how to provide this path sanely from - within DejaGnu, so for now, this test is disabled. */ -/* { dg-skip-if "" { *-*-* } } */ +/* { dg-options "-fself-test=$srcdir/selftests" } */ /* Verify that -fself-test does not fail on a non empty source. */ -- cgit v1.1 From b48d4e6818674898f90d9358378c127511ef0f9f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 17 Aug 2021 14:49:05 -0600 Subject: Move more warning code to gimple-ssa-warn-access etc. Also resolves: PR middle-end/101854 - Invalid warning -Wstringop-overflow wrong argument gcc/ChangeLog: PR middle-end/101854 * builtins.c (expand_builtin_alloca): Move warning code to check_alloca in gimple-ssa-warn-access.cc. * calls.c (alloc_max_size): Move code to check_alloca. (get_size_range): Move to pointer-query.cc. (maybe_warn_alloc_args_overflow): Move to gimple-ssa-warn-access.cc. (get_attr_nonstring_decl): Move to tree.c. (fntype_argno_type): Move to gimple-ssa-warn-access.cc. (append_attrname): Same. (maybe_warn_rdwr_sizes): Same. (initialize_argument_information): Move code to gimple-ssa-warn-access.cc. * calls.h (maybe_warn_alloc_args_overflow): Move to gimple-ssa-warn-access.h. (get_attr_nonstring_decl): Move to tree.h. (maybe_warn_nonstring_arg): Move to gimple-ssa-warn-access.h. (enum size_range_flags): Move to pointer-query.h. (get_size_range): Same. * gimple-ssa-warn-access.cc (has_location): Remove unused overload to avoid Clang -Wunused-function. (get_size_range): Declare static. (maybe_emit_free_warning): Rename... (maybe_check_dealloc_call): ...to this for consistency. (class pass_waccess): Add members. (pass_waccess::~pass_waccess): Defined. (alloc_max_size): Move here from calls.c. (maybe_warn_alloc_args_overflow): Same. (check_alloca): New function. (check_alloc_size_call): New function. (check_strncat): Handle another warning flag. (pass_waccess::check_builtin): Handle alloca. (fntype_argno_type): Move here from calls.c. (append_attrname): Same. (maybe_warn_rdwr_sizes): Same. (pass_waccess::check_call): Define. (check_nonstring_args): New function. (pass_waccess::check): Call new member functions. (pass_waccess::execute): Enable ranger. * gimple-ssa-warn-access.h (get_size_range): Move here from calls.h. (maybe_warn_nonstring_arg): Same. * gimple-ssa-warn-restrict.c: Remove #include. * pointer-query.cc (get_size_range): Move here from calls.c. * pointer-query.h (enum size_range_flags): Same. (get_size_range): Same. * tree.c (get_attr_nonstring_decl): Move here from calls.c. * tree.h (get_attr_nonstring_decl): Move here from calls.h. gcc/testsuite/ChangeLog: * gcc.dg/attr-alloc_size-5.c: Adjust optimization to -O1. * gcc.dg/attr-alloc_size-7.c: Use #pragmas to adjust optimization. * gcc.dg/attr-alloc_size-8.c: Adjust optimization to -O1. PR middle-end/101854 * gcc.dg/Wstringop-overflow-72.c: New test. --- gcc/testsuite/gcc.dg/Wstringop-overflow-72.c | 13 ++++++++ gcc/testsuite/gcc.dg/attr-alloc_size-5.c | 2 +- gcc/testsuite/gcc.dg/attr-alloc_size-7.c | 45 ++++++++++++++++++++++++---- gcc/testsuite/gcc.dg/attr-alloc_size-8.c | 2 +- 4 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-72.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-72.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-72.c new file mode 100644 index 0000000..c10773e --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-72.c @@ -0,0 +1,13 @@ +/* PR middle-end/101854 - Invalid warning -Wstringop-overflow wrong argument + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct A { int a[5]; }; + +struct A g (int*, int[6][8]); + +struct A f (void) +{ + int a[2]; + return g (a, 0); // { dg-bogus "-Wstringop-overflow" } +} diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c index 7aa7cbf..4eea625 100644 --- a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c +++ b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c @@ -4,7 +4,7 @@ zero bytes. For standard allocation functions the return value is implementation-defined and so relying on it may be a source of bugs. */ /* { dg-do compile } */ -/* { dg-options "-O2 -Wall -Walloc-zero" } */ +/* { dg-options "-O1 -Wall -Walloc-zero" } */ #define SCHAR_MAX __SCHAR_MAX__ #define SCHAR_MIN (-SCHAR_MAX - 1) diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-7.c b/gcc/testsuite/gcc.dg/attr-alloc_size-7.c index 68602ec..3adde5c 100644 --- a/gcc/testsuite/gcc.dg/attr-alloc_size-7.c +++ b/gcc/testsuite/gcc.dg/attr-alloc_size-7.c @@ -4,7 +4,7 @@ of the maximum specified by -Walloc-size-larger-than=maximum. */ /* { dg-do compile } */ /* { dg-require-effective-target alloca } */ -/* { dg-options "-O2 -Wall -Walloc-size-larger-than=12345" } */ +/* { dg-options "-O1 -Wall -Walloc-size-larger-than=12345" } */ #define SIZE_MAX __SIZE_MAX__ #define MAXOBJSZ 12345 @@ -13,15 +13,40 @@ typedef __SIZE_TYPE__ size_t; void sink (void*); -static size_t maxobjsize (void) +#pragma GCC push_options +/* Verify that constant evaluation takes place even at -O0. */ +#pragma GCC optimize ("0") + +void test_cst (void *p) { - return MAXOBJSZ; + enum { max = MAXOBJSZ }; + + sink (__builtin_aligned_alloc (1, max)); + sink (__builtin_aligned_alloc (1, max + 1)); /* { dg-warning "argument 2 value .12346\[lu\]*. exceeds maximum object size 12345" } */ + + sink (__builtin_alloca (max)); + sink (__builtin_alloca (max + 2)); /* { dg-warning "argument 1 value .12347\[lu\]*. exceeds maximum object size 12345" } */ + + sink (__builtin_calloc (1, max)); + sink (__builtin_calloc (max, 1)); + + sink (__builtin_calloc (max / 2, 3)); /* { dg-warning "product .6172\[lu\]* \\* 3\[lu\]*. of arguments 1 and 2 exceeds maximum object size 12345" } */ + sink (__builtin_calloc (4, max / 3)); /* { dg-warning "product .4\[lu\]* \\* 4115\[lu\]*. of arguments 1 and 2 exceeds maximum object size 12345" } */ + + sink (__builtin_malloc (max)); + sink (__builtin_malloc (max + 3)); /* { dg-warning "argument 1 value .12348\[lu\]*. exceeds maximum object size 12345" } */ + + sink (__builtin_realloc (p, max)); + sink (__builtin_realloc (p, max + 4)); /* { dg-warning "argument 2 value .12349\[lu\]*. exceeds maximum object size 12345" } */ } -void test_var (void *p) +/* Variable evaluation needs -O1. */ +#pragma GCC pop_options + +__attribute__ ((noipa)) void test_var (void *p) { - size_t max = maxobjsize (); + size_t max = MAXOBJSZ; sink (__builtin_aligned_alloc (1, max)); sink (__builtin_aligned_alloc (1, max + 1)); /* { dg-warning "argument 2 value .12346\[lu\]*. exceeds maximum object size 12345" } */ @@ -43,7 +68,15 @@ void test_var (void *p) } -void test_range (void *p, size_t range) +/* Value range evaluation (apparently) needs -O2 here. */ +#pragma GCC optimize ("2") + +static size_t maxobjsize (void) +{ + return MAXOBJSZ; +} + +__attribute__ ((noipa)) void test_range (void *p, size_t range) { /* Make sure the variable is at least as large as the maximum object size but also make sure that it's guaranteed not to be too big to diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-8.c b/gcc/testsuite/gcc.dg/attr-alloc_size-8.c index 91d7eb5..7b47b04 100644 --- a/gcc/testsuite/gcc.dg/attr-alloc_size-8.c +++ b/gcc/testsuite/gcc.dg/attr-alloc_size-8.c @@ -4,7 +4,7 @@ two more specific options override the more general latter option. */ /* { dg-do compile } */ /* { dg-require-effective-target alloca } */ -/* { dg-options "-O2 -Walloc-size-larger-than=123 -Walloca-larger-than=234 -Wvla-larger-than=345" } */ +/* { dg-options "-O -Walloc-size-larger-than=123 -Walloca-larger-than=234 -Wvla-larger-than=345" } */ typedef __SIZE_TYPE__ size_t; -- cgit v1.1 From 1bf976a5de69ecd9b1e10eb7515357b98e78faf7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 18 Aug 2021 10:20:50 +0200 Subject: openmp: Actually ignore pragma_stmt pragmas for which c_parser_pragma returns false Unlike the C++ FE, the C FE ignored pragmas (as if they weren't there) in pragma_stmt contexts if c*_parser_pragma returns false only when after labels, not inside of substatements of selection or loop statements. After making just that change, several gomp/goacc testcases started failing, because extra diagnostics has been emitted (in C, in C++ it was emitted already before). Say void foo (int x) { if (x) #pragma omp barrier } used to in C emit just an error that the pragma is not allowed in such contexts, but in C++ emitted both that and a parsing error that if (x) } is invalid. So, the rest of this patch is mostly about returning true after we report that that certain pragma is not allowed in pragma_stmt contexts, because for error-recovery it seems better to treat the pragma in that case as something that is the substatement of such if etc. c*_parser_pragma return value is only ever used for pragma_stmt context, in which false means act as if the pragma isn't there (e.g. has been handled already by preprocessor etc.), and true which means it was there. 2021-08-18 Jakub Jelinek gcc/c/ * c-parser.c (c_parser_statement_after_labels): Add restart label near the start of the function. If c_parser_pragma returns false, goto restart. (c_parser_pragma): For PRAGMA_OMP_CANCELLATION_POINT return what c_parser_omp_cancellation_point returned. For PRAGMA_OMP_DECLARE return what c_parser_omp_declare returned. Return true instead of false after emitting errors that the directive is not allowed in pragma_stmt context. (c_parser_omp_ordered): Return true instead of false after emitting errors that the directive is not allowed in pragma_stmt context. (c_parser_omp_target_update): Likewise. (c_parser_omp_target_enter_data, c_parser_omp_target_exit_data): Change return type from tree to bool, return false if the directive should be ignored in pragma_stmt contexts. (c_parser_omp_target): Adjust callers of c_parser_omp_target_*_data, return their result directly. (c_parser_omp_cancellation_point): Change return type from void to bool, return false if the directive should be ignored in pragma_stmt contexts. (c_parser_omp_declare): Likewise. gcc/cp/ * parser.c (cp_parser_omp_ordered): Return true instead of false after emitting errors that the directive is not allowed in pragma_stmt context. (cp_parser_omp_target_update): Likewise. (cp_parser_omp_cancellation_point): Change return type from void to bool, return false if the directive should be ignored in pragma_stmt contexts. (cp_parser_omp_target_enter_data, cp_parser_omp_target_exit_data): Change return type from tree to bool, return false if the directive should be ignored in pragma_stmt contexts. (cp_parser_omp_target): Adjust callers of cp_parser_omp_target_*_data, return their result directly. (cp_parser_pragma): For PRAGMA_OMP_CANCELLATION_POINT return what cp_parser_omp_cancellation_point returned. Return true instead of false after emitting errors that the directive is not allowed in pragma_stmt context. gcc/testsuite/ * c-c++-common/gomp/pr63326.c: Don't expect extra "before" errors in C++. * g++.dg/gomp/attrs-7.C: Don't expect one extra error. * g++.dg/gomp/barrier-2.C: Likewise. * gcc.dg/gomp/declare-simd-5.c: Likewise. * gcc.dg/gomp/barrier-2.c: Likewise. * gcc.dg/gomp/declare-variant-2.c: Likewise. --- gcc/testsuite/gcc.dg/gomp/barrier-2.c | 3 +-- gcc/testsuite/gcc.dg/gomp/declare-simd-5.c | 2 +- gcc/testsuite/gcc.dg/gomp/declare-variant-2.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/barrier-2.c b/gcc/testsuite/gcc.dg/gomp/barrier-2.c index c0d62f5..ef605a0 100644 --- a/gcc/testsuite/gcc.dg/gomp/barrier-2.c +++ b/gcc/testsuite/gcc.dg/gomp/barrier-2.c @@ -16,8 +16,7 @@ void f1(void) void f2(void) { - label: /* { dg-error "label at end of compound statement" } */ - /* { dg-warning "defined but not used" "" { target *-*-* } .-1 } */ + label: /* { dg-warning "defined but not used" } */ #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ } diff --git a/gcc/testsuite/gcc.dg/gomp/declare-simd-5.c b/gcc/testsuite/gcc.dg/gomp/declare-simd-5.c index b9a4161..9397820 100644 --- a/gcc/testsuite/gcc.dg/gomp/declare-simd-5.c +++ b/gcc/testsuite/gcc.dg/gomp/declare-simd-5.c @@ -15,7 +15,7 @@ f1 (int x) lab: #pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int)) extern int f5 (int a, int *b, int c); /* { dg-error "must be followed by function declaration or definition" } */ - x++; /* { dg-error "a label can only be part of a statement and a declaration is not a statement" "" { target *-*-* } .-1 } */ + x++; } return x; } diff --git a/gcc/testsuite/gcc.dg/gomp/declare-variant-2.c b/gcc/testsuite/gcc.dg/gomp/declare-variant-2.c index 39c2c1d..3da5dc7 100644 --- a/gcc/testsuite/gcc.dg/gomp/declare-variant-2.c +++ b/gcc/testsuite/gcc.dg/gomp/declare-variant-2.c @@ -17,7 +17,7 @@ f1 (int x) lab: #pragma omp declare variant (fn0) match (user={condition(0)}) extern int f5 (int a, int *b, int c); /* { dg-error "must be followed by function declaration or definition" } */ - x++; /* { dg-error "a label can only be part of a statement and a declaration is not a statement" "" { target *-*-* } .-1 } */ + x++; } return x; } -- cgit v1.1 From aef703cf982072427e74034f4c460a11c5e04b8e Mon Sep 17 00:00:00 2001 From: Ankur Saini Date: Thu, 29 Jul 2021 15:48:07 +0530 Subject: analyzer: detect and analyze calls via function pointer 2021-07-29 Ankur Saini gcc/analyzer/ChangeLog: PR analyzer/100546 * analysis-plan.cc (analysis_plan::use_summary_p): Don't use call summaries if there is no callgraph edge * checker-path.cc (call_event::call_event): Handle calls events that are not represented by a supergraph call edge (return_event::return_event): Likewise. (call_event::get_desc): Work with new call_event structure. (return_event::get_desc): Likeise. * checker-path.h (call_event::m_src_snode): New field. (call_event::m_dest_snode): New field. (return_event::m_src_snode): New field. (return_event::m_dest_snode): New field. * diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic): Refactor to work with edges without callgraph edge. (diagnostic_manager::prune_for_sm_diagnostic): Likewise. * engine.cc (dynamic_call_info_t::update_model): New function. (dynamic_call_info_t::add_events_to_path): New function. (exploded_graph::create_dynamic_call): New function. (exploded_graph::process_node): Work with dynamically discovered calls. * exploded-graph.h (class dynamic_call_info_t): New class. (exploded_graph::create_dynamic_call): New decl. * program-point.cc (program_point::push_to_call_stack): New function. (program_point::pop_from_call_stack): New function. * program-point.h (program_point::push_to_call_stack): New decl. (program_point::pop_from_call_stack): New decl. * program-state.cc (program_state::push_call): New function. (program_state::returning_call): New function. * program-state.h (program_state::push_call): New decl. (program_state::returning_call): New decl. * region-model.cc (region_model::update_for_gcall) New function. (region_model::update_for_return_gcall): New function. (egion_model::update_for_call_superedge): Get the underlying gcall and update for gcall. (region_model::update_for_return_superedge): Likewise. * region-model.h (region_model::update_for_gcall): New decl. (region_model::update_for_return_gcall): New decl. * state-purge.cc (state_purge_per_ssa_name::process_point): Update to work with calls without underlying cgraph edge. * supergraph.cc (supergraph::supergraph) Split snodes at every callsite. * supergraph.h (supernode::get_returning_call) New accessor. gcc/testsuite/ChangeLog: PR analyzer/100546 * gcc.dg/analyzer/function-ptr-4.c: New test. * gcc.dg/analyzer/pr100546.c: New test. --- gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr100546.c | 17 +++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr100546.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c b/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c new file mode 100644 index 0000000..016351a --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c @@ -0,0 +1,24 @@ +/* Test to see if the analyzer detect and analyze calls via + function pointers or not. */ + +#include + +void fun(int *int_ptr) +{ + free(int_ptr); /* { dg-warning "double-'free' of 'int_ptr'" } */ +} + +void single_call() +{ + int *int_ptr = (int*)malloc(sizeof(int)); + void (*fun_ptr)(int *) = &fun; + (*fun_ptr)(int_ptr); +} + +void double_call() +{ + int *int_ptr = (int*)malloc(sizeof(int)); + void (*fun_ptr)(int *) = &fun; + (*fun_ptr)(int_ptr); /* { dg-message "calling 'fun' from 'double_call'" } */ + (*fun_ptr)(int_ptr); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr100546.c b/gcc/testsuite/gcc.dg/analyzer/pr100546.c new file mode 100644 index 0000000..3349d40 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr100546.c @@ -0,0 +1,17 @@ +#include +#include + +static void noReturn(const char *str) __attribute__((noreturn)); +static void noReturn(const char *str) { + printf("%s\n", str); + exit(1); +} + +void (*noReturnPtr)(const char *str) = &noReturn; + +int main(int argc, char **argv) { + char *str = 0; + if (!str) + noReturnPtr(__FILE__); + return printf("%c\n", *str); +} -- cgit v1.1 From b7fc42073c04813f6b63e0641d3f6765424857c9 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Thu, 19 Aug 2021 08:25:47 +0200 Subject: Fix up 'gcc.dg/pr78213.c' for '--enable-checking=release' etc. Fix up for r242748 (commit 3615816da830d41f67a5d8955ae588eba7f0b6fb) "[PR target/78213] Do not ICE on non-empty -fself-test", as made apparent by recent commit a42467bdb70650cd2f421e67b6c3418f74feaec2 "Restore 'gcc.dg/pr78213.c' testing", after the test case had gotten disabled in r243681 (commit ecfc21ff34ddc6f8aa517251fb51494c68ff741f) "Introduce selftest::locate_file" shortly after its original introduction. gcc/testsuite/ PR testsuite/101969 * gcc.dg/pr78213.c: Fix up for '--enable-checking=release' etc. --- gcc/testsuite/gcc.dg/pr78213.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr78213.c b/gcc/testsuite/gcc.dg/pr78213.c index 40dd3c8..04bf038 100644 --- a/gcc/testsuite/gcc.dg/pr78213.c +++ b/gcc/testsuite/gcc.dg/pr78213.c @@ -8,4 +8,5 @@ int i; while (i--) bar(); } -/* { dg-message "fself\-test: " "-fself-test" { target *-*-* } 0 } */ + +/* { dg-regexp {^-fself-test: [0-9]+ pass\(es\) in [.0-9]+ seconds$|.*: note: self-tests are not enabled in this build$} } */ -- cgit v1.1 From e92d0ff6b5e6d4b95c04fc3e326d40efeb136086 Mon Sep 17 00:00:00 2001 From: Ankur Saini Date: Thu, 19 Aug 2021 19:54:56 +0530 Subject: analyzer: Fix PR analyzer/101980 2021-08-19 Ankur Saini gcc/analyzer/ChangeLog: PR analyzer/101980 * diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic): Use caller_model only when the supergraph_edge doesn't exixt. (diagnostic_manager::prune_for_sm_diagnostic): Likewise. * engine.cc (exploded_graph::create_dynamic_call): Rename to... (exploded_graph::maybe_create_dynamic_call): ...this, return call creation status. (exploded_graph::process_node): Handle calls which were not dynamically discovered. * exploded-graph.h (exploded_graph::create_dynamic_call): Rename to... (exploded_graph::maybe_create_dynamic_call): ...this. * region-model.cc (region_model::update_for_gcall): New param, use it to push call to frame. (region_model::update_for_call_superedge): Pass callee function to update_for_gcall. * region-model.h (region_model::update_for_gcall): New param. gcc/testsuite/ChangeLog: PR analyzer/101980 * gcc.dg/analyzer/function-ptr-2.c : Add issue for double 'free'. * gcc.dg/analyzer/malloc-callbacks.c : Fix xfail testcase. --- gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c | 5 ++--- gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c b/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c index 411b1b3..fd25e3b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c @@ -6,9 +6,10 @@ typedef void (*fn_ptr_t) (void *); void calls_free (void *victim) { - free (victim); + free (victim); /* { dg-warning "double-'free' of 'victim'" } */ } + void no_op (void *ptr) { @@ -25,7 +26,6 @@ void test_1 (void *ptr) fn_ptr (ptr); fn_ptr (ptr); } -// TODO: issue a double-'free' warning at 2nd call to fn_ptr. /* As above, but with an extra indirection to try to thwart the optimizer. */ @@ -41,4 +41,3 @@ void test_2 (void *ptr, fn_ptr_t *fn_ptr) (*fn_ptr) (ptr); (*fn_ptr) (ptr); } -// TODO: issue a double-'free' warning at 2nd call to fn_ptr. diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c index 901ca5c..53c75fd 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c @@ -69,7 +69,7 @@ int *test_5 (void) static void __attribute__((noinline)) called_by_test_6a (void *ptr) { - free (ptr); /* { dg-warning "double-'free'" "" { xfail *-*-* } } */ + free (ptr); /* { dg-warning "double-'free'"} */ } static deallocator_t __attribute__((noinline)) -- cgit v1.1 From 9b08f7764cecd16cba84944f2a8b67a7f73a7ce7 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 22 Aug 2021 20:57:19 +0200 Subject: Clear EAF_NOCLOBBER for indirect calls gcc/ChangeLog: 2021-08-22 Jan Hubicka Martin Liska PR middle-end/101949 * ipa-modref.c (analyze_ssa_name_flags): Indirect call implies ~EAF_NOCLOBBER. gcc/testsuite/ChangeLog: 2021-08-22 Jan Hubicka Martin Liska * gcc.dg/lto/pr101949_0.c: New test. * gcc.dg/lto/pr101949_1.c: New test. --- gcc/testsuite/gcc.dg/lto/pr101949_0.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/lto/pr101949_1.c | 4 ++++ 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/lto/pr101949_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr101949_1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/lto/pr101949_0.c b/gcc/testsuite/gcc.dg/lto/pr101949_0.c new file mode 100644 index 0000000..142dffe --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr101949_0.c @@ -0,0 +1,20 @@ +/* { dg-lto-do run } */ +/* { dg-lto-options { "-O2 -fipa-pta -flto -flto-partition=1to1" } } */ + +extern int bar (int (*)(int *), int *); + +static int x; + +static int __attribute__ ((noinline)) foo (int *p) +{ + *p = 1; + x = 0; + return *p; +} + +int main () +{ + if (bar (foo, &x) != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr101949_1.c b/gcc/testsuite/gcc.dg/lto/pr101949_1.c new file mode 100644 index 0000000..871d15c --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr101949_1.c @@ -0,0 +1,4 @@ +int __attribute__((noinline,noclone)) bar (int (*fn)(int *), int *p) +{ + return fn (p); +} -- cgit v1.1 From 972eab51f53d1db26864ec7d62d40c2ff83407ec Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Sun, 22 Aug 2021 23:47:58 +0200 Subject: Correct treatment of qualifiers for pointers to arrays for C2X [PR98397] 2021-08-22 Martin Uecker gcc/c/ PR c/98397 * c-typeck.c (comp_target_types): Change pedwarn to pedwarn_c11 for pointers to arrays with qualifiers. (build_conditional_expr): For C23 don't lose qualifiers for pointers to arrays when the other pointer is a void pointer. Update warnings. (convert_for_assignment): Update warnings for C2X when converting from void* with qualifiers to a pointer to array with the same qualifiers. gcc/testsuite/ PR c/98397 * gcc.dg/c11-qual-1.c: New test. * gcc.dg/c2x-qual-1.c: New test. * gcc.dg/c2x-qual-2.c: New test. * gcc.dg/c2x-qual-3.c: New test. * gcc.dg/c2x-qual-4.c: New test. * gcc.dg/c2x-qual-5.c: New test. * gcc.dg/c2x-qual-6.c: New test. * gcc.dg/c2x-qual-7.c: New test. * gcc.dg/pointer-array-quals-1.c: Remove unnecessary flag. * gcc.dg/pointer-array-quals-2.c: Remove unnecessary flag. --- gcc/testsuite/gcc.dg/c11-qual-1.c | 11 +++ gcc/testsuite/gcc.dg/c2x-qual-1.c | 30 +++++++ gcc/testsuite/gcc.dg/c2x-qual-2.c | 30 +++++++ gcc/testsuite/gcc.dg/c2x-qual-3.c | 30 +++++++ gcc/testsuite/gcc.dg/c2x-qual-4.c | 105 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-qual-5.c | 101 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-qual-6.c | 114 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-qual-7.c | 16 ++++ gcc/testsuite/gcc.dg/pointer-array-quals-1.c | 2 +- gcc/testsuite/gcc.dg/pointer-array-quals-2.c | 2 +- 10 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/c11-qual-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-1.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-2.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-3.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-4.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-5.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-6.c create mode 100644 gcc/testsuite/gcc.dg/c2x-qual-7.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/c11-qual-1.c b/gcc/testsuite/gcc.dg/c11-qual-1.c new file mode 100644 index 0000000..f731e06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-qual-1.c @@ -0,0 +1,11 @@ +/* Test that qualifiers are lost in tertiary operator for pointers to arrays before C2X, PR98397 */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors -Wno-discarded-array-qualifiers" } */ + +void foo(void) +{ + const int (*u)[1]; + void *v; + _Static_assert(_Generic(1 ? u : v, const void*: 0, void*: 1), "qualifier not lost"); + _Static_assert(_Generic(1 ? v : u, const void*: 0, void*: 1), "qualifier not lost"); +} diff --git a/gcc/testsuite/gcc.dg/c2x-qual-1.c b/gcc/testsuite/gcc.dg/c2x-qual-1.c new file mode 100644 index 0000000..4d33db1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-1.c @@ -0,0 +1,30 @@ +/* Tests related to qualifiers and pointers to arrays in C2X, PR98397 */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +/* test that qualifiers are preserved in tertiary operator for pointers to arrays in C2X */ + +void f(void) +{ + const int (*u)[1]; + void *v; + _Static_assert(_Generic(1 ? u : v, const void*: 1, void*: 0), "lost qualifier"); + _Static_assert(_Generic(1 ? v : u, const void*: 1, void*: 0), "lost qualifier"); +} + +/* test that assignment of unqualified to qualified pointers works as expected */ + +void g(void) +{ + int (*x)[3]; + const int (*p)[3] = x; +} + +/* test that assignment of qualified void pointers works as expected */ + +void h(void) +{ + const void* x; + const int (*p)[3] = x; +} + diff --git a/gcc/testsuite/gcc.dg/c2x-qual-2.c b/gcc/testsuite/gcc.dg/c2x-qual-2.c new file mode 100644 index 0000000..f60a5b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-2.c @@ -0,0 +1,30 @@ +/* Tests related to qualifiers and pointers to arrays in C2X, PR98397 */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -Wc11-c2x-compat" } */ + +/* test that qualifiers are preserved in tertiary operator for pointers to arrays in C2X */ + +void f(void) +{ + const int (*u)[1]; + void *v; + _Static_assert(_Generic(1 ? u : v, const void*: 1, void*: 0), "lost qualifier"); /* { dg-warning "pointer to array loses qualifier in conditional" } */ + _Static_assert(_Generic(1 ? v : u, const void*: 1, void*: 0), "lost qualifier"); /* { dg-warning "pointer to array loses qualifier in conditional" } */ +} + +/* test that assignment of unqualified to qualified pointers works as expected */ + +void g(void) +{ + int (*x)[3]; + const int (*p)[3] = x; /* { dg-warning "arrays with different qualifiers" } */ +} + +/* test that assignment of qualified void pointers works as expected */ + +void h(void) +{ + const void* x; + const int (*p)[3] = x; /* { dg-warning "array with qualifier on the element is not qualified before C2X" } */ +} + diff --git a/gcc/testsuite/gcc.dg/c2x-qual-3.c b/gcc/testsuite/gcc.dg/c2x-qual-3.c new file mode 100644 index 0000000..31896fcb --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-3.c @@ -0,0 +1,30 @@ +/* Tests related to qualifiers and pointers to arrays in C2X, PR98397 */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -Wc11-c2x-compat -pedantic-errors" } */ + +/* test that qualifiers are preserved in tertiary operator for pointers to arrays in C2X */ + +void f(void) +{ + const int (*u)[1]; + void *v; + _Static_assert(_Generic(1 ? u : v, const void*: 1, void*: 0), "lost qualifier"); /* { dg-warning "pointer to array loses qualifier in conditional" } */ + _Static_assert(_Generic(1 ? v : u, const void*: 1, void*: 0), "lost qualifier"); /* { dg-warning "pointer to array loses qualifier in conditional" } */ +} + +/* test that assignment of unqualified to qualified pointers works as expected */ + +void g(void) +{ + int (*x)[3]; + const int (*p)[3] = x; /* { dg-warning "arrays with different qualifiers" } */ +} + +/* test that assignment of qualified void pointers works as expected */ + +void h(void) +{ + const void* x; + const int (*p)[3] = x; /* { dg-warning "array with qualifier on the element is not qualified before C2X" } */ +} + diff --git a/gcc/testsuite/gcc.dg/c2x-qual-4.c b/gcc/testsuite/gcc.dg/c2x-qual-4.c new file mode 100644 index 0000000..93b4723 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-4.c @@ -0,0 +1,105 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ +void tvoid(void* x); +void transpose0(double* out, const double* in) { } +void transpose1(double out[2][2], const double in[2][2]) { } +void transpose2(double out[2][2][2], const double in[2][2][2]) { } +// return +int (*y2(const int x[3][3]))[3] { return x; } /* { dg-warning "return discards 'const' qualifier from pointer target type" } */ +const int (*y3(int x[3][3]))[3] { return x; } +void test(void) +{ + double x0[2]; + double y0[2]; + const double z0[4]; + double x1[2][2]; + double y1[2][2]; + double o1[2][3]; + const double z1[2][2]; + double x2[2][2][2]; + double y2[2][2][2]; + double o2[2][2][3]; + const double z2[2][2][2]; + // void pointers + tvoid(x0); + tvoid(x1); + tvoid(x2); + tvoid(z0); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z1); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z2); /* { dg-warning "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + void* p; + const void* pc; + p = x0; + p = x1; + p = x2; + p = z0; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + p = z1; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + p = z2; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + pc = x0; + pc = x1; + pc = x2; + pc = z0; + pc = z1; + pc = z2; + transpose0(pc, p); /* { dg-warning "passing argument 1 of 'transpose0' discards 'const' qualifier from pointer target type" } */ + transpose1(pc, p); /* { dg-warning "passing argument 1 of 'transpose1' discards 'const' qualifier from pointer target type" } */ + transpose2(pc, p); /* { dg-warning "passing argument 1 of 'transpose2' discards 'const' qualifier from pointer target type" } */ + transpose0(p, pc); + transpose1(p, pc); + transpose2(p, pc); + // passing as arguments + transpose0(y0, x0); + transpose1(y1, x1); + transpose2(y2, x2); + // initialization + const double (*u0p) = x0; + const double (*u1p)[2] = x1; + const double (*u2p)[2][2] = x2; + double (*v0p) = z0; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ + double (*v1p)[2] = z1; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ + double (*v2p)[2][2] = z2; /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */ + // subtraction + &(x0[1]) - &(z0[0]); + &(x1[1]) - &(z1[0]); + &(x2[1]) - &(z2[0]); + // comparison + x0 == z0; + x1 == z1; + x2 == z2; + x0 < z0; + x1 < z1; + x2 < z2; + x0 > z0; + x1 > z1; + x2 > z2; + // assignment + u0p = x0; + u1p = x1; + u2p = x2; + v0p = z0; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = z1; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = z2; /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + // conditional expressions + (void)(1 ? x0 : z0); + (void)(1 ? x1 : z1); + (void)(1 ? x2 : z2); + (void)(1 ? x0 : x1); /* { dg-warning "pointer type mismatch in conditional expression" } */ + (void)(1 ? x1 : x2); /* { dg-warning "pointer type mismatch in conditional expression" } */ + (void)(1 ? x2 : x0); /* { dg-warning "pointer type mismatch in conditional expression" } */ + v0p = (1 ? z0 : v0p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? z1 : v1p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? z2 : v2p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v0p = (1 ? x0 : u0p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? x1 : u1p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? x2 : u2p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + (1 ? x0 : z0)[0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x1 : z1)[0][0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x2 : z2)[0][0][0] = 1; /* { dg-error "assignment of read-only location" } */ + v0p = (1 ? p : z0); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? p : z1); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? p : z2); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v0p = (1 ? pc : x0); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? pc : x1); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? pc : x2); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */ +} + diff --git a/gcc/testsuite/gcc.dg/c2x-qual-5.c b/gcc/testsuite/gcc.dg/c2x-qual-5.c new file mode 100644 index 0000000..0801fa0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-5.c @@ -0,0 +1,101 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ +void tvoid(void* x); +void transpose0(double* out, const double* in) { } +void transpose1(double out[2][2], const double in[2][2]) { } +void transpose2(double out[2][2][2], const double in[2][2][2]) { } +// return +int (*x2(const int x[3][3]))[3] { return x; } /* { dg-error "return discards" } */ +const int (*x3(int x[3][3]))[3] { return x; } +void test(void) +{ + double x0[2]; + double y0[2]; + const double z0[4]; + double x1[2][2]; + double y1[2][2]; + double o1[2][3]; + const double z1[2][2]; + double x2[2][2][2]; + double y2[2][2][2]; + double o2[2][2][3]; + const double z2[2][2][2]; + // void pointers + tvoid(z0); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z1); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z2); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + void* p; + const void* pc; + p = x0; + p = x1; + p = x2; + p = z0; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + p = z1; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + p = z2; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + pc = x0; + pc = x1; + pc = x2; + pc = z0; + pc = z1; + pc = z2; + transpose0(pc, p); /* { dg-error "passing argument 1 of 'transpose0' discards 'const' qualifier from pointer target type" } */ + transpose1(pc, p); /* { dg-error "passing argument 1 of 'transpose1' discards 'const' qualifier from pointer target type" } */ + transpose2(pc, p); /* { dg-error "passing argument 1 of 'transpose2' discards 'const' qualifier from pointer target type" } */ + transpose0(p, pc); + transpose1(p, pc); + transpose2(p, pc); + // passing as arguments + transpose0(y0, x0); + transpose1(y1, o1); /* { dg-error "passing argument 2 of 'transpose1' from incompatible pointer type" } */ + transpose1(y1, x1); + transpose2(y2, o2); /* { dg-error "passing argument 2 of 'transpose2' from incompatible pointer type" } */ + transpose2(y2, x2); + // initialization + const double (*x0p) = x0; + const double (*x1p)[2] = x1; + const double (*x2p)[2][2] = x2; + double (*v0p) = z0; /* { dg-error "initialization discards 'const' qualifier from pointer target type" } */ + double (*v1p)[2] = z1; /* { dg-error "initialization discards" } */ + double (*v2p)[2][2] = z2; /* { dg-error "initialization discards" } */ + // assignment + x0p = x0; + x1p = x1; + x2p = x2; + // subtraction + &(x0[1]) - &(z0[0]); + &(x1[1]) - &(z1[0]); + &(x2[1]) - &(z2[0]); + // comparison + x0 == z0; + x1 == z1; + x2 == z2; + x0 < z0; + x1 < z1; + x2 < z2; + x0 > z0; + x1 > z1; + x2 > z2; + // conditional expressions + (void)(1 ? x0 : z0); + (void)(1 ? x1 : z1); + (void)(1 ? x2 : z2); + (void)(1 ? x0 : x1); /* { dg-error "pointer type mismatch in conditional expression" } */ + (void)(1 ? x1 : x2); /* { dg-error "pointer type mismatch in conditional expression" } */ + (void)(1 ? x2 : x0); /* { dg-error "pointer type mismatch in conditional expression" } */ + v0p = (1 ? z0 : v0p); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? z1 : v1p); /* { dg-error "assignment discards" } */ + v2p = (1 ? z2 : v2p); /* { dg-error "assignment discards" } */ + v0p = (1 ? x0 : x0p); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? x1 : x1p); /* { dg-error "assignment discards" } */ + v2p = (1 ? x2 : x2p); /* { dg-error "assignment discards" } */ + (1 ? x0 : z0)[0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x1 : z1)[0][0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x2 : z2)[0][0][0] = 1; /* { dg-error "assignment of read-only location" } */ + v0p = (1 ? p : z0); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? p : z1); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? p : z2); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v0p = (1 ? pc : x0); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? pc : x1); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? pc : x2); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ +} + diff --git a/gcc/testsuite/gcc.dg/c2x-qual-6.c b/gcc/testsuite/gcc.dg/c2x-qual-6.c new file mode 100644 index 0000000..9c91e20 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-6.c @@ -0,0 +1,114 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -Wc11-c2x-compat -pedantic-errors" } */ +void tvoid(void* x); +void transpose0(double* out, const double* in) { } +void transpose1(double out[2][2], const double in[2][2]) { } +void transpose2(double out[2][2][2], const double in[2][2][2]) { } +// return +int (*x2(const int x[3][3]))[3] { return x; } /* { dg-warning "before C2X" } */ + /* { dg-error "return discards" "" { target *-*-* } .-1 } */ +const int (*x3(int x[3][3]))[3] { return x; } /* { dg-warning "before C2X" } */ +void test(void) +{ + double x0[2]; + double y0[2]; + const double z0[4]; + double x1[2][2]; + double y1[2][2]; + double o1[2][3]; + const double z1[2][2]; + double x2[2][2][2]; + double y2[2][2][2]; + double o2[2][2][3]; + const double z2[2][2][2]; + // void pointers + tvoid(z0); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z1); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + tvoid(z2); /* { dg-error "passing argument 1 of 'tvoid' discards 'const' qualifier from pointer target type" } */ + void* p; + const void* pc; + p = x0; + p = x1; + p = x2; + p = z0; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + p = z1; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + p = z2; /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + pc = x0; + pc = x1; + pc = x2; + pc = z0; + pc = z1; + pc = z2; + transpose0(pc, p); /* { dg-error "passing argument 1 of 'transpose0' discards 'const' qualifier from pointer target type" } */ + transpose1(pc, p); /* { dg-error "passing argument 1 of 'transpose1' discards 'const' qualifier from pointer target type" } */ + transpose2(pc, p); /* { dg-error "passing argument 1 of 'transpose2' discards 'const' qualifier from pointer target type" } */ + transpose0(p, pc); + transpose1(p, pc); /* { dg-warning "before C2X" } */ + transpose2(p, pc); /* { dg-warning "before C2X" } */ + // passing as arguments + transpose0(y0, x0); + transpose1(y1, o1); /* { dg-error "passing argument 2 of 'transpose1' from incompatible pointer type" } */ + transpose1(y1, x1); /* { dg-warning "before C2X" } */ + transpose2(y2, o2); /* { dg-error "passing argument 2 of 'transpose2' from incompatible pointer type" } */ + transpose2(y2, x2); /* { dg-warning "before C2X" } */ + // initialization + const double (*x0p) = x0; + const double (*x1p)[2] = x1; /* { dg-warning "before C2X" } */ + const double (*x2p)[2][2] = x2; /* { dg-warning "before C2X" } */ + double (*v0p) = z0; /* { dg-error "initialization discards 'const' qualifier from pointer target type" } */ + double (*v1p)[2] = z1; /* { dg-warning "before C2X" } */ + /* { dg-error "initialization discards" "" { target *-*-* } .-1 } */ + double (*v2p)[2][2] = z2; /* { dg-warning "before C2X" } */ + /* { dg-error "initialization discards" "" { target *-*-* } .-1 } */ + + // assignment + x0p = x0; + x1p = x1; /* { dg-warning "before C2X" } */ + x2p = x2; /* { dg-warning "before C2X" } */ + + // subtraction + &(x0[1]) - &(z0[0]); + &(x1[1]) - &(z1[0]); /* { dg-warning "before C2X" } */ + &(x2[1]) - &(z2[0]); /* { dg-warning "before C2X" } */ + // comparison + x0 == z0; + x1 == z1; /* { dg-warning "before C2X" } */ + x2 == z2; /* { dg-warning "before C2X" } */ + x0 < z0; + x1 < z1; /* { dg-warning "before C2X" } */ + x2 < z2; /* { dg-warning "before C2X" } */ + x0 > z0; + x1 > z1; /* { dg-warning "before C2X" } */ + x2 > z2; /* { dg-warning "before C2X" } */ + // conditional expressions + (void)(1 ? x0 : z0); + (void)(1 ? x1 : z1); /* { dg-warning "before C2X" } */ + (void)(1 ? x2 : z2); /* { dg-warning "before C2X" } */ + (void)(1 ? x0 : x1); /* { dg-error "pointer type mismatch in conditional expression" } */ + (void)(1 ? x1 : x2); /* { dg-error "pointer type mismatch in conditional expression" } */ + (void)(1 ? x2 : x0); /* { dg-error "pointer type mismatch in conditional expression" } */ + v0p = (1 ? z0 : v0p); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? z1 : v1p); /* { dg-warning "before C2X" } */ + /* { dg-error "assignment discards" "" { target *-*-* } .-1 } */ + v2p = (1 ? z2 : v2p); /* { dg-warning "before C2X" } */ + /* { dg-error "assignment discards" "" { target *-*-* } .-1 } */ + v0p = (1 ? x0 : x0p); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? x1 : x1p); /* { dg-error "assignment discards" } */ + /* { dg-warning "before C2X" "" { target *-*-* } .-1 } */ + v2p = (1 ? x2 : x2p); /* { dg-error "assignment discards" } */ + /* { dg-warning "before C2X" "" { target *-*-* } .-1 } */ + (1 ? x0 : z0)[0] = 1; /* { dg-error "assignment of read-only location" } */ + (1 ? x1 : z1)[0][0] = 1; /* { dg-error "assignment of read-only location" } */ + /* { dg-warning "before C2X" "" { target *-*-* } .-1 } */ + (1 ? x2 : z2)[0][0][0] = 1; /* { dg-error "assignment of read-only location" } */ + /* { dg-warning "before C2X" "" { target *-*-* } .-1 } */ + v0p = (1 ? p : z0); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? p : z1); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + /* { dg-warning "before C2X" "" { target *-*-* } .-1 } */ + v2p = (1 ? p : z2); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + /* { dg-warning "before C2X" "" { target *-*-* } .-1 } */ + v0p = (1 ? pc : x0); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v1p = (1 ? pc : x1); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ + v2p = (1 ? pc : x2); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */ +} + diff --git a/gcc/testsuite/gcc.dg/c2x-qual-7.c b/gcc/testsuite/gcc.dg/c2x-qual-7.c new file mode 100644 index 0000000..5fe15e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-qual-7.c @@ -0,0 +1,16 @@ +/* Tests related to qualifiers and pointers to arrays in C2X, PR98397 */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +/* test that _Atomic qualifier is not preserved in tertiary operator for pointers to arrays in C2X */ + +void f(void) +{ + _Atomic void *u; + void *v; + _Static_assert(_Generic(1 ? u : v, _Atomic void*: 0, void*: 1), "_Atomic should be removed"); + _Static_assert(_Generic(1 ? v : u, _Atomic void*: 0, void*: 1), "_Atomic should be removed"); +} + + + diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c index 921a37e..498ab22 100644 --- a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c +++ b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* Origin: Martin Uecker */ -/* { dg-options "-Wdiscarded-array-qualifiers" } */ +/* { dg-options "" } */ void tvoid(void* x); void transpose0(double* out, const double* in) { } void transpose1(double out[2][2], const double in[2][2]) { } diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-2.c b/gcc/testsuite/gcc.dg/pointer-array-quals-2.c index 30689c7..4c95d8a 100644 --- a/gcc/testsuite/gcc.dg/pointer-array-quals-2.c +++ b/gcc/testsuite/gcc.dg/pointer-array-quals-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Wdiscarded-array-qualifiers -pedantic-errors" } */ +/* { dg-options "-pedantic-errors" } */ /* Origin: Martin Uecker */ void tvoid(void* x); void transpose0(double* out, const double* in) { } -- cgit v1.1 From b284053bb75661fc1bf13c275f3ba5364bb17608 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 23 Aug 2021 11:50:14 +0200 Subject: dwarf2out: Emit DW_AT_location for global register vars during early dwarf [PR101905] The following patch emits DW_AT_location for global register variables already during early dwarf, since usually late_global_decl hook isn't even called for those, as nothing needs to be emitted for them. 2021-08-23 Jakub Jelinek PR debug/101905 * dwarf2out.c (gen_variable_die): Add DW_AT_location for global register variables already during early_dwarf if possible. * gcc.dg/guality/pr101905.c: New test. --- gcc/testsuite/gcc.dg/guality/pr101905.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/guality/pr101905.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/guality/pr101905.c b/gcc/testsuite/gcc.dg/guality/pr101905.c new file mode 100644 index 0000000..71b7516 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr101905.c @@ -0,0 +1,15 @@ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ +/* { dg-options "-g -ffixed-r15" } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +register unsigned long long regVar asm ("r15"); + +int +main() +{ + regVar = 0xdeadbeefcafebabeULL; + asm ("nop" : "+r" (regVar)); + asm volatile ("nop"); /* { dg-final { gdb-test . "regVar" "0xdeadbeefcafebabeULL" } } */ + asm volatile ("nop" : : "r" (regVar)); + return 0; +} -- cgit v1.1 From ad665deeafd31238b537139385e1e80b40c10e0c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 23 Aug 2021 09:57:05 +0200 Subject: tree-optimization/79334 - avoid PRE of possibly trapping array-ref This replicates tree-eh.c in_array_bound_p into VNs vn_reference_may_trap to fix hoisting of a possibly trapping ARRAY_REF across a call that might not return. 2021-08-23 Richard Biener PR tree-optimization/79334 * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Record a type also for COMPONENT_REFs. (vn_reference_may_trap): Check ARRAY_REF with constant index against the array domain. * gcc.dg/torture/pr79334-0.c: New testcase. * gcc.dg/torture/pr79334-1.c: Likewise. --- gcc/testsuite/gcc.dg/torture/pr79334-0.c | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr79334-1.c | 1 + 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr79334-0.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr79334-1.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr79334-0.c b/gcc/testsuite/gcc.dg/torture/pr79334-0.c new file mode 100644 index 0000000..fa45a6d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr79334-0.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-additional-sources "pr79334-1.c" } */ + +extern int d[][8]; + +static void __attribute__((noinline)) +func_that_exits (int flag) +{ + if (!flag) + __builtin_exit (0); +} + +int main () +{ + int e = 0; + while (1) + { + func_that_exits (e); + /* We do not know whether d[1024][0] will trap. */ + e = d[1024][0]; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr79334-1.c b/gcc/testsuite/gcc.dg/torture/pr79334-1.c new file mode 100644 index 0000000..b1c8a27 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr79334-1.c @@ -0,0 +1 @@ +int d[1][8]; -- cgit v1.1 From b320edc0c29c838b0090c3c9be14187d132f73f2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 23 Aug 2021 11:52:06 +0200 Subject: bswap: Recognize (int) __builtin_bswap64 (arg) idioms or __builtin_bswap?? (arg) & mask [PR86723] The following patch recognizes in the bswap pass (only there for now, haven't done it for store merging pass yet) code sequences that can be handled by (int32) __builtin_bswap64 (arg), i.e. where we have 0x05060708 n->n with 64-bit non-memory argument (if it is memory, we can just load the 32-bit at 4 bytes into the address and n->n would be 0x01020304; and only 64 -> 32 bit, because 64 -> 16 bit or 32 -> 16 bit would mean only two bytes in the result and probably not worth it), and furthermore the case where we have in the 0x0102030405060708 etc. numbers some bytes 0 (i.e. known to contain zeros rather than source bytes), as long as we have at least two original bytes in the right positions (and no unknown bytes). This can be handled by __builtin_bswap64 (arg) & 0xff0000ffffff00ffULL etc. The latter change is the reason why counting the bswap messages doesn't work too well in optimize-bswap* tests anymore, while the pass iterates from end of basic block towards start, it will often match both the bswap at the end and some of the earlier bswaps with some masks (not a problem generally, we'll just DCE it away whenever possible). The pass right now doesn't handle __builtin_bswap* calls in the pattern matching (which is the reason why it operates backwards), but it uses FOR_EACH_BB_FN (bb, fun) order of handling blocks and matched sequences can span multiple blocks, so I was worried about cases like: void bar (unsigned long long); unsigned long long foo (unsigned long long value, int x) { unsigned long long tmp = (((value & 0x00000000000000ffull) << 56) | ((value & 0x000000000000ff00ull) << 40) | ((value & 0x00000000ff000000ull) << 8)); if (x) bar (tmp); return (tmp | ((value & 0x000000ff00000000ull) >> 8) | ((value & 0x0000ff0000000000ull) >> 24) | ((value & 0x0000000000ff0000ull) << 24) | ((value & 0x00ff000000000000ull) >> 40) | ((value & 0xff00000000000000ull) >> 56)); } but it seems we handle even that fine, while bb2 ending in GIMPLE_COND is processed first, we recognize there a __builtin_bswap64 (value) & mask1, in the last bb we recognize tmp | (__builtin_bswap64 (value) & mask2) and PRE optimizes that into t = __builtin_bswap64 (value); tmp = t & mask1; in the first bb and return t; in the last one. 2021-08-23 Jakub Jelinek PR tree-optimization/86723 * gimple-ssa-store-merging.c (find_bswap_or_nop_finalize): Add cast64_to_32 argument, set *cast64_to_32 to false, unless n is non-memory permutation of 64-bit src which only has bytes of 0 or [5..8] and n->range is 4. (find_bswap_or_nop): Add cast64_to_32 and mask arguments, adjust find_bswap_or_nop_finalize caller, support bswap with some bytes zeroed, as long as at least two bytes are not zeroed. (bswap_replace): Add mask argument and handle masking of bswap result. (maybe_optimize_vector_constructor): Adjust find_bswap_or_nop caller, punt if cast64_to_32 or mask is not all ones. (pass_optimize_bswap::execute): Adjust find_bswap_or_nop_finalize caller, for now punt if cast64_to_32. * gcc.dg/pr86723.c: New test. * gcc.target/i386/pr86723.c: New test. * gcc.dg/optimize-bswapdi-1.c: Use -fdump-tree-optimized instead of -fdump-tree-bswap and scan for number of __builtin_bswap64 calls. * gcc.dg/optimize-bswapdi-2.c: Likewise. * gcc.dg/optimize-bswapsi-1.c: Use -fdump-tree-optimized instead of -fdump-tree-bswap and scan for number of __builtin_bswap32 calls. * gcc.dg/optimize-bswapsi-5.c: Likewise. * gcc.dg/optimize-bswapsi-3.c: Likewise. Expect one __builtin_bswap32 call instead of zero. --- gcc/testsuite/gcc.dg/optimize-bswapdi-1.c | 4 +- gcc/testsuite/gcc.dg/optimize-bswapdi-2.c | 4 +- gcc/testsuite/gcc.dg/optimize-bswapsi-1.c | 4 +- gcc/testsuite/gcc.dg/optimize-bswapsi-3.c | 4 +- gcc/testsuite/gcc.dg/optimize-bswapsi-5.c | 4 +- gcc/testsuite/gcc.dg/pr86723.c | 63 +++++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr86723.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c index a4a3a79..56a2071b 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target bswap } */ /* { dg-require-effective-target stdint_types } */ -/* { dg-options "-O2 -fdump-tree-bswap" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-additional-options "-mzarch" { target s390*-*-* } } */ #include @@ -58,4 +58,4 @@ swap64_c (uint64_t x) } -/* { dg-final { scan-tree-dump-times "64 bit bswap implementation found at" 3 "bswap" } } */ +/* { dg-final { scan-tree-dump-times "= __builtin_bswap64 \\\(" 3 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/optimize-bswapdi-2.c b/gcc/testsuite/gcc.dg/optimize-bswapdi-2.c index 89b251f..c6d9604 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapdi-2.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapdi-2.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target bswap } */ /* { dg-require-effective-target stdint_types } */ -/* { dg-options "-O2 -fdump-tree-bswap" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-additional-options "-mzarch" { target s390*-*-* } } */ #include @@ -23,4 +23,4 @@ swap64_c (uint64_t x) } -/* { dg-final { scan-tree-dump-times "64 bit bswap implementation found at" 1 "bswap" } } */ +/* { dg-final { scan-tree-dump-times "= __builtin_bswap64 \\\(" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c index c403d04..2d24f43 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target bswap } */ /* { dg-require-effective-target stdint_types } */ -/* { dg-options "-O2 -fdump-tree-bswap" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-additional-options "-march=z900" { target s390*-*-* } } */ #include @@ -89,4 +89,4 @@ swap32_f (unsigned in) return in; } -/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 6 "bswap" } } */ +/* { dg-final { scan-tree-dump-times "= __builtin_bswap32 \\\(" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-3.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-3.c index 9418a83..7cd1b40 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapsi-3.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-3.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target bswap } */ /* { dg-require-effective-target stdint_types } */ -/* { dg-options "-O2 -fdump-tree-bswap" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-additional-options "-march=z900" { target s390-*-* } } */ typedef int SItype __attribute__ ((mode (SI))); @@ -20,4 +20,4 @@ swap32 (SItype in) | (((in >> 24) & 0xFF) << 0); } -/* { dg-final { scan-tree-dump-not "32 bit bswap implementation found at" "bswap" } } */ +/* { dg-final { scan-tree-dump-times "= __builtin_bswap32 \\\(" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-5.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-5.c index b4d8b9a..91a5284 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswapsi-5.c +++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-5.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target bswap } */ -/* { dg-options "-O2 -fdump-tree-bswap -fno-inline-functions" } */ +/* { dg-options "-O2 -fdump-tree-optimized -fno-inline-functions" } */ /* { dg-additional-options "-march=z900" { target s390-*-* } } */ struct L { unsigned int l[2]; }; @@ -28,4 +28,4 @@ bar (double a, struct L *p) foo (a, p); } -/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 2 "bswap" } } */ +/* { dg-final { scan-tree-dump-times "= __builtin_bswap32 \\\(" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr86723.c b/gcc/testsuite/gcc.dg/pr86723.c new file mode 100644 index 0000000..e3fd6b9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr86723.c @@ -0,0 +1,63 @@ +/* PR tree-optimization/86723 */ +/* { dg-do run { target { ilp32 || lp64 } } } */ +/* { dg-options "-O2" } */ + +__attribute__((noipa)) int +foo (unsigned long long value) +{ + return (((value & 0x00000000000000ffull) << 56) + | ((value & 0x000000000000ff00ull) << 40) + | ((value & 0x0000000000ff0000ull) << 24) + | ((value & 0x00000000ff000000ull) << 8) + | ((value & 0x000000ff00000000ull) >> 8) + | ((value & 0x0000ff0000000000ull) >> 24) + | ((value & 0x00ff000000000000ull) >> 40) + | ((value & 0xff00000000000000ull) >> 56)); +} + +__attribute__((noipa)) int +bar (unsigned long long value) +{ + return (((value & 0x000000ff00000000ull) >> 8) + | ((value & 0x0000ff0000000000ull) >> 24) + | ((value & 0x00ff000000000000ull) >> 40) + | ((value & 0xff00000000000000ull) >> 56)); +} + +__attribute__((noipa)) unsigned long long +baz (unsigned long long value) +{ + return (((value & 0x00000000000000ffull) << 56) + | ((value & 0x000000000000ff00ull) << 40) + | ((value & 0x00000000ff000000ull) << 8) + | ((value & 0x000000ff00000000ull) >> 8) + | ((value & 0x0000ff0000000000ull) >> 24) + | ((value & 0xff00000000000000ull) >> 56)); +} + +__attribute__((noipa)) unsigned int +qux (unsigned int value) +{ + return (((value & 0x000000ff) << 24) + | ((value & 0x00ff0000) >> 8) + | ((value & 0xff000000) >> 24)); +} + +__attribute__((noipa)) unsigned int +corge (unsigned int value) +{ + return (((value & 0x000000ff) << 24) + | ((value & 0xff000000) >> 24)); +} + +int +main () +{ + if (foo (0x0102030405060708ull) != 0x04030201 + || bar (0x0102030405060708ull) != 0x04030201 + || baz (0x0102030405060708ull) != 0x0807000504030001ull + || qux (0x01020304) != 0x04000201 + || corge (0x01020304) != 0x04000001) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 1d244020246cb155e4de62ca3b302b920a1f513f Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 23 Aug 2021 12:37:04 +0100 Subject: Fold sign of LSHIFT_EXPR to eliminate no-op conversions. This short patch teaches fold that it is "safe" to change the sign of a left shift, to reduce the number of type conversions in gimple. As an example: unsigned int foo(unsigned int i) { return (int)i << 8; } is currently optimized to: unsigned int foo (unsigned int i) { int i.0_1; int _2; unsigned int _4; [local count: 1073741824]: i.0_1 = (int) i_3(D); _2 = i.0_1 << 8; _4 = (unsigned int) _2; return _4; } with this patch, this now becomes: unsigned int foo (unsigned int i) { unsigned int _2; [local count: 1073741824]: _2 = i_1(D) << 8; return _2; } which generates exactly the same assembly language. Aside from the reduced memory usage, the real benefit is that no-op conversions tend to interfere with many folding optimizations. For example, unsigned int bar(unsigned char i) { return (i ^ (i<<16)) | (i<<8); } currently gets (tangled in conversions and) optimized to: unsigned int bar (unsigned char i) { unsigned int _1; unsigned int _2; int _3; int _4; unsigned int _6; unsigned int _8; [local count: 1073741824]: _1 = (unsigned int) i_5(D); _2 = _1 * 65537; _3 = (int) i_5(D); _4 = _3 << 8; _8 = (unsigned int) _4; _6 = _2 | _8; return _6; } but with this patch, bar now optimizes down to: unsigned int bar(unsigned char i) { unsigned int _1; unsigned int _4; [local count: 1073741824]: _1 = (unsigned int) i_3(D); _4 = _1 * 65793; return _4; } 2021-08-23 Roger Sayle gcc/ChangeLog * match.pd (shift transformations): Change the sign of an LSHIFT_EXPR if it reduces the number of explicit conversions. gcc/testsuite/ChangeLog * gcc.dg/fold-convlshift-1.c: New test case. * gcc.dg/fold-convlshift-2.c: New test case. --- gcc/testsuite/gcc.dg/fold-convlshift-1.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/fold-convlshift-2.c | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-convlshift-1.c create mode 100644 gcc/testsuite/gcc.dg/fold-convlshift-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/fold-convlshift-1.c b/gcc/testsuite/gcc.dg/fold-convlshift-1.c new file mode 100644 index 0000000..b6f57f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-convlshift-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +unsigned int foo(unsigned int i) +{ + int t1 = i; + int t2 = t1 << 8; + return t2; +} + +int bar(int i) +{ + unsigned int t1 = i; + unsigned int t2 = t1 << 8; + return t2; +} + +/* { dg-final { scan-tree-dump-not "\\(int\\)" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "\\(unsigned int\\)" "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/fold-convlshift-2.c b/gcc/testsuite/gcc.dg/fold-convlshift-2.c new file mode 100644 index 0000000..f21358c --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-convlshift-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +unsigned int foo(unsigned char c) +{ + int t1 = c; + int t2 = t1 << 8; + return t2; +} + +int bar(unsigned char c) +{ + unsigned int t1 = c; + unsigned int t2 = t1 << 8; + return t2; +} + +/* { dg-final { scan-tree-dump-times "\\(int\\)" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 1 "optimized" } } */ + -- cgit v1.1 From 537878152ded8b7d271333b803b36c27a9aea8d2 Mon Sep 17 00:00:00 2001 From: Ankur Saini Date: Mon, 23 Aug 2021 17:03:29 +0530 Subject: analyzer: Fix PR analyzer/102020 2021-08-23 Ankur Saini gcc/analyzer/ChangeLog: PR analyzer/102020 * diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic): Fix typo. gcc/testsuite/ChangeLog: PR analyzer/102020 * gcc.dg/analyzer/malloc-callbacks.c : Fix faulty test. --- gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c index 53c75fd..8820ddd 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c @@ -69,7 +69,7 @@ int *test_5 (void) static void __attribute__((noinline)) called_by_test_6a (void *ptr) { - free (ptr); /* { dg-warning "double-'free'"} */ + free (ptr); /* { dg-warning "double-'free'" } */ } static deallocator_t __attribute__((noinline)) -- cgit v1.1 From 6a64964212c8e5e10e474803d06a07514c1069b7 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 23 Aug 2021 17:56:51 +0200 Subject: Avoid redundant entries in modref access lists. In PR101296 Richard noticed that modref is giving up on analysis in milc by hitting --param=modref-max-accesses limit. While cleaning up original modref patch I removed code that tried to do smart things while merging accesses because it had bugs and wanted to reimplement it later which I later forgot. This patch adds logic that avoids adding access and its subaccess to the list which is just waste of memory and compile time. Incrementally I will add logic merging the ranges. gcc/ChangeLog: 2021-08-23 Jan Hubicka * ipa-modref-tree.h (modref_access_node::range_info_useful_p): Improve range compare. (modref_access_node::contains): New member function. (modref_access_node::search): Remove. (modref_access_node::insert): Be smarter about subaccesses. gcc/testsuite/ChangeLog: 2021-08-23 Jan Hubicka * gcc.dg/tree-ssa/modref-7.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/modref-7.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/modref-7.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c new file mode 100644 index 0000000..53ffa1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c @@ -0,0 +1,13 @@ +/* { dg-options "-O2 --param modref-max-accesses=1 -fdump-tree-modref1" } */ +/* { dg-do compile } */ +struct a { + int array[10]; + int tail; +}; +int test(struct a *a, int p) +{ + a->array[p] = 0; + a->array[0] = 1; +} +/* All three accesses combine to one bigger access. */ +/* { dg-final { scan-tree-dump-not "param=modref-max-accesses" "modref1" } } */ -- cgit v1.1 From 4892b3087412e6afc261cc9977ef4b54c799660f Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 23 Aug 2021 14:01:01 -0400 Subject: analyzer: fix uninit false positive on overlapping bindings gcc/analyzer/ChangeLog: * store.cc (bit_range::intersects_p): New overload. (bit_range::operator-): New. (binding_cluster::maybe_get_compound_binding): Handle the partial overlap case. (selftest::test_bit_range_intersects_p): Add test coverage for new overload of bit_range::intersects_p. * store.h (bit_range::intersects_p): New overload. (bit_range::operator-): New. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/data-model-22.c: New test. * gcc.dg/analyzer/uninit-6.c: New test. * gcc.dg/analyzer/uninit-6b.c: New test. --- gcc/testsuite/gcc.dg/analyzer/data-model-22.c | 101 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/uninit-6.c | 29 ++++++++ gcc/testsuite/gcc.dg/analyzer/uninit-6b.c | 29 ++++++++ 3 files changed, 159 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-22.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-6.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-6b.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-22.c b/gcc/testsuite/gcc.dg/analyzer/data-model-22.c new file mode 100644 index 0000000..8429b2f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-22.c @@ -0,0 +1,101 @@ +#include +#include "analyzer-decls.h" + +extern void check_init_char (char v); +extern void check_init_int (int v); + +void test_1 (void) +{ + union + { + char c[16]; + int i[4]; + } v; + memset (&v, 0, sizeof (v)); + v.c[5] = 42; + check_init_int (v.c[0]); + check_init_int (v.c[4]); + check_init_int (v.c[6]); + check_init_int (v.i[1]); +} + +void test_2 (void) +{ + /* Intersection of byte ranges within "v". */ + union + { + struct { + int a; + char b; + char c; + } __attribute__((packed)) icc; + struct { + char a; + int b; + char c; + } __attribute__((packed)) cic; + struct { + char a; + char b; + int c; + } __attribute__((packed)) cci; + } v; + + v.icc.a = 1066; + v.icc.b = 42; + v.icc.c = 17; + + __analyzer_eval (v.icc.a == 1066); /* { dg-warning "TRUE" } */ + __analyzer_eval (v.icc.b == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (v.icc.c == 17); /* { dg-warning "TRUE" } */ + check_init_int (v.icc.a); + check_init_char (v.icc.b); + check_init_char (v.icc.c); + + check_init_char (v.cic.a); + check_init_int (v.cic.b); + check_init_char (v.cic.c); + + check_init_char (v.cci.a); + check_init_char (v.cci.b); + check_init_int (v.cci.c); + + v.cic.a = 42; + v.cic.b = 1066; + v.cic.c = 17; + + __analyzer_eval (v.cic.a == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (v.cic.b == 1066); /* { dg-warning "TRUE" } */ + __analyzer_eval (v.cic.c == 17); /* { dg-warning "TRUE" } */ + check_init_int (v.icc.a); + check_init_char (v.icc.b); + check_init_char (v.icc.c); + + check_init_char (v.cic.a); + check_init_int (v.cic.b); + check_init_char (v.cic.c); + + check_init_char (v.cci.a); + check_init_char (v.cci.b); + check_init_int (v.cci.c); + + v.cci.a = 42; + v.cci.b = 17; + v.cci.c = 1066; + + __analyzer_eval (v.cci.a == 42); /* { dg-warning "TRUE" } */ + __analyzer_eval (v.cci.b == 17); /* { dg-warning "TRUE" } */ + __analyzer_eval (v.cci.c == 1066); /* { dg-warning "TRUE" } */ + check_init_int (v.icc.a); + check_init_char (v.icc.b); + check_init_char (v.icc.c); + + check_init_char (v.cic.a); + check_init_int (v.cic.b); + check_init_char (v.cic.c); + + check_init_char (v.cci.a); + check_init_char (v.cci.b); + check_init_int (v.cci.c); + +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-6.c b/gcc/testsuite/gcc.dg/analyzer/uninit-6.c new file mode 100644 index 0000000..75a99ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-6.c @@ -0,0 +1,29 @@ +/* Reduced from uninit false positive seen on Linux kernel with + net/ethtool/ioctl.c */ + +typedef signed char s8; +typedef unsigned int u32; +typedef __SIZE_TYPE__ size_t; + +void *memset(void *s, int c, size_t n); + +struct ethtool_link_settings { + u32 cmd; + s8 link_mode_masks_nwords; +}; + +struct ethtool_link_ksettings { + struct ethtool_link_settings base; + u32 lanes; +}; + +struct ethtool_link_settings +ethtool_get_link_ksettings(void) { + struct ethtool_link_ksettings link_ksettings; + + memset(&link_ksettings, 0, sizeof(link_ksettings)); + link_ksettings.base.cmd = 0x0000004c; + link_ksettings.base.link_mode_masks_nwords = -3; + + return link_ksettings.base; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-6b.c b/gcc/testsuite/gcc.dg/analyzer/uninit-6b.c new file mode 100644 index 0000000..32ba30f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-6b.c @@ -0,0 +1,29 @@ +/* Reduced from uninit false positive seen on Linux kernel with + net/ethtool/ioctl.c */ + +typedef signed char s8; +typedef unsigned int u32; +typedef __SIZE_TYPE__ size_t; + +void *memset(void *s, int c, size_t n); + +struct ethtool_link_settings { + u32 cmd; + s8 link_mode_masks_nwords; +}; + +struct ethtool_link_ksettings { + u32 lanes; + struct ethtool_link_settings base; +}; + +struct ethtool_link_settings +ethtool_get_link_ksettings(void) { + struct ethtool_link_ksettings link_ksettings; + + memset(&link_ksettings, 0, sizeof(link_ksettings)); + link_ksettings.base.cmd = 0x0000004c; + link_ksettings.base.link_mode_masks_nwords = -3; + + return link_ksettings.base; +} -- cgit v1.1 From e82e0f149b0aba660896ea9aa12c442c07a16d12 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 23 Aug 2021 14:07:39 -0400 Subject: analyzer: assume that POINTER_PLUS_EXPR of non-NULL is non-NULL [PR101962] gcc/analyzer/ChangeLog: PR analyzer/101962 * region-model.cc (region_model::eval_condition_without_cm): Refactor comparison against zero, adding a check for POINTER_PLUS_EXPR of non-NULL. gcc/testsuite/ChangeLog: PR analyzer/101962 * gcc.dg/analyzer/data-model-23.c: New test. * gcc.dg/analyzer/pr101962.c: New test. --- gcc/testsuite/gcc.dg/analyzer/data-model-23.c | 26 ++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr101962.c | 51 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-23.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101962.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-23.c b/gcc/testsuite/gcc.dg/analyzer/data-model-23.c new file mode 100644 index 0000000..c76dd4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-23.c @@ -0,0 +1,26 @@ +#include "analyzer-decls.h" + +#define NULL ((void *)0) + +void * __attribute__((noinline)) +hide (void *ptr) +{ + return ptr; +} + +void test_1 (void) +{ + int a; + __analyzer_eval (hide (&a) == NULL); /* { dg-warning "FALSE" } */ + __analyzer_eval (hide (&a) + 1 != NULL); /* { dg-warning "TRUE" } */ + __analyzer_eval (hide (&a) + 1 == NULL); /* { dg-warning "FALSE" } */ + __analyzer_eval (hide (&a) - 1 != NULL); /* { dg-warning "TRUE" } */ + __analyzer_eval (hide (&a) - 1 == NULL); /* { dg-warning "FALSE" } */ +} + +void test_2 (void) +{ + __analyzer_eval (hide (NULL) == NULL); /* { dg-warning "TRUE" } */ + __analyzer_eval (hide (NULL) - 1 == NULL); /* { dg-warning "FALSE" } */ + __analyzer_eval (hide (NULL) + 1 == NULL); /* { dg-warning "FALSE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/gcc.dg/analyzer/pr101962.c new file mode 100644 index 0000000..7b83d03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101962.c @@ -0,0 +1,51 @@ +#include "analyzer-decls.h" + +#define NULL ((void *)0) + +/* Verify that the analyzer makes the simplifying assumption that we don't + hit NULL when incrementing pointers to non-NULL memory regions. */ + +static int * __attribute__((noinline)) +maybe_inc_int_ptr (int *ptr) +{ + if (!ptr) + return NULL; + return ++ptr; +} + +int +test_1 (void) +{ + int stack; + int *a = &stack; + a = maybe_inc_int_ptr (a); + a = maybe_inc_int_ptr (a); + __analyzer_eval (a == NULL); /* { dg-warning "FALSE" } */ + __analyzer_eval (a != NULL); /* { dg-warning "TRUE" } */ + return *a; /* { dg-warning "use of uninitialized value '\\*a'" } */ + /* TODO: a complaint about out-of-bounds would be a better warning. */ +} + +static const char * __attribute__((noinline)) +maybe_inc_char_ptr (const char *ptr) +{ + if (!ptr) + return NULL; + return ++ptr; +} + +char +test_s (void) +{ + const char *msg = "hello world"; + const char *a = msg; + __analyzer_eval (*a == 'h'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'e'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'l'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'l'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'o'); /* { dg-warning "TRUE" } */ +} -- cgit v1.1 From 4b821c7efbe12cfbb129a88541108b39058da526 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 23 Aug 2021 14:09:44 -0400 Subject: analyzer: fix ICE when failing to reconstruct a fn ptr [PR101837] gcc/analyzer/ChangeLog: PR analyzer/101837 * analyzer.cc (maybe_reconstruct_from_def_stmt): Bail if fn is NULL, and assert that it's non-NULL before passing it to build_call_array_loc. gcc/testsuite/ChangeLog: PR analyzer/101837 * gcc.dg/analyzer/pr101837.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr101837.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101837.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101837.c b/gcc/testsuite/gcc.dg/analyzer/pr101837.c new file mode 100644 index 0000000..f99374d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101837.c @@ -0,0 +1,10 @@ +/* { dg-additional-options "-O3 -fsanitize=undefined" } */ + +void memory_exhausted(); +void memcheck(void *ptr) { + if (ptr) /* { dg-warning "leak" } */ + memory_exhausted(); +} + +int emalloc(int size) { memcheck(__builtin_malloc(size)); } /* { dg-message "allocated here" } */ +int main() { int max_envvar_len = emalloc(max_envvar_len + 1); } /* { dg-message "use of uninitialized value 'max_envvar_len'" } */ -- cgit v1.1 From 3d654ca3f421ff9646470d312097602037176352 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 23 Aug 2021 14:11:58 -0400 Subject: analyzer: fix ICE with NULL change.m_expr [PR101875] gcc/analyzer/ChangeLog: PR analyzer/101875 * sm-file.cc (file_diagnostic::describe_state_change): Handle change.m_expr being NULL. gcc/testsuite/ChangeLog: PR analyzer/101875 * gcc.dg/analyzer/pr101875.c: New test. --- gcc/testsuite/gcc.dg/analyzer/pr101875.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101875.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101875.c b/gcc/testsuite/gcc.dg/analyzer/pr101875.c new file mode 100644 index 0000000..5988b8e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101875.c @@ -0,0 +1,16 @@ +char * +fopen (const char *restrict, const char *restrict); + +void +err (void); + +void +k2 (void) +{ + char *setfiles[1]; + int i; + + setfiles[i] = fopen("", ""); /* { dg-warning "use of uninitialized value 'i'" } */ + if (!setfiles[i]) /* { dg-warning "use of uninitialized value 'i'" } */ + err (); +} /* { dg-warning "leak of FILE" } */ -- cgit v1.1 From 8ca7fa84a3af355c3e2bbda2acc61934c16078b2 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 23 Aug 2021 19:27:21 -0400 Subject: analyzer: rewrite of switch handling When investigating false positives on the Linux kernel from -Wanalyzer-use-of-uninitialized-value, I noticed that the existing implementation of switch statements in the analyzer is broken. Specifically, the existing implementation assumes a 1:1 association between CFG out-edges from the basic block and case labels in the gimple switch statement. This happened to be the case in the examples I had tested, but there is no such association in general. In particular, in the motivating example: arch/x86/kernel/cpu/mtrr/if.c: mtrr_ioctl the switch statement has 3 blocks, each covering multiple ranges of ioctl command IDs for which different local variables are initialized, which the existing implementation gets badly wrong. [1] This patch reimplements switch handling in the analyzer to eliminate this false assumption - instead, for each out-edge we gather the set of case labels for that out-edge, and use that to determine the set of value ranges for the edge. Avoiding false positives for the above example requires that we accurately track value ranges for symbolic values, so the patch extends constraint_manager with a new bounded_ranges_constraint, adding just enough information to capture the ranges for switch statements whilst retaining combatility with the existing constraint-handling (ultimately I'd prefer to simply throw all of this into a SAT solver and let it track things). Doing so fixes the false positives seen on the Linux kernel and an existing xfail in the test suite. The patch also fixes a long-standing bug in constraint_manager::add_unknown_constraint when updating constraints due to combining equivalence classes, spotted when debugging the same logic for the new kind of constraints. [1] a reduced version of this code is captured in this patch, in gcc.dg/analyzer/torture/switch-3.c gcc/analyzer/ChangeLog: * analyzer.h (struct rejected_constraint): Convert to... (class rejected_constraint): ...this. (class bounded_ranges): New forward decl. (class bounded_ranges_manager): New forward decl. * constraint-manager.cc: Include "analyzer/analyzer-logging.h" and "tree-pretty-print.h". (can_plus_one_p): New. (plus_one): New. (can_minus_one_p): New. (minus_one): New. (bounded_range::bounded_range): New. (dump_cst): New. (bounded_range::dump_to_pp): New. (bounded_range::dump): New. (bounded_range::to_json): New. (bounded_range::set_json_attr): New. (bounded_range::contains_p): New. (bounded_range::intersects_p): New. (bounded_range::operator==): New. (bounded_range::cmp): New. (bounded_ranges::bounded_ranges): New. (bounded_ranges::bounded_ranges): New. (bounded_ranges::bounded_ranges): New. (bounded_ranges::canonicalize): New. (bounded_ranges::validate): New. (bounded_ranges::operator==): New. (bounded_ranges::dump_to_pp): New. (bounded_ranges::dump): New. (bounded_ranges::to_json): New. (bounded_ranges::eval_condition): New. (bounded_ranges::contain_p): New. (bounded_ranges::cmp): New. (bounded_ranges_manager::~bounded_ranges_manager): New. (bounded_ranges_manager::get_or_create_empty): New. (bounded_ranges_manager::get_or_create_point): New. (bounded_ranges_manager::get_or_create_range): New. (bounded_ranges_manager::get_or_create_union): New. (bounded_ranges_manager::get_or_create_intersection): New. (bounded_ranges_manager::get_or_create_inverse): New. (bounded_ranges_manager::consolidate): New. (bounded_ranges_manager::get_or_create_ranges_for_switch): New. (bounded_ranges_manager::create_ranges_for_switch): New. (bounded_ranges_manager::make_case_label_ranges): New. (bounded_ranges_manager::log_stats): New. (bounded_ranges_constraint::print): New. (bounded_ranges_constraint::to_json): New. (bounded_ranges_constraint::operator==): New. (bounded_ranges_constraint::add_to_hash): New. (constraint_manager::constraint_manager): Update for new field m_bounded_ranges_constraints. (constraint_manager::operator=): Likewise. (constraint_manager::hash): Likewise. (constraint_manager::operator==): Likewise. (constraint_manager::print): Likewise. (constraint_manager::dump_to_pp): Likewise. (constraint_manager::to_json): Likewise. (constraint_manager::add_unknown_constraint): Update the lhs_ec_id if necessary in existing constraints when combining equivalence classes. Add similar code for handling m_bounded_ranges_constraints. (constraint_manager::add_constraint_internal): Add comment. (constraint_manager::add_bounded_ranges): New. (constraint_manager::eval_condition): Use new field m_bounded_ranges_constraints. (constraint_manager::purge): Update bounded_ranges_constraint instances. (constraint_manager::canonicalize): Update for new field. (merger_fact_visitor::on_ranges): New. (constraint_manager::for_each_fact): Use new field m_bounded_ranges_constraints. (constraint_manager::validate): Fix off-by-one error needed due to bug fixed above in add_unknown_constraint. Validate the EC IDs in m_bounded_ranges_constraints. (constraint_manager::get_range_manager): New. (selftest::assert_dump_bounded_range_eq): New. (ASSERT_DUMP_BOUNDED_RANGE_EQ): New. (selftest::test_bounded_range): New. (selftest::assert_dump_bounded_ranges_eq): New. (ASSERT_DUMP_BOUNDED_RANGES_EQ): New. (selftest::test_bounded_ranges): New. (selftest::run_constraint_manager_tests): Call the new selftests. * constraint-manager.h (struct bounded_range): New. (struct bounded_ranges): New. (template <> struct default_hash_traits): New. (class bounded_ranges_manager): New. (fact_visitor::on_ranges): New pure virtual function. (class bounded_ranges_constraint): New. (constraint_manager::add_bounded_ranges): New decl. (constraint_manager::get_range_manager): New decl. (constraint_manager::m_bounded_ranges_constraints): New field. * diagnostic-manager.cc (epath_finder::process_worklist_item): Transfer ownership of rc to add_feasibility_problem. * engine.cc (feasibility_problem::dump_to_pp): Use get_model. * feasible-graph.cc (infeasible_node::dump_dot): Update for conversion of m_rc to a pointer. (feasible_graph::add_feasibility_problem): Pass RC by pointer and take ownership. * feasible-graph.h (infeasible_node::infeasible_node): Pass RC by pointer and take ownership. (infeasible_node::~infeasible_node): New. (infeasible_node::m_rc): Convert to a pointer. (feasible_graph::add_feasibility_problem): Pass RC by pointer and take ownership. * region-model-manager.cc: Include "analyzer/constraint-manager.h". (region_model_manager::region_model_manager): Initializer new field m_range_mgr. (region_model_manager::~region_model_manager): Delete it. (region_model_manager::log_stats): Call log_stats on it. * region-model.cc (region_model::add_constraint): Use new subclass rejected_op_constraint. (region_model::apply_constraints_for_gswitch): Reimplement using bounded_ranges_manager. (rejected_constraint::dump_to_pp): Convert to... (rejected_op_constraint::dump_to_pp): ...this. (rejected_ranges_constraint::dump_to_pp): New. * region-model.h (struct purge_stats): Add field m_num_bounded_ranges_constraints. (region_model_manager::get_range_manager): New. (region_model_manager::m_range_mgr): New. (region_model::get_range_manager): New. (struct rejected_constraint): Split into... (class rejected_constraint):...this new abstract base class, and... (class rejected_op_constraint): ...this new concrete subclass. (class rejected_ranges_constraint): New. * supergraph.cc: Include "tree-cfg.h". (supergraph::supergraph): Drop idx param from add_cfg_edge. (supergraph::add_cfg_edge): Drop idx param. (switch_cfg_superedge::switch_cfg_superedge): Move here from header. Populate m_case_labels with all cases which go to DST. (switch_cfg_superedge::dump_label_to_pp): Reimplement to use m_case_labels. (switch_cfg_superedge::get_case_label): Delete. * supergraph.h (supergraphadd_cfg_edge): Drop "idx" param. (switch_cfg_superedge::switch_cfg_superedge): Drop idx param and move implementation to supergraph.cc. (switch_cfg_superedge::get_case_label): Delete. (switch_cfg_superedge::get_case_labels): New. (switch_cfg_superedge::m_idx): Delete. (switch_cfg_superedge::m_case_labels): New field. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/switch.c: Remove xfail. Add various tests. * gcc.dg/analyzer/torture/switch-2.c: New test. * gcc.dg/analyzer/torture/switch-3.c: New test. * gcc.dg/analyzer/torture/switch-4.c: New test. * gcc.dg/analyzer/torture/switch-5.c: New test. --- gcc/testsuite/gcc.dg/analyzer/switch.c | 141 +++++++++++++++++++- gcc/testsuite/gcc.dg/analyzer/torture/switch-2.c | 42 ++++++ gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c | 158 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/torture/switch-4.c | 27 ++++ gcc/testsuite/gcc.dg/analyzer/torture/switch-5.c | 68 ++++++++++ 5 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/switch-2.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/switch-4.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/switch-5.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/switch.c b/gcc/testsuite/gcc.dg/analyzer/switch.c index 870b00f..0b9e7e3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/switch.c +++ b/gcc/testsuite/gcc.dg/analyzer/switch.c @@ -8,23 +8,156 @@ void test (int i) { case 0: __analyzer_eval (i == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != -1); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 0); /* { dg-warning "FALSE" } */ + __analyzer_eval (i != 1); /* { dg-warning "TRUE" } */ break; case 3 ... 5: + __analyzer_eval (i != 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (i > 1); /* { dg-warning "TRUE" } */ + __analyzer_eval (i > 2); /* { dg-warning "TRUE" } */ + __analyzer_eval (i >= 2); /* { dg-warning "TRUE" } */ __analyzer_eval (i >= 3); /* { dg-warning "TRUE" } */ __analyzer_eval (i <= 5); /* { dg-warning "TRUE" } */ + __analyzer_eval (i < 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (i <= 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (i < 7); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 3); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i != 4); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i != 5); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i >= 4); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i >= 5); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i <= 3); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i <= 4); /* { dg-warning "UNKNOWN" } */ break; default: + __analyzer_eval (i == -1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i == 0); /* { dg-warning "FALSE" } */ __analyzer_eval (i == 2); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i == 3); /* { dg-warning "FALSE" } */ - __analyzer_eval (i == 4); /* { dg-warning "FALSE" "desired" { xfail *-*-* } } */ - /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ - /* TODO(xfail^^^): we're only checking against endpoints of case - ranges, not the insides. */ + __analyzer_eval (i == 4); /* { dg-warning "FALSE" } */ __analyzer_eval (i == 5); /* { dg-warning "FALSE" } */ __analyzer_eval (i == 6); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i != 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (i != 3); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 4); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 5); /* { dg-warning "TRUE" } */ + __analyzer_eval (i != 6); /* { dg-warning "UNKNOWN" } */ break; } } + +/* Verify that the analyzer follows the correct paths on a + switch statement guarded by an if, using noinline to defeat + optimizations. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_2 (int y) +{ + switch (y) + { + case 0: + __analyzer_dump_path (); /* { dg-bogus "path" } */ + break; + case 1: + __analyzer_dump_path (); /* { dg-message "path" } */ + break; + case 2: + __analyzer_dump_path (); /* { dg-bogus "path" } */ + break; + default: + __analyzer_dump_path (); /* { dg-bogus "path" } */ + break; + } +} + +void test_2 (int x) +{ + if (x == 1) + __analyzer_called_by_test_2 (x); +} + +void test_3 (int x, int y) +{ + if (y == 3) + switch (x) + { + case 0 ... 9: + case 20 ... 29: + if (x == y) + __analyzer_dump_path (); /* { dg-message "path" } */ + else + __analyzer_dump_path (); /* { dg-message "path" } */ + } +} + +struct s4 +{ + unsigned char level:3; + unsigned char key_id_mode:2; + unsigned char reserved:3; +}; + +void test_4 (struct s4 *p) +{ + switch (p->key_id_mode) + { + case 0: + __analyzer_dump_path (); /* { dg-message "path" } */ + break; + case 1: + __analyzer_dump_path (); /* { dg-message "path" } */ + break; + case 2: + __analyzer_dump_path (); /* { dg-message "path" } */ + break; + case 3: + __analyzer_dump_path (); /* { dg-message "path" } */ + break; + } + __analyzer_dump_path (); /* { dg-message "path" } */ +} + +int test_5 (unsigned v) +{ + switch (v) + { + case 0: + return 7; + break; + case 1: + return 23; + break; + default: + return v * 2; + } +} + +int test_6 (unsigned v) +{ + switch (v) + { + case 0: + return 3; + case -1: + return 22; + } + return -3; +} + +int g7 = -1; +int test_7 () +{ + switch (g7++) { + case 0: + return 32; + + case 100: + return 42; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/switch-2.c b/gcc/testsuite/gcc.dg/analyzer/torture/switch-2.c new file mode 100644 index 0000000..3da2e30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/switch-2.c @@ -0,0 +1,42 @@ +struct s +{ + int f0; + int f1; +}; + +int test (int cmd) +{ + int err = 0; + struct s foo; + struct s bar; + + switch (cmd) + { + case 0: + foo.f0 = 0; + break; + case 1: + foo.f0 = 1; + break; + case 30 ... 50: + case 70 ... 80: + __builtin_memset (&bar, 0, sizeof (bar)); + break; + } + + switch (cmd) + { + default: + return -1; + case 0 ... 1: + return foo.f0; + break; + case 42: + return bar.f1; + break; + case 65: + return bar.f1; + break; + } + return err; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c b/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c new file mode 100644 index 0000000..57b8acd --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c @@ -0,0 +1,158 @@ +typedef unsigned int __u32; +__extension__ typedef unsigned long long __u64; + +extern unsigned long +copy_from_user(void *to, const void *from, unsigned long n); + +extern unsigned long +copy_to_user(void *to, const void *from, unsigned long n); + +struct mtrr_sentry { + __u64 base; + __u32 size; + __u32 type; +}; + +struct mtrr_gentry { + __u64 base; + __u32 size; + __u32 regnum; + __u32 type; + __u32 _pad; +}; + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +#define _IOC_TYPECHECK(t) (sizeof(t)) + +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) + +#define MTRR_IOCTL_BASE 'M' + +#define EFAULT 14 +#define EINVAL 22 +#define ENOTTY 25 + +#define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry) +#define MTRRIOC_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry) +#define MTRRIOC_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry) +#define MTRRIOC_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry) +#define MTRRIOC_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry) +#define MTRRIOC_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry) +#define MTRRIOC_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry) +#define MTRRIOC_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry) +#define MTRRIOC_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry) +#define MTRRIOC_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry) + +extern void check_init_u64 (__u64 v); +extern void check_init_u32 (__u32 v); + +/* Adapted/reduced from arch/x86/kernel/cpu/mtrr/if.c: mtrr_ioctl, + which is GPL-2.0 */ + +long mtrr_ioctl(unsigned int cmd, unsigned long __arg) { + int err = 0; + struct mtrr_sentry sentry; + struct mtrr_gentry gentry; + void *arg = (void *)__arg; + + __builtin_memset(&gentry, 0, sizeof(gentry)); + + switch (cmd) { + case MTRRIOC_ADD_ENTRY: + case MTRRIOC_SET_ENTRY: + case MTRRIOC_DEL_ENTRY: + case MTRRIOC_KILL_ENTRY: + case MTRRIOC_ADD_PAGE_ENTRY: + case MTRRIOC_SET_PAGE_ENTRY: + case MTRRIOC_DEL_PAGE_ENTRY: + case MTRRIOC_KILL_PAGE_ENTRY: + if (copy_from_user(&sentry, arg, sizeof(sentry))) + return -EFAULT; + break; + case MTRRIOC_GET_ENTRY: + case MTRRIOC_GET_PAGE_ENTRY: + if (copy_from_user(&gentry, arg, sizeof(gentry))) + return -EFAULT; + break; + } + + switch (cmd) { + default: + return -ENOTTY; + case MTRRIOC_ADD_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_SET_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_DEL_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_KILL_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_GET_ENTRY: + check_init_u64 (gentry.base); + check_init_u32 (gentry.size); + check_init_u32 (gentry.regnum); + check_init_u32 (gentry.type); + check_init_u32 (gentry._pad); + break; + case MTRRIOC_ADD_PAGE_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_SET_PAGE_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_DEL_PAGE_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_KILL_PAGE_ENTRY: + check_init_u64 (sentry.base); + check_init_u32 (sentry.size); + check_init_u32 (sentry.type); + break; + case MTRRIOC_GET_PAGE_ENTRY: + check_init_u64 (gentry.base); + check_init_u32 (gentry.size); + check_init_u32 (gentry.regnum); + check_init_u32 (gentry.type); + check_init_u32 (gentry._pad); + break; + } + + return err; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/switch-4.c b/gcc/testsuite/gcc.dg/analyzer/torture/switch-4.c new file mode 100644 index 0000000..f5cdb5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/switch-4.c @@ -0,0 +1,27 @@ +struct snd_ac97 { + // snip + unsigned int id; + // snip +}; + +int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) { + + switch (ac97->id) { + case 0x53544d02: + if (reg == 0x22 || reg == 0x7a) + return 1; + __attribute__((__fallthrough__)); + case 0x414b4d00: + return 0; + } + return 1; +} + +int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg) { + if (ac97->id == 0x414c4781) + { + if (!snd_ac97_valid_reg(ac97, reg)) + return -22; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/switch-5.c b/gcc/testsuite/gcc.dg/analyzer/torture/switch-5.c new file mode 100644 index 0000000..10b2f29 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/switch-5.c @@ -0,0 +1,68 @@ +/* { dg-additional-options "-fno-analyzer-call-summaries" } */ + +typedef unsigned char u8; +typedef signed int s32; +typedef unsigned int u32; + +enum v4l2_mpeg_video_hevc_profile { + V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN = 0, + V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE = 1, + V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 = 2 +}; +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2 +}; +struct v4l2_fmtdesc { + u32 index; + u32 type; +}; +struct v4l2_ctrl; +s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl); +struct create_channel_param { + u8 profile; +}; + +u8 +hevc_profile_to_mcu_profile(enum v4l2_mpeg_video_hevc_profile profile) { + switch (profile) { + default: + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: + return 1; + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10: + return 2; + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: + return 3; + } +} + +int fill_create_channel_param(struct v4l2_ctrl *ctrl, + struct create_channel_param *param) { + enum v4l2_mpeg_video_hevc_profile profile; + profile = v4l2_ctrl_g_ctrl(ctrl); + param->profile = hevc_profile_to_mcu_profile(profile); + return 0; +} + +int allegro_enum_fmt_vid(struct v4l2_fmtdesc *f) { + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (f->index >= 1) + return -22; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (f->index >= 2) + return -22; + break; + default: + return -22; + } + return 0; +} + +int allegro_ioctl_streamon(struct v4l2_ctrl *ctrl, + struct create_channel_param *param) { + fill_create_channel_param(ctrl, param); + + return 0; +} -- cgit v1.1 From 78fa5112b4c2dcd94b78ee79baddebbf14d6ad98 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 24 Aug 2021 02:59:02 +0100 Subject: [Committed] PR middle-end/102029: Stricter typing in LSHIFT_EXPR sign folding. My sincere apologies to everyone (again). As diagnosed by Jakub Jelinek, my recent patch to fold the signedness of LSHIFT_EXPR needs to be careful not to attempt transforming a left shift in an integer type into an invalid left shift of a pointer type. 2021-08-24 Roger Sayle Jakub Jelinek gcc/ChangeLog PR middle-end/102029 * match.pd (shift transformations): Add an additional check for !POINTER_TYPE_P in the recently added left shift transformation. gcc/testsuite/ChangeLog PR middle-end/102029 * gcc.dg/fold-convlshift-3.c: New test case. --- gcc/testsuite/gcc.dg/fold-convlshift-3.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-convlshift-3.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/fold-convlshift-3.c b/gcc/testsuite/gcc.dg/fold-convlshift-3.c new file mode 100644 index 0000000..8d01191 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-convlshift-3.c @@ -0,0 +1,8 @@ +/* PR middle-end/102029 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +int * +foo (const __PTRDIFF_TYPE__ l) +{ + return (int *) (l << 2); +} -- cgit v1.1 From 675a3e40567e1d0dd6d7e7be3efab74b22731415 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 18 Aug 2021 16:36:19 -0400 Subject: Add transitive operations to the relation oracle. When registering relations in the oracle, search for other relations which imply new transitive relations. gcc/ * 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. gcc/testsuite/ * gcc.dg/predict-1.c: Disable evrp. * gcc.dg/tree-ssa/evrp-trans.c: New. --- gcc/testsuite/gcc.dg/predict-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/evrp-trans.c | 144 +++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/evrp-trans.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/predict-1.c b/gcc/testsuite/gcc.dg/predict-1.c index 9e5605a..d2e753e 100644 --- a/gcc/testsuite/gcc.dg/predict-1.c +++ b/gcc/testsuite/gcc.dg/predict-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-profile_estimate" } */ +/* { dg-options "-O2 -fdump-tree-profile_estimate --disable-tree-evrp" } */ extern int global; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp-trans.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp-trans.c new file mode 100644 index 0000000..8ee8e3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp-trans.c @@ -0,0 +1,144 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +/* Simple tests to make sure transitives are working. */ +void keep(); +void kill(); + +void +f1 (int x, int y, int z) +{ + if (x > y) + if (y > z) + { + if (x > z) + keep (); + else + kill (); + } +} + +void +f2 (int w, int x, int y, int z) +{ + // Test one equivalence. + if (w == z) + if (x > y) + if (y > z) + { + if (x > w) + keep (); + else + kill (); + } +} + +void +f3 (int a, int w, int x, int y, int z) +{ + // Test two equivlaences. + if (a == x) + if (w == z) + if (x > y) + if (y > z) + { + if (a > w) + keep (); + else + kill (); + } +} + +void +f4 (int x, int y, int z) +{ + // test X > Y >= Z + if (x > y) + if (y >= z) + { + if (x > z) + keep (); + else + kill (); + } +} +void +f5 (int x, int y, int z) +{ + // test X >= Y > Z + if (x >= y) + if (y > z) + { + if (x > z) + keep (); + else + kill (); + } +} + +void +f6 (int x, int y, int z) +{ + // test X >= Y >= Z + if (x >= y) + if (y >= z) + { + if (x > z) + keep (); + else if (x == z) + keep (); + else + kill (); + } +} + +void +f7 (int x, int y, int z) +{ + // test Y <= X , Z <= Y + if (y <= x) + if (z <= y) + { + if (x > z) + keep (); + else if (x == z) + keep (); + else + kill (); + } +} + +void +f8 (int x, int y, int z) +{ + // test X >= Y, Z <= Y + if (x >= y) + if (z <= y) + { + if (x > z) + keep (); + else if (x == z) + keep (); + else + kill (); + } +} + +void +f9 (int x, int y, int z) +{ + // test Y <= X Y >= Z + if (y <= x) + if (y >= z) + { + if (x > z) + keep (); + else if (x == z) + keep (); + else + kill (); + } +} + +/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */ +/* { dg-final { scan-tree-dump-times "keep" 13 "evrp"} } */ -- cgit v1.1 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/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 +++++---- 4 files changed, 177 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-88.c (limited to 'gcc/testsuite/gcc.dg') 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 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 ++++ 8 files changed, 367 insertions(+) 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/testsuite/gcc.dg') 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); +} -- 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 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr102046.c (limited to 'gcc/testsuite/gcc.dg') 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; +} -- 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/testsuite/gcc.dg/diagnostic-input-charset-1.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c | 14 ++++++++++++++ 2 files changed, 31 insertions(+) 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/testsuite/gcc.dg') 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 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/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 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/modref-8.c (limited to 'gcc/testsuite/gcc.dg') 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 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/testsuite/gcc.dg') 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 b2ef23239f245871e9b35b902391f2e94a041627 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Thu, 26 Aug 2021 18:57:00 +0100 Subject: Improved handling of shifts/rotates in bit CCP. This patch is the next in the series to improve bit bounds in tree-ssa's bit CCP pass, this time: bounds for shifts and rotates by unknown amounts. This allows us to optimize expressions such as ((x&15)<<(y&24))&64. In this case, the expression (y&24) contains only two unknown bits, and can therefore have only four possible values: 0, 8, 16 and 24. From this (x&15)<<(y&24) has the nonzero bits 0x0f0f0f0f, and from that ((x&15)<<(y&24))&64 must always be zero. One clever use of computer science in this patch is the use of XOR to efficiently enumerate bit patterns in Gray code order. As the order in which we generate values is not significant, it's faster and more convenient to enumerate values by flipping one bit at a time, rather than in numerical order [which would require carry bits and additional logic]. There's a pre-existing ??? comment in tree-ssa-ccp.c that we should eventually be able to optimize (x<<(y|8))&255, but this patch takes the conservatively paranoid approach of only optimizing cases where the shift/rotate is guaranteed to be less than the target precision, and therefore avoids changing any cases that potentially might invoke undefined behavior. This patch does optimize (x<<((y&31)|8))&255. 2021-08-26 Roger Sayle gcc/ChangeLog * tree-ssa-ccp.c (get_individual_bits): Helper function to extract the individual bits from a widest_int constant (mask). (gray_code_bit_flips): New read-only table for effiently enumerating permutations/combinations of bits. (bit_value_binop) [LROTATE_EXPR, RROTATE_EXPR]: Handle rotates by unknown counts that are guaranteed less than the target precision and four or fewer unknown bits by enumeration. [LSHIFT_EXPR, RSHIFT_EXPR]: Likewise, also handle shifts by enumeration under the same conditions. Handle remaining shifts as a mask based upon the minimum possible shift value. gcc/testsuite/ChangeLog * gcc.dg/tree-ssa/ssa-ccp-41.c: New test case. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-41.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-41.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-41.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-41.c new file mode 100644 index 0000000..d2b054e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-41.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int foo(int x) +{ + int p = x & 24; + int r = 1 << p; + return r & (1<<17); +} + +/* { dg-final { scan-tree-dump "return 0;" "optimized" } } */ -- cgit v1.1 From 41439e1f6d2da1e86538c726f0603cffd5dd098e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 27 Aug 2021 09:47:49 +0200 Subject: tree-optimization/45178 - DCE of dead control flow in infinite loop This fixes DCE to be able to elide dead control flow in an infinite loop without an exit edge. This special situation is handled well by the code finding an edge to preserve since there's no chance it will find the exit edge and make the loop finite. 2021-08-27 Richard Biener PR tree-optimization/45178 * tree-ssa-dce.c (find_obviously_necessary_stmts): For infinite loops without exit do not mark control dependent edges of the latch necessary. * gcc.dg/tree-ssa/ssa-dce-3.c: Adjust testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c index 863aa79..fdfe37e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c @@ -21,11 +21,12 @@ int main(void) return 0; } -/* We now can prove the infiniteness of the loop during CCP and fail - to eliminate the code inside the infinite loop because we start - by marking the j % 7 condition as useful. See PR45178. */ +/* We now can prove the infiniteness of the loop during CCP but we + still want to eliminate the code inside the infinite loop. See PR45178. */ /* We should eliminate the inner condition, but the loop must be preserved - as it is infinite. Therefore there should be just one goto and no PHI. */ + as it is infinite. Therefore there should be just one goto and no PHI + and no if. */ /* { dg-final { scan-tree-dump-times "PHI " 0 "cddce1" } } */ +/* { dg-final { scan-tree-dump-times "if " 0 "cddce1" } } */ /* { dg-final { scan-tree-dump-times "goto" 1 "cddce1" } } */ -- cgit v1.1 From f5ff3a8ed4ca91737c16757ce4938cf2e0187fc0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 28 Aug 2021 20:57:08 +0200 Subject: Improve handling of table overflows in modref_ref_node gcc/ChangeLog: * ipa-modref-tree.h (modref_access_node::merge): Break out logic combining offsets and logic merging ranges to ... (modref_access_node::combined_offsets): ... here (modref_access_node::update2): ... here (modref_access_node::closer_pair_p): New member function. (modref_access_node::forced_merge): New member function. (modre_ref_node::insert): Do merging when table is full. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/modref-9.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/modref-9.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/modref-9.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-9.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-9.c new file mode 100644 index 0000000..02de2f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-9.c @@ -0,0 +1,15 @@ +/* { dg-options "-O2 --param modref-max-accesses=2 -fdump-tree-modref1" } */ +/* { dg-do compile } */ +void +test(char *a) +{ + a[0] = 0; + a[1] = 1; + a[3] = 3; + a[7] = 7; + a[9] = 9; +} +/* We allow only two accesses per function. + It is best to group together {0,1,3} and {7,9}. */ +/* { dg-final { scan-tree-dump "access: Parm 0 param offset:0 offset:0 size:8 max_size:32" "modref1" } } */ +/* { dg-final { scan-tree-dump "access: Parm 0 param offset:7 offset:0 size:8 max_size:24" "modref1" } } */ -- cgit v1.1 From dc033e0149fd7790b89f816041e87a6ddc22e21c Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Mon, 15 Mar 2021 21:40:40 +0000 Subject: testsuite, Darwin : Skip a test requiring strndup in libc. Before Darwin11 there is no strndup in libc. This test fails with warning output because of that - so skip it on these versions (since they are not able to use strndup anyway). gcc/testsuite/ChangeLog: * gcc.dg/analyzer/strndup-1.c: Skip for Darwin versions without strndup support in libc. --- gcc/testsuite/gcc.dg/analyzer/strndup-1.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c index 23d9b60..5822353 100644 --- a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "no strndup in libc" { *-*-darwin[789]* *-*-darwin10* } } */ #include #include -- cgit v1.1 From eafa9d969237fd8f712c4b25a8c58932c01f44b4 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 30 Aug 2021 18:36:31 -0400 Subject: analyzer: support "bifurcation"; reimplement realloc [PR99260] Most of the state-management code in the analyzer involves modifying state objects in-place, which implies a single outcome. (I originally implemented in-place modification because I wanted to avoid having to create copies of state objects, and it's now very difficult to change this aspect of the analyzer's design) However, there are various special-cases such as "realloc" for which it's best to split the state into multiple outcomes. This patch adds a mechanism for "bifurcating" the analysis in places where there isn't a split in the CFG, and uses it to implement realloc, in this case treating it as having 3 possible outcomes: - failure, returning NULL - success, growing the buffer in-place without moving it - success, allocating a new buffer, copying the content of the old buffer to it, and freeing the old buffer. gcc/ChangeLog: PR analyzer/99260 * Makefile.in (ANALYZER_OBJS): Add analyzer/call-info.o. gcc/analyzer/ChangeLog: PR analyzer/99260 * analyzer.h (class custom_edge_info): New class, adapted from exploded_edge::custom_info_t. Make member functions const. Make update_model return bool, converting edge param from reference to a pointer, and adding a ctxt param. (class path_context): New class. * call-info.cc: New file. * call-info.h: New file. * engine.cc: Include "analyzer/call-info.h" and . (impl_region_model_context::impl_region_model_context): Update for new m_path_ctxt field. (impl_region_model_context::bifurcate): New. (impl_region_model_context::terminate_path): New. (impl_region_model_context::get_malloc_map): New. (impl_sm_context::impl_sm_context): Update for new m_path_ctxt field. (impl_sm_context::get_fndecl_for_call): Likewise. (impl_sm_context::set_next_state): Likewise. (impl_sm_context::warn): Likewise. (impl_sm_context::is_zero_assignment): Likewise. (impl_sm_context::get_path_context): New. (impl_sm_context::m_path_ctxt): New. (impl_region_model_context::on_condition): Update for new path_ctxt param. Handle m_enode_for_diag being NULL. (impl_region_model_context::on_phi): Update for new path_ctxt param. (exploded_node::on_stmt): Add path_ctxt param, updating ctor calls to use it as necessary. Use it to bail out after sm-handling, if needed. (exploded_node::detect_leaks): Update for new path_ctxt param. (dynamic_call_info_t::update_model): Update for conversion of exploded_edge::custom_info_t to custom_edge_info. (dynamic_call_info_t::add_events_to_path): Likewise. (rewind_info_t::update_model): Likewise. (rewind_info_t::add_events_to_path): Likewise. (exploded_edge::exploded_edge): Likewise. (exploded_graph::add_edge): Likewise. (exploded_graph::maybe_process_run_of_before_supernode_enodes): Update for new path_ctxt param. (class impl_path_context): New. (exploded_graph::process_node): Update for new path_ctxt param. Create an impl_path_context and pass it to exploded_node::on_stmt. Use it to terminate iterating stmts if terminate_path is called on it. After processing a run of stmts, query path_ctxt to potentially terminate the analysis path, and/or to "bifurcate" the analysis into multiple additional paths. (feasibility_state::maybe_update_for_edge): Update for new update_model ctxt param. * exploded-graph.h (impl_region_model_context::impl_region_model_context): Add path_ctxt param. (impl_region_model_context::bifurcate): New. (impl_region_model_context::terminate_path): New (impl_region_model_context::get_ext_state): New. (impl_region_model_context::get_malloc_map): New. (impl_region_model_context::m_path_ctxt): New field. (exploded_node::on_stmt): Add path_ctxt param. (class exploded_edge::custom_info_t): Move to analyzer.h, renaming to custom_edge_info, and making the changes as noted in analyzer.h above. (exploded_edge::exploded_edge): Update for these changes to exploded_edge::custom_info_t. (exploded_edge::m_custom_info): Likewise. (class dynamic_call_info_t): Likewise. (class rewind_info_t): Likewise. (exploded_graph::add_edge): Likewise. * program-state.cc (program_state::on_edge): Update for new path_ctxt param. (program_state::push_call): Likewise. (program_state::returning_call): Likewise. (program_state::prune_for_point): Likewise. * region-model-impl-calls.cc: Include "analyzer/call-info.h". (call_details::get_fndecl_for_call): New. (region_model::impl_call_realloc): Reimplement. * region-model.cc (region_model::on_call_pre): Move call to impl_call_realloc to... (region_model::on_call_post): ...here. Consolidate creation of call_details instance. (noop_region_model_context::bifurcate): New. (noop_region_model_context::terminate_path): New. * region-model.h (call_details::get_call_stmt): New. (call_details::get_fndecl_for_call): New. (region_model::on_realloc_with_move): New. (region_model_context::bifurcate): New. (region_model_context::terminate_path): New. (region_model_context::get_ext_state): New. (region_model_context::get_malloc_map): New. (noop_region_model_context::bifurcate): New. (noop_region_model_context::terminate_path): New. (noop_region_model_context::get_ext_state): New. (noop_region_model_context::get_malloc_map): New. * sm-malloc.cc: Include "analyzer/program-state.h". (malloc_state_machine::on_realloc_call): Reimplement. (malloc_state_machine::on_realloc_with_move): New. (region_model::on_realloc_with_move): New. * sm-signal.cc (class signal_delivery_edge_info_t): Update for conversion from exploded_edge::custom_info_t to custom_edge_info. * sm.h (sm_context::get_path_context): New. * svalue.cc (svalue::maybe_get_constant): Call unwrap_any_unmergeable. gcc/testsuite/ChangeLog: PR analyzer/99260 * gcc.dg/analyzer/capacity-2.c: Update for changes to realloc analysis. * gcc.dg/analyzer/pr99193-1.c: Likewise. * gcc.dg/analyzer/pr99193-3.c: Likewise. * gcc.dg/analyzer/realloc-1.c: Likewise. Add test coverage for realloc of non-heap pointer, realloc from mismatching allocator, and realloc on a freed pointer. * gcc.dg/analyzer/realloc-2.c: New test. --- gcc/testsuite/gcc.dg/analyzer/capacity-2.c | 8 +-- gcc/testsuite/gcc.dg/analyzer/pr99193-1.c | 2 + gcc/testsuite/gcc.dg/analyzer/pr99193-3.c | 2 + gcc/testsuite/gcc.dg/analyzer/realloc-1.c | 47 +++++++++++++++--- gcc/testsuite/gcc.dg/analyzer/realloc-2.c | 80 ++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/capacity-2.c b/gcc/testsuite/gcc.dg/analyzer/capacity-2.c index 9f92bcf..2db1b3f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/capacity-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/capacity-2.c @@ -8,7 +8,8 @@ void * test_realloc_1 (void *p, size_t new_sz) { void *q = realloc (p, new_sz); - __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ + __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" "failure" } */ + /* { dg-warning "capacity: 'INIT_VAL\\(new_sz\[^\n\r\]*\\)'" "success" { target *-*-* } .-1 } */ return q; } @@ -18,8 +19,9 @@ test_realloc_2 (size_t sz_a, size_t sz_b) void *p = malloc (sz_a); __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz_a_\[^\n\r\]*\\)'" } */ void *q = realloc (p, sz_b); - __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" } */ - return p; + __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(sizetype\\)'" "failure" } */ + /* { dg-warning "capacity: 'INIT_VAL\\(sz_b\[^\n\r\]*\\)'" "success" { target *-*-* } .-1 } */ + return q; /* { dg-warning "leak of 'p'" } */ } void * diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c index c6179e9..459357c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c @@ -1,3 +1,5 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + /* Verify absence of false positive from -Wanalyzer-mismatching-deallocation on realloc(3). Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/command.c#L115 diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c b/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c index 3e7ffd6..d64b045 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c @@ -1,3 +1,5 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + /* Verify absence of false positive from -Wanalyzer-mismatching-deallocation on realloc(3). Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/debug.c#L115 diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c index a6c6bfc..606a19a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c @@ -1,3 +1,5 @@ +/* { dg-additional-options "-Wno-free-nonheap-object" } */ + typedef __SIZE_TYPE__ size_t; #define NULL ((void *)0) @@ -20,11 +22,10 @@ void *test_1 (void *ptr) void *test_2 (void *ptr) { - void *p = malloc (1024); - p = realloc (p, 4096); - /* TODO: should warn about the leak when the above call fails (PR analyzer/99260). */ + void *p = malloc (1024); /* { dg-message "allocated here" } */ + p = realloc (p, 4096); /* { dg-message "when 'realloc' fails" } */ free (p); -} +} /* { dg-warning "leak of 'p'" } */ // ideally this would be on the realloc stmt void *test_3 (void *ptr) { @@ -44,8 +45,8 @@ void *test_4 (void) int *test_5 (int *p) { *p = 42; - int *q = realloc (p, sizeof(int) * 4); - *q = 43; /* { dg-warning "possibly-NULL 'q'" "PR analyzer/99260" { xfail *-*-* } } */ + int *q = realloc (p, sizeof(int) * 4); /* { dg-message "when 'realloc' fails" } */ + *q = 43; /* { dg-warning "dereference of NULL 'q'" } */ return q; } @@ -53,3 +54,37 @@ void test_6 (size_t sz) { void *p = realloc (NULL, sz); } /* { dg-warning "leak of 'p'" } */ + +/* The analyzer should complain about realloc of non-heap. */ + +void *test_7 (size_t sz) +{ + char buf[100]; + void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '&buf' which points to memory not on the heap" } */ + return p; +} + +/* Mismatched allocator. */ + +struct foo +{ + int m_int; +}; + +extern void foo_release (struct foo *); +extern struct foo *foo_acquire (void) + __attribute__ ((malloc (foo_release))); + +void test_8 (void) +{ + struct foo *p = foo_acquire (); + void *q = realloc (p, 1024); /* { dg-warning "'p' should have been deallocated with 'foo_release' but was deallocated with 'realloc'" } */ +} + +/* We should complain about realloc on a freed pointer. */ + +void test_9 (void *p) +{ + free (p); + void *q = realloc (p, 1024); /* { dg-warning "double-'free' of 'p'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-2.c b/gcc/testsuite/gcc.dg/analyzer/realloc-2.c new file mode 100644 index 0000000..a397753 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-2.c @@ -0,0 +1,80 @@ +#include "analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + +#define NULL ((void *)0) + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +char *test_8 (size_t sz) +{ + char *p, *q; + + p = malloc (3); + if (!p) + return NULL; + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)3'" } */ + + p[0] = 'a'; + p[1] = 'b'; + p[2] = 'c'; + + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + + q = realloc (p, 6); + + /* We should have 3 nodes, corresponding to "failure", + "success without moving", and "success with moving". */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ + + if (q) + { + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(size_t\\)6'" } */ + q[3] = 'd'; + q[4] = 'e'; + q[5] = 'f'; + if (q == p) + { + /* "realloc" success, growing the buffer in-place. */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + // TODO + } + else + { + /* "realloc" success, moving the buffer (and thus freeing "p"). */ + __analyzer_eval (q[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[2] == 'c'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ + } + __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ + } + else + { + /* "realloc" failure. p should be unchanged. */ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)3'" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + return p; + } + + return q; +} -- cgit v1.1 From aba800615e1af875b75f7774de67778c1b3315ad Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Tue, 31 Aug 2021 05:36:47 +0000 Subject: Fix gcc.dg/ipa/inline-8.c for -fPIC The problem here is with -fPIC, both cmp and move don't bind locally so they are not even tried to be inlined. This fixes the issue by marking both functions as static and now the testcase passes for both -fPIC and -fno-PIC cases. OK? Tested on x86_64-linux-gnu. gcc/testsuite/ChangeLog: * gcc.dg/ipa/inline-8.c: Mark cmp and move as static so they both bind local and available for inlinine. --- gcc/testsuite/gcc.dg/ipa/inline-8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/ipa/inline-8.c b/gcc/testsuite/gcc.dg/ipa/inline-8.c index 388283c..c51eec2 100644 --- a/gcc/testsuite/gcc.dg/ipa/inline-8.c +++ b/gcc/testsuite/gcc.dg/ipa/inline-8.c @@ -6,13 +6,13 @@ #include extern int isnanf (float); /* Can't be inlined because isnanf will be optimized out. */ -int +static int cmp (float a) { return isnanf (a); } /* Can be inlined. */ -int +static int move (int a) { return a; -- cgit v1.1 From eca730231d5493647bb1e508fb1f853ffee0e95a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 31 Aug 2021 15:26:14 +0200 Subject: testsuite: Fix gcc.dg/vect/pr101145* tests [PR101145] I'm getting: FAIL: gcc.dg/vect/pr101145.c scan-tree-dump-times vect "vectorized 1 loops" 7 FAIL: gcc.dg/vect/pr101145_1.c scan-tree-dump-times vect "vectorized 1 loops" 2 FAIL: gcc.dg/vect/pr101145_2.c scan-tree-dump-times vect "vectorized 1 loops" 2 FAIL: gcc.dg/vect/pr101145_3.c scan-tree-dump-times vect "vectorized 1 loops" 2 FAIL: gcc.dg/vect/pr101145.c -flto -ffat-lto-objects scan-tree-dump-times vect "vectorized 1 loops" 7 FAIL: gcc.dg/vect/pr101145_1.c -flto -ffat-lto-objects scan-tree-dump-times vect "vectorized 1 loops" 2 FAIL: gcc.dg/vect/pr101145_2.c -flto -ffat-lto-objects scan-tree-dump-times vect "vectorized 1 loops" 2 FAIL: gcc.dg/vect/pr101145_3.c -flto -ffat-lto-objects scan-tree-dump-times vect "vectorized 1 loops" 2 on i686-linux (or x86_64-linux with -m32/-mno-sse). The problem is that those tests use dg-options, which in */vect/ testsuite throws away all the carefully added default options to enable vectorization on each target (and which e.g. vect_int etc. effective targets rely on). The old way would be to name those tests gcc.dg/vect/O3-pr101145*, but we can also use dg-additional-options (which doesn't throw the default options, just appends to them) which is IMO better so that we don't have to rename the tests. 2021-08-31 Jakub Jelinek PR tree-optimization/101145 * gcc.dg/vect/pr101145.c: Use dg-additional-options with just -O3 instead of dg-options with -O3 -fdump-tree-vect-details. * gcc.dg/vect/pr101145_1.c: Likewise. * gcc.dg/vect/pr101145_2.c: Likewise. * gcc.dg/vect/pr101145_3.c: Likewise. --- gcc/testsuite/gcc.dg/vect/pr101145.c | 2 +- gcc/testsuite/gcc.dg/vect/pr101145_1.c | 2 +- gcc/testsuite/gcc.dg/vect/pr101145_2.c | 2 +- gcc/testsuite/gcc.dg/vect/pr101145_3.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.c b/gcc/testsuite/gcc.dg/vect/pr101145.c index 74031b0..cd11c03 100644 --- a/gcc/testsuite/gcc.dg/vect/pr101145.c +++ b/gcc/testsuite/gcc.dg/vect/pr101145.c @@ -1,5 +1,5 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-options "-O3 -fdump-tree-vect-details" } */ +/* { dg-additional-options "-O3" } */ #include unsigned __attribute__ ((noinline)) diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_1.c b/gcc/testsuite/gcc.dg/vect/pr101145_1.c index 8bc26e2..9332b2c 100644 --- a/gcc/testsuite/gcc.dg/vect/pr101145_1.c +++ b/gcc/testsuite/gcc.dg/vect/pr101145_1.c @@ -1,5 +1,5 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-options "-O3 -fdump-tree-vect-details" } */ +/* { dg-additional-options "-O3" } */ #define TYPE signed char #define MIN -128 #define MAX 127 diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_2.c b/gcc/testsuite/gcc.dg/vect/pr101145_2.c index b14c4b4..fa2c6be 100644 --- a/gcc/testsuite/gcc.dg/vect/pr101145_2.c +++ b/gcc/testsuite/gcc.dg/vect/pr101145_2.c @@ -1,5 +1,5 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-options "-O3 -fdump-tree-vect-details" } */ +/* { dg-additional-options "-O3" } */ #define TYPE unsigned char #define MIN 0 #define MAX 255 diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_3.c b/gcc/testsuite/gcc.dg/vect/pr101145_3.c index 99289af..9f43c82 100644 --- a/gcc/testsuite/gcc.dg/vect/pr101145_3.c +++ b/gcc/testsuite/gcc.dg/vect/pr101145_3.c @@ -1,5 +1,5 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-options "-O3 -fdump-tree-vect-details" } */ +/* { dg-additional-options "-O3" } */ #define TYPE int * #define MIN ((TYPE)0) #define MAX ((TYPE)((long long)-1)) -- cgit v1.1 From 823685221de986afb729910a6f2237f07a377f17 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 1 Sep 2021 08:38:39 +0100 Subject: C: PR c/79412: Poison decls with error_mark_node after type mismatch This patch fixes an ICE during error-recovery regression in the C front-end. The symptom is that the middle-end's sanity checking assertions fail during gimplification when being asked to increment an array, which is non-sense. The issue is that the C-front end has detected the type mismatch and reported an error to the user, but hasn't provided any indication of this to the middle-end, simply passing bogus trees that the optimizers recognize as invalid. This appears to be a frequently reported ICE with 94730, 94731, 101036 and 101365 all marked as duplicates. I believe the correct (polite) fix is to mark the mismatched types as problematic/dubious in the front-end, when the error is spotted, so that the middle-end has a heads-up and can be a little more forgiving. This patch to c-decl.c's duplicate_decls sets (both) mismatched types to error_mark_node if they are significantly different, and we've issued an error message. Alas, this is too punitive for FUNCTION_DECLs where we store return types, parameter lists, parameter types and attributes in the type, but fortunately the middle-end is already more cautious about trusting possibly suspect function types. This fix required one minor change to the testsuite, typedef-var-2.c where after conflicting type definitions, we now no longer assume that the (first or) second definition is the correct one. This change only affects the behaviour after seen_error(), so should be relatively safe. 2021-09-01 Roger Sayle Joseph Myers gcc/c/ChangeLog PR c/79412 * c-decl.c (duplicate_decls): On significant mismatches, mark the types of both (non-function) decls as error_mark_node, so that the middle-end can see the code is malformed. (free_attr_access_data): Don't process if the type has been set to error_mark_node. gcc/testsuite/ChangeLog PR c/79412 * gcc.dg/pr79412.c: New test case. * gcc.dg/typedef-var-2.c: Update expeted errors. --- gcc/testsuite/gcc.dg/pr79412.c | 9 +++++++++ gcc/testsuite/gcc.dg/typedef-var-2.c | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr79412.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr79412.c b/gcc/testsuite/gcc.dg/pr79412.c new file mode 100644 index 0000000..b60d5e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr79412.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +int a; +/* { dg-message "note: previous declaration" "previous declaration" { target *-*-* } .-1 } */ +void fn1 () +{ + a++; +} +int a[] = {2}; /* { dg-error "conflicting types" } */ diff --git a/gcc/testsuite/gcc.dg/typedef-var-2.c b/gcc/testsuite/gcc.dg/typedef-var-2.c index 716d29c..bc119a0 100644 --- a/gcc/testsuite/gcc.dg/typedef-var-2.c +++ b/gcc/testsuite/gcc.dg/typedef-var-2.c @@ -4,12 +4,13 @@ int f (void) { extern float v; - +/* { dg-message "note: previous declaration" "previous declaration" { target *-*-* } .-1 } */ return (v > 0.0f); } extern int t; +/* { dg-message "note: previous declaration" "previous declaration" { target *-*-* } .-1 } */ typedef float t; /* { dg-error "redeclared as different kind of symbol" } */ -t v = 4.5f; +t v = 4.5f; /* { dg-error "conflicting types" } */ -- cgit v1.1 From e6bd9c42b0ad0cc4a615135612599adb829f2d9c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 1 Sep 2021 08:06:48 +0200 Subject: tree-optimization/102149 - add testcase for fixed bug This adds the testcase from the PR. 2021-09-01 Richard Biener PR tree-optimization/102149 * gcc.dg/torture/pr102149.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr102149.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr102149.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr102149.c b/gcc/testsuite/gcc.dg/torture/pr102149.c new file mode 100644 index 0000000..34a8c21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr102149.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-vect-cost-model" } */ + +int a[8]; +int *b = &a[6]; +char c; +int main() +{ + int d = 7; + for (; d >= 0; d--) + { + *b = 1; + c = a[d] >> 3; + a[d] = c; + } + if (a[6] != 1) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 45ff12512e568089a4c7b85b5322ab8019723cd9 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 1 Sep 2021 12:06:25 +0200 Subject: bswap: Fix up bswap_view_convert handling [PR102141] bswap_view_convert is used twice in spots where gsi_insert_before is the right thing, but in the last one it wants to insert preparation stmts for the VIEW_CONVERT_EXPR emitted with gsi_insert_after, where at the gsi we still need to insert bswap_stmt and maybe mask_stmt whose lhs the preparation stmts will use. So, this patch adds a BEFORE argument to the function and emits the preparation statements before or after depending on that. 2021-09-01 Jakub Jelinek PR tree-optimization/102141 * gimple-ssa-store-merging.c (bswap_view_convert): Add BEFORE argument. If false, emit stmts after gsi instead of before, and with GSI_NEW_STMT. (bswap_replace): Adjust callers. When converting output of bswap, emit VIEW_CONVERT prepratation stmts after a copy of gsi instead of before it. * gcc.dg/pr102141.c: New test. --- gcc/testsuite/gcc.dg/pr102141.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr102141.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr102141.c b/gcc/testsuite/gcc.dg/pr102141.c new file mode 100644 index 0000000..f3fc8d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102141.c @@ -0,0 +1,11 @@ +/* PR tree-optimization/102141 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +unsigned int __attribute__((__vector_size__ (4))) v; + +void +foo (unsigned long long x) +{ + v &= (unsigned) (x >> 56 | x >> 40 & 0xff00); +} -- cgit v1.1 From 153766ec8351d55cfe8bd6d69bdfc0c2cef71e56 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 31 Aug 2021 10:28:40 +0200 Subject: tree-optimization/102139 - fix SLP DR base alignment When doing whole-function SLP we have to make sure the recorded base alignments we compute as the maximum alignment seen for a base anywhere in the function is actually valid at the point we want to make use of it. To make this work we now record the stmt the alignment was derived from in addition to the DRs innermost behavior and we use a dominance check to verify the recorded info is valid when doing BB vectorization. For this to work for groups inside a BB that are separate by a call that might not return we now store the DR analysis group-id permanently and use that for an additional check when the DRs are in the same BB. 2021-08-31 Richard Biener PR tree-optimization/102139 * tree-vectorizer.h (vec_base_alignments): Adjust hash-map type to record a std::pair of the stmt-info and the innermost loop behavior. (dr_vec_info::group): New member. * tree-vect-data-refs.c (vect_record_base_alignment): Adjust. (vect_compute_data_ref_alignment): Verify the recorded base alignment can be used. (data_ref_pair): Remove. (dr_group_sort_cmp): Adjust. (vect_analyze_data_ref_accesses): Store the group-ID in the dr_vec_info and operate on a vector of dr_vec_infos. * gcc.dg/torture/pr102139.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr102139.c | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr102139.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr102139.c b/gcc/testsuite/gcc.dg/torture/pr102139.c new file mode 100644 index 0000000..06c1357 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr102139.c @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-slp-vectorize" } */ + +typedef double aligned_double __attribute__((aligned(2*sizeof(double)))); + +void __attribute__((noipa)) +bar (int aligned, double *p) +{ + if (aligned) + { + *(aligned_double *)p = 3.; + p[1] = 4.; + } + else + { + p[2] = 0.; + p[3] = 1.; + } +} + +void __attribute__((noipa)) +foo (int i) +{ + if (i) + __builtin_exit (0); +} +void __attribute__((noipa)) +baz (double *p) +{ + p[0] = 0.; + p[1] = 1.; + foo (1); + *(aligned_double *)p = 3.; + p[1] = 4.; +} + +double x[8] __attribute__((aligned(2*sizeof (double)))); +int main() +{ + bar (0, &x[1]); + baz (&x[1]); + return 0; +} -- cgit v1.1 From 13a43a90aea368a25da50762eba4873bafb4e448 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 1 Sep 2021 11:49:39 +0200 Subject: tree-optimization/93491 - avoid PRE of trapping calls across exits This makes us avoid PREing calls that could trap across other calls that might not return. The PR88087 testcase has exactly such case so I've refactored the testcase to contain a valid PRE. I've also adjusted PRE to not consider pure calls possibly not returning in line with what we do elsewhere. Note we don't have a good idea whether a function always returns normally or whether its body is known to never trap. That's something IPA could compute. 2021-09-01 Richard Biener PR tree-optimization/93491 * tree-ssa-pre.c (compute_avail): Set BB_MAY_NOTRETURN after processing the stmt itself. Do not consider pure functions possibly not returning. Properly avoid adding possibly trapping calls to EXP_GEN when there's a preceeding possibly not returning call. * tree-ssa-sccvn.c (vn_reference_may_trap): Conservatively not handle calls. * gcc.dg/torture/pr93491.c: New testcase. * gcc.dg/tree-ssa/pr88087.c: Change to valid PRE opportunity. --- gcc/testsuite/gcc.dg/torture/pr93491.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr88087.c | 18 +++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr93491.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr93491.c b/gcc/testsuite/gcc.dg/torture/pr93491.c new file mode 100644 index 0000000..2cb4c0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr93491.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ + +extern void exit (int); + +__attribute__((noipa)) +void f(int i) +{ + exit(i); +} + +__attribute__((const,noipa)) +int g(int i) +{ + return 1 / i; +} + +int main() +{ + while (1) + { + f(0); + f(g(0)); + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c index d0061b6..c48dba5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c @@ -1,17 +1,17 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fno-code-hoisting -fdump-tree-pre-stats" } */ int f(); int d; -void c() +void c(int x) { - for (;;) - { - f(); - int (*fp)() __attribute__((const)) = (void *)f; - d = fp(); - } + int (*fp)() __attribute__((const)) = (void *)f; + if (x) + d = fp (); + int tem = fp (); + f(); + d = tem; } -/* We shouldn't ICE and hoist the const call of fp out of the loop. */ +/* We shouldn't ICE and PRE the const call. */ /* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */ -- cgit v1.1 From bea07159d1d4c9a61c8f7097e9f88c2b206b1b2f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 1 Sep 2021 13:30:51 +0200 Subject: vectorizer: Fix up vectorization using WIDEN_MINUS_EXPR [PR102124] The following testcase is miscompiled on aarch64-linux at -O3 since the introduction of WIDEN_MINUS_EXPR. The problem is if the inner type (half_type) is unsigned and the result type in which the subtraction is performed (type) has precision more than twice as larger as the inner type's precision. For other widening operations like WIDEN_{PLUS,MULT}_EXPR, if half_type is unsigned, the addition/multiplication result in itype is also unsigned and needs to be zero-extended to type. But subtraction is special, even when half_type is unsigned, the subtraction behaves as signed (also regardless of whether the result type is signed or unsigned), 0xfeU - 0xffU is -1 or 0xffffffffU, not 0x0000ffff. I think it is better not to use mixed signedness of types in WIDEN_MINUS_EXPR (have unsigned vector of operands and signed result vector), so this patch instead adds another cast to make sure we always sign-extend the result from itype to type if type is wider than itype. 2021-09-01 Jakub Jelinek PR tree-optimization/102124 * tree-vect-patterns.c (vect_recog_widen_op_pattern): For ORIG_CODE MINUS_EXPR, if itype is unsigned with smaller precision than type, add an extra cast to signed variant of itype to ensure sign-extension. * gcc.dg/torture/pr102124.c: New test. --- gcc/testsuite/gcc.dg/torture/pr102124.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr102124.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/torture/pr102124.c b/gcc/testsuite/gcc.dg/torture/pr102124.c new file mode 100644 index 0000000..a158b4a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr102124.c @@ -0,0 +1,27 @@ +/* PR tree-optimization/102124 */ + +int +foo (const unsigned char *a, const unsigned char *b, unsigned long len) +{ + int ab, ba; + unsigned long i; + for (i = 0, ab = 0, ba = 0; i < len; i++) + { + ab |= a[i] - b[i]; + ba |= b[i] - a[i]; + } + return (ab | ba) >= 0; +} + +int +main () +{ + unsigned char a[32] = { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }; + unsigned char b[32] = { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }; + unsigned char c[32] = { 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b' }; + if (!foo (a, b, 16)) + __builtin_abort (); + if (foo (a, c, 16)) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 8433baadec88e5f31fa141b6d78094e91256079d Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 8 Nov 2020 09:04:07 +0000 Subject: C-family: Add attribute 'unavailable'. If an interface is marked 'deprecated' then, presumably, at some point it will be withdrawn and no longer available. The 'unavailable' attribute makes it possible to mark up interfaces to indicate this status. It is used quite extensively in some codebases where a single set of headers can be used to permit code generation for multiple system versions. From a configuration perspective, it also allows a compile test to determine that an interface is missing - rather than requiring a link test. The implementation follows the pattern of attribute deprecated, but produces an error (where deprecation produces a warning). This attribute has been implemented in clang for some years. Signed-off-by: Iain Sandoe gcc/c-family/ChangeLog: * c-attribs.c (handle_unavailable_attribute): New. gcc/c/ChangeLog: * c-decl.c (enum deprecated_states): Add unavailable state. (merge_decls): Copy unavailability. (quals_from_declspecs): Handle unavailable case. (start_decl): Amend the logic handling suppression of nested deprecation states to include unavailability. (smallest_type_quals_location): Amend comment. (grokdeclarator): Handle the unavailable deprecation state. (declspecs_add_type): Set TREE_UNAVAILABLE from the decl specs. * c-tree.h (struct c_declspecs): Add unavailable_p. * c-typeck.c (build_component_ref): Handle unavailability. (build_external_ref): Likewise. gcc/cp/ChangeLog: * call.c (build_over_call): Handle unavailable state in addition to deprecation. * class.c (type_build_ctor_call): Likewise. (type_build_dtor_call): Likewise. * cp-tree.h: Rename cp_warn_deprecated_use to cp_handle_deprecated_or_unavailable. * decl.c (duplicate_decls): Merge unavailability. (grokdeclarator): Handle unavailability in addition to deprecation. (type_is_unavailable): New. (grokparms): Handle unavailability in addition to deprecation. * decl.h (enum deprecated_states): Add UNAVAILABLE_DEPRECATED_SUPPRESS. * decl2.c (cplus_decl_attributes): Propagate unavailability to templates. (cp_warn_deprecated_use): Rename to ... (cp_handle_deprecated_or_unavailable): ... this and amend to handle the unavailable case. It remains a warning in the case of deprecation but becomes an error in the case of unavailability. (cp_warn_deprecated_use_scopes): Handle unavailability. (mark_used): Likewise. * parser.c (cp_parser_template_name): Likewise. (cp_parser_template_argument): Likewise. (cp_parser_parameter_declaration_list): Likewise. * typeck.c (build_class_member_access_expr): Likewise. (finish_class_member_access_expr): Likewise. * typeck2.c (build_functional_cast_1): Likewise. gcc/ChangeLog: * doc/extend.texi: Document unavailable attribute. * print-tree.c (print_node): Handle unavailable attribute. * tree-core.h (struct tree_base): Add a bit to carry unavailability. * tree.c (error_unavailable_use): New. * tree.h (TREE_UNAVAILABLE): New. (error_unavailable_use): New. gcc/objc/ChangeLog: * objc-act.c (objc_add_property_declaration): Register unavailable attribute. (maybe_make_artificial_property_decl): Set available. (objc_maybe_build_component_ref): Generalise to the method prototype to count availability. (objc_build_class_component_ref): Likewise. (build_private_template): Likewise. (objc_decl_method_attributes): Handle unavailable attribute. (lookup_method_in_hash_lists): Amend comments. (objc_finish_message_expr): Handle unavailability in addition to deprecation. (start_class): Likewise. (finish_class): Likewise. (lookup_protocol): Likewise. (objc_declare_protocol): Likewise. (start_protocol): Register unavailable attribute. (really_start_method): Likewise. (objc_gimplify_property_ref): Emit error on encountering an unavailable entity (and a warning for a deprecated one). gcc/testsuite/ChangeLog: * g++.dg/ext/attr-unavailable-1.C: New test. * g++.dg/ext/attr-unavailable-2.C: New test. * g++.dg/ext/attr-unavailable-3.C: New test. * g++.dg/ext/attr-unavailable-4.C: New test. * g++.dg/ext/attr-unavailable-5.C: New test. * g++.dg/ext/attr-unavailable-6.C: New test. * g++.dg/ext/attr-unavailable-7.C: New test. * g++.dg/ext/attr-unavailable-8.C: New test. * g++.dg/ext/attr-unavailable-9.C: New test. * gcc.dg/attr-unavailable-1.c: New test. * gcc.dg/attr-unavailable-2.c: New test. * gcc.dg/attr-unavailable-3.c: New test. * gcc.dg/attr-unavailable-4.c: New test. * gcc.dg/attr-unavailable-5.c: New test. * gcc.dg/attr-unavailable-6.c: New test. * obj-c++.dg/attributes/method-unavailable-1.mm: New test. * obj-c++.dg/attributes/method-unavailable-2.mm: New test. * obj-c++.dg/attributes/method-unavailable-3.mm: New test. * obj-c++.dg/property/at-property-unavailable-1.mm: New test. * obj-c++.dg/property/at-property-unavailable-2.mm: New test. * obj-c++.dg/property/dotsyntax-unavailable-1.mm: New test. * objc.dg/attributes/method-unavailable-1.m: New test. * objc.dg/attributes/method-unavailable-2.m: New test. * objc.dg/attributes/method-unavailable-3.m: New test. * objc.dg/property/at-property-unavailable-1.m: New test. * objc.dg/property/at-property-unavailable-2.m: New test. * objc.dg/property/dotsyntax-unavailable-1.m: New test. --- gcc/testsuite/gcc.dg/attr-unavailable-1.c | 88 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/attr-unavailable-2.c | 6 +++ gcc/testsuite/gcc.dg/attr-unavailable-3.c | 10 ++++ gcc/testsuite/gcc.dg/attr-unavailable-4.c | 88 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/attr-unavailable-5.c | 6 +++ gcc/testsuite/gcc.dg/attr-unavailable-6.c | 11 ++++ 6 files changed, 209 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/attr-unavailable-1.c create mode 100644 gcc/testsuite/gcc.dg/attr-unavailable-2.c create mode 100644 gcc/testsuite/gcc.dg/attr-unavailable-3.c create mode 100644 gcc/testsuite/gcc.dg/attr-unavailable-4.c create mode 100644 gcc/testsuite/gcc.dg/attr-unavailable-5.c create mode 100644 gcc/testsuite/gcc.dg/attr-unavailable-6.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/attr-unavailable-1.c b/gcc/testsuite/gcc.dg/attr-unavailable-1.c new file mode 100644 index 0000000..768214f --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-unavailable-1.c @@ -0,0 +1,88 @@ +/* Test __attribute__ ((unavailable)) */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef int INT1 __attribute__((unavailable)); +typedef INT1 INT2 __attribute__ ((__unavailable__)); + +typedef INT1 INT1a; /* { dg-error "'INT1' is unavailable" "" } */ +typedef INT1 INT1b __attribute__ ((unavailable)); + +INT1 should_be_unavailable; /* { dg-error "'INT1' is unavailable" "" } */ +INT1a should_not_be_unavailable; + +INT1 f1(void) __attribute__ ((unavailable)); +INT1 f2(void) { return 0; } /* { dg-error "'INT1' is unavailable" "" } */ + +INT2 f3(void) __attribute__ ((__unavailable__)); +INT2 f4(void) { return 0; } /* { dg-error "'INT2' is unavailable" "" } */ +int f5(INT2 x); /* { dg-error "'INT2' is unavailable" "" } */ +int f6(INT2 x) __attribute__ ((__unavailable__)); /* { dg-error "'INT2' is unavailable" "" } */ + +typedef enum {red, green, blue} Color __attribute__((unavailable)); + +int g1; +int g2 __attribute__ ((unavailable)); +int g3 __attribute__ ((__unavailable__)); +Color k; /* { dg-error "'Color' is unavailable" "" } */ + +typedef struct { + int field1; + int field2 __attribute__ ((unavailable)); + int field3; + int field4 __attribute__ ((__unavailable__)); + union { + int field5; + int field6 __attribute__ ((unavailable)); + } u1; + int field7:1; + int field8:1 __attribute__ ((unavailable)); + union { + int field9; + int field10; + } u2 __attribute__ ((unavailable)); +} S1; + +int func1() +{ + INT1 w; /* { dg-error "'INT1' is unavailable" "" } */ + int x __attribute__ ((unavailable)); + int y __attribute__ ((__unavailable__)); + int z; + int (*pf)() = f1; /* { dg-error "'f1' is unavailable" "" } */ + + z = w + x + y + g1 + g2 + g3; /* { dg-error "'x' is unavailable" "" } */ + /* { dg-error "'y' is unavailable" "y" { target *-*-* } .-1 } */ + /* { dg-error "'g2' is unavailable" "g2" { target *-*-* } .-2 } */ + /* { dg-error "'g3' is unavailable" "g3" { target *-*-* } .-3 } */ + return f1(); /* { dg-error "'f1' is unavailable" "f1" } */ +} + +int func2(S1 *p) +{ + S1 lp; + + if (p->field1) + return p->field2; /* { dg-error "'field2' is unavailable" "" } */ + else if (lp.field4) /* { dg-error "'field4' is unavailable" "" } */ + return p->field3; + + p->u1.field5 = g1 + p->field7; + p->u2.field9; /* { dg-error "'u2' is unavailable" "" } */ + return p->u1.field6 + p->field8; /* { dg-error "'field6' is unavailable" "" } */ + /* { dg-error "'field8' is unavailable" "field8" { target *-*-* } .-1 } */ +} + +struct SS1 { + int x; + INT1 y; /* { dg-error "'INT1' is unavailable" "" } */ +} __attribute__ ((unavailable)); + +struct SS1 *p1; /* { dg-error "'SS1' is unavailable" "" } */ + +struct __attribute__ ((__unavailable__)) SS2 { + int x; + INT1 y; /* { dg-error "'INT1' is unavailable" "" } */ +}; + +struct SS2 *p2; /* { dg-error "'SS2' is unavailable" "" } */ diff --git a/gcc/testsuite/gcc.dg/attr-unavailable-2.c b/gcc/testsuite/gcc.dg/attr-unavailable-2.c new file mode 100644 index 0000000..303f973 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-unavailable-2.c @@ -0,0 +1,6 @@ +/* Test __attribute__((unavailable)). Test types without names. */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct { int a; } __attribute__((unavailable)) x; /* { dg-error "type is unavailable" } */ +typeof(x) y; /* { dg-error "type is unavailable" } */ diff --git a/gcc/testsuite/gcc.dg/attr-unavailable-3.c b/gcc/testsuite/gcc.dg/attr-unavailable-3.c new file mode 100644 index 0000000..7274c19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-unavailable-3.c @@ -0,0 +1,10 @@ +/* Test __attribute__((unavailable)). */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void func(void); +void func(void) __attribute__((unavailable)); + +void f(void) { + func(); /* { dg-error "'func' is unavailable" } */ +} diff --git a/gcc/testsuite/gcc.dg/attr-unavailable-4.c b/gcc/testsuite/gcc.dg/attr-unavailable-4.c new file mode 100644 index 0000000..9e39c50 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-unavailable-4.c @@ -0,0 +1,88 @@ +/* Test __attribute__ ((unavailable("message"))) */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef int INT1 __attribute__((unavailable("You can't use INT1"))); +typedef INT1 INT2 __attribute__ ((__unavailable__("You can't use INT2"))); + +typedef INT1 INT1a; /* { dg-error "'INT1' is unavailable: You can't use INT1" "" } */ +typedef INT1 INT1b __attribute__ ((unavailable("You can't use INT1b"))); + +INT1 should_be_unavailable; /* { dg-error "'INT1' is unavailable: You can't use INT1" "" } */ +INT1a should_not_be_unavailable; + +INT1 f1(void) __attribute__ ((unavailable("You can't use f1"))); +INT1 f2(void) { return 0; } /* { dg-error "'INT1' is unavailable: You can't use INT1" "" } */ + +INT2 f3(void) __attribute__ ((__unavailable__("You can't use f3"))); +INT2 f4(void) { return 0; } /* { dg-error "'INT2' is unavailable: You can't use INT2" "" } */ +int f5(INT2 x); /* { dg-error "'INT2' is unavailable: You can't use INT2" "" } */ +int f6(INT2 x) __attribute__ ((__unavailable__("You can't use f6"))); /* { dg-error "'INT2' is unavailable: You can't use INT2" "" } */ + +typedef enum {red, green, blue} Color __attribute__((unavailable("You can't use Color"))); + +int g1; +int g2 __attribute__ ((unavailable("You can't use g2"))); +int g3 __attribute__ ((__unavailable__("You can't use g3"))); +Color k; /* { dg-error "'Color' is unavailable: You can't use Color" "" } */ + +typedef struct { + int field1; + int field2 __attribute__ ((unavailable("You can't use field2"))); + int field3; + int field4 __attribute__ ((__unavailable__("You can't use field4"))); + union { + int field5; + int field6 __attribute__ ((unavailable("You can't use field6"))); + } u1; + int field7:1; + int field8:1 __attribute__ ((unavailable("You can't use field8"))); + union { + int field9; + int field10; + } u2 __attribute__ ((unavailable("You can't use u2"))); +} S1; + +int func1() +{ + INT1 w; /* { dg-error "'INT1' is unavailable: You can't use INT1" "" } */ + int x __attribute__ ((unavailable("Avoid x"))); + int y __attribute__ ((__unavailable__("Bad y"))); + int z; + int (*pf)() = f1; /* { dg-error "'f1' is unavailable: You can't use f1" "" } */ + + z = w + x + y + g1 + g2 + g3; /* { dg-error "'x' is unavailable: Avoid x" "" } */ + /* { dg-error "'y' is unavailable: Bad y" "y" { target *-*-* } .-1 } */ + /* { dg-error "'g2' is unavailable: You can't use g2" "g2" { target *-*-* } .-2 } */ + /* { dg-error "'g3' is unavailable: You can't use g3" "g3" { target *-*-* } .-3 } */ + return f1(); /* { dg-error "'f1' is unavailable: You can't use f1" "" } */ +} + +int func2(S1 *p) +{ + S1 lp; + + if (p->field1) + return p->field2; /* { dg-error "'field2' is unavailable: You can't use field2" "" } */ + else if (lp.field4) /* { dg-error "'field4' is unavailable: You can't use field4" "" } */ + return p->field3; + + p->u1.field5 = g1 + p->field7; + p->u2.field9; /* { dg-error "'u2' is unavailable: You can't use u2" "" } */ + return p->u1.field6 + p->field8; /* { dg-error "'field6' is unavailable: You can't use field6" "" } */ + /* { dg-error "'field8' is unavailable: You can't use field8" "field8" { target *-*-* } .-1 } */ +} + +struct SS1 { + int x; + INT1 y; /* { dg-error "'INT1' is unavailable: You can't use INT1" "" } */ +} __attribute__ ((unavailable("You can't use SS1"))); + +struct SS1 *p1; /* { dg-error "'SS1' is unavailable: You can't use SS1" "" } */ + +struct __attribute__ ((__unavailable__("You can't use SS2"))) SS2 { + int x; + INT1 y; /* { dg-error "'INT1' is unavailable: You can't use INT1" "" } */ +}; + +struct SS2 *p2; /* { dg-error "'SS2' is unavailable: You can't use SS2" "" } */ diff --git a/gcc/testsuite/gcc.dg/attr-unavailable-5.c b/gcc/testsuite/gcc.dg/attr-unavailable-5.c new file mode 100644 index 0000000..051f960 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-unavailable-5.c @@ -0,0 +1,6 @@ +/* Test __attribute__((unavailable)). Test types without names. */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct { int a; } __attribute__((unavailable ("Do not use"))) x; /* { dg-error "type is unavailable" } */ +typeof(x) y; /* { dg-error "type is unavailable: Do not use" } */ diff --git a/gcc/testsuite/gcc.dg/attr-unavailable-6.c b/gcc/testsuite/gcc.dg/attr-unavailable-6.c new file mode 100644 index 0000000..f5f4560 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-unavailable-6.c @@ -0,0 +1,11 @@ +/* Test __attribute__((unavailable)). Test merging with multiple + declarations. */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void func(void); +void func(void) __attribute__((unavailable ("Do not use"))); + +void f(void) { + func(); /* { dg-error "'func' is unavailable: Do not use" } */ +} -- cgit v1.1 From ece28da924ddda8b379c94c9df7cd01168f75fbb Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 1 Sep 2021 13:46:19 -0600 Subject: Enable ranger and caching in pass_waccess. gcc/ChangeLog: * gimple-ssa-warn-access.cc (get_size_range): Add argument. (check_access): Pass additional argument. (check_memop_access): Remove template and make a member function. (maybe_check_dealloc_call): Make a pass_waccess member function. (class pass_waccess): Add, rename, and remove members. (pass_waccess::pass_waccess): Adjust to name change. (pass_waccess::~pass_waccess): Same. (check_alloca): Make a member function. (check_alloc_size_call): Same. (check_strcat): Same. (check_strncat): Same. (check_stxcpy): Same. (check_stxncpy): Same. (check_strncmp): Same. (maybe_warn_rdwr_sizes): Rename... (pass_waccess::maybe_check_access_sizes): ...to this. (pass_waccess::check_call): Adjust to name changes. (pass_waccess::maybe_check_dealloc_call): Make a pass_waccess member function. (pass_waccess::execute): Adjust to name changes. * gimple-ssa-warn-access.h (check_memop_access): Remove. * pointer-query.cc (access_ref::phi): Handle null pointer. (access_ref::inform_access): Same. (pointer_query::put_ref): Modify a cached value, not a copy of it. (pointer_query::dump): New function. (compute_objsize_r): Avoid overwriting access_ref::bndrng. Cache more results. * pointer-query.h (pointer_query::dump): Declare. * tree-ssa-strlen.c (get_range): Simplify. Use function query. (dump_strlen_info): Use function query. (printf_strlen_execute): Factor code out into pointer_query::put_ref. gcc/testsuite/ChangeLog: * gcc.dg/Wstringop-overflow-11.c: Remove xfails. * gcc.dg/Wstringop-overflow-12.c: Same. * gcc.dg/Wstringop-overflow-43.c: Add xfails. * gcc.dg/Wstringop-overflow-73.c: New test. --- gcc/testsuite/gcc.dg/Wstringop-overflow-11.c | 8 +++---- gcc/testsuite/gcc.dg/Wstringop-overflow-12.c | 6 ++--- gcc/testsuite/gcc.dg/Wstringop-overflow-43.c | 9 ++++--- gcc/testsuite/gcc.dg/Wstringop-overflow-73.c | 35 ++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-73.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c index ec3c97e..cf53652 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c @@ -56,7 +56,7 @@ void test_memset_array_cst_range_off (void) T (2, SR ( 1, 2), 4); T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ - T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */ + T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */ T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ T (7, UR (-7, 0), 7); T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ @@ -134,7 +134,7 @@ void test_memcpy_array_cst_range_off (const void *s) T (2, SR ( 1, 2), 4); T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ - T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */ + T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */ T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ T (7, UR (-7, 0), 7); T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ @@ -211,7 +211,7 @@ void test_strcpy_array_cst_range_off (void) T (2, SR ( 1, 2), 3); T (2, SR ( 1, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ - T (2, SR ( 0, 1), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */ + T (2, SR ( 0, 1), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */ T (2, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ T (7, UR (-7, 0), 6); T (7, UR (-7, 0), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ @@ -277,7 +277,7 @@ void test_strncpy_array_cst_range_off (const char *s) T (2, SR ( 1, 2), 4); T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ - T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */ + T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */ T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ T (7, UR (-7, 0), 7); T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c index 7c3dc8c..1ba7720 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c @@ -25,9 +25,7 @@ void test_memcpy_array_cst_range_off (const void *s) T (d + UR (1, 2), 5); T (d + UR (0, 1), 6); - /* The warning below should be "writing" but the [0, 1] range - is somehow lost and get_range_info() returns VR_VARYING. */ - T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 7 bytes into a region of size 6 overflows the destination" "pr89428" { xfail *-*-* } } */ + T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 7 bytes into a region of size 6 overflows the destination" "pr89428" } */ T (d + UR (1, 2), 6); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" } */ T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " } */ @@ -66,7 +64,7 @@ void test_memset_array_unsigned_off (void) T (d + UR (1, 2), 5); T (d + UR (0, 1), 6); - T (d + UR (0, 1), 7); /* { dg-warning ".memset. writing 6 bytes into a region of size 5 overflows the destination" "pr89428" { xfail *-*-* } } */ + T (d + UR (0, 1), 7); /* { dg-warning ".memset. writing 7 bytes into a region of size 6 overflows the destination" "pr89428" } */ T (d + UR (1, 2), 6); /* { dg-warning ".memset. writing 6 bytes into a region of size 5 overflows the destination" } */ T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " } */ diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c index 6d045c5..9100661 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c @@ -161,8 +161,11 @@ void warn_memset_reversed_range (void) /* Since the offset is excessive, either starting before &a11[0] ot just past &a[11], the region size in the warning should - probably be zero, but accept other sizes too. */ - T1 (p, SAR (INT_MIN, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" } + probably be zero, but accept other sizes too. + + The problem isn't detected anymore because the offset is in + the anti-range ~[INT_MIN, -11] which isn't handled. */ + T1 (p, SAR (INT_MIN, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" "" { xfail *-*-* } } /* The following are represented as ordinary ranges with reversed bounds and those are handled. */ @@ -170,7 +173,7 @@ void warn_memset_reversed_range (void) T1 (p, SAR (INT_MIN, 1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } T1 (p, SAR (INT_MIN, 0), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } /* Also represented as a true anti-range. */ - T1 (p, SAR ( -12, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" } + T1 (p, SAR ( -12, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" "" { xfail *-*-* } } T1 (p, SAR ( -12, -1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } T1 (p, SAR ( -11, 0), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } T1 (p, SAR ( -11, 11), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-73.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-73.c new file mode 100644 index 0000000..0bb4afe --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-73.c @@ -0,0 +1,35 @@ +/* + { dg-do compile } + { dg-options "-Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +int memcmp (const void*, const void*, size_t); +int strncmp (const char*, const char*, size_t); +char* stpncpy (char*, const char*, size_t); +char* strncpy (char*, const char*, size_t); + +extern char a4[4], b5[5]; + +struct A { char a4[4]; }; + +extern volatile int i; +extern void* volatile ptr; + +void test_stpncpy (struct A *p) +{ + ptr = stpncpy (a4, b5, 4); + ptr = stpncpy (a4, b5, 5); // { dg-warning "writing 5 bytes" } + + ptr = stpncpy (p->a4, b5, 4); + ptr = stpncpy (p->a4, b5, 5); // { dg-warning "writing 5 bytes" } +} + +void test_strncpy (struct A *p) +{ + ptr = strncpy (a4, b5, 4); + ptr = strncpy (a4, b5, 5); // { dg-warning "writing 5 bytes" } + + ptr = strncpy (p->a4, b5, 4); + ptr = strncpy (p->a4, b5, 5); // { dg-warning "writing 5 bytes" } +} -- cgit v1.1 From c4d6dcacfca1b804504515496e6d9de176d7f51e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 1 Sep 2021 22:33:06 +0200 Subject: libcpp: Implement C++23 P1949R7 - C++ Identifier Syntax using Unicode Standard Annex 31 The following patch implements the P1949R7 - C++ Identifier Syntax using Unicode Standard Annex 31 paper. We already allow UTF-8 characters in the source, so that part is already implemented, so IMHO all we need to do is pedwarn instead of just warn for the (default) -Wnormalize=nfc (or for -Wnormalize={id,nkfc}) if the character is not in NFC and to use the unicode XID_Start and XID_Continue derived code properties to find out what characters are allowed (the standard actually adds U+005F to XID_Start, but we are handling the ASCII compatible characters differently already and they aren't allowed in UCNs in identifiers). Instead of hardcoding the large tables in ucnid.tab, this patch makes makeucnid.c read them from the Unicode tables (13.0.0 version at this point). For non-pedantic mode, we accept as 2nd+ char in identifiers a union of valid characters in all supported modes, but for the 1st char it was actually pedantically requiring that it is not any of the characters that may not appear in the currently chosen standard as the first character. This patch changes it such that also what is allowed at the start of an identifier is a union of characters valid at the start of an identifier in any of the pedantic modes. 2021-09-01 Jakub Jelinek PR c++/100977 libcpp/ * include/cpplib.h (struct cpp_options): Add cxx23_identifiers. * charset.c (CXX23, NXX23): New enumerators. (CID, NFC, NKC, CTX): Renumber. (ucn_valid_in_identifier): Implement P1949R7 - use CXX23 and NXX23 flags for cxx23_identifiers. For start character in non-pedantic mode, allow characters that are allowed as start characters in any of the supported language modes, rather than disallowing characters allowed only as non-start characters in current mode but for characters from other language modes allowing them even if they are never allowed at start. * init.c (struct lang_flags): Add cxx23_identifiers. (lang_defaults): Add cxx23_identifiers column. (cpp_set_lang): Initialize CPP_OPTION (pfile, cxx23_identifiers). * lex.c (warn_about_normalization): If cxx23_identifiers, use cpp_pedwarning_with_line instead of cpp_warning_with_line for "is not in NFC" diagnostics. * makeucnid.c: Adjust usage comment. (CXX23, NXX23): New enumerators. (all_languages): Add CXX23. (not_NFC, not_NFKC, maybe_not_NFC): Renumber. (read_derivedcore): New function. (write_table): Print also CXX23 and NXX23 columns. (main): Require 5 arguments instead of 4, call read_derivedcore. * ucnid.h: Regenerated using Unicode 13.0.0 files. gcc/testsuite/ * g++.dg/cpp23/normalize1.C: New test. * g++.dg/cpp23/normalize2.C: New test. * g++.dg/cpp23/normalize3.C: New test. * g++.dg/cpp23/normalize4.C: New test. * g++.dg/cpp23/normalize5.C: New test. * g++.dg/cpp23/normalize6.C: New test. * g++.dg/cpp23/normalize7.C: New test. * g++.dg/cpp23/ucnid-1-utf8.C: New test. * g++.dg/cpp23/ucnid-2-utf8.C: New test. * gcc.dg/cpp/ucnid-4.c: Don't expect "not valid at the start of an identifier" errors. * gcc.dg/cpp/ucnid-4-utf8.c: Likewise. * gcc.dg/cpp/ucnid-5-utf8.c: New test. --- gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c | 4 ++-- gcc/testsuite/gcc.dg/cpp/ucnid-4.c | 4 ++-- gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c b/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c index ccc7a1e..0a527ef 100644 --- a/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c +++ b/gcc/testsuite/gcc.dg/cpp/ucnid-4-utf8.c @@ -9,9 +9,9 @@ Ö ΄ -Ù© /* { dg-error "not valid at the start of an identifier" } */ +Ù© AÙ© 0º 0Ù© -๙ /* { dg-error "not valid at the start of an identifier" } */ +๙ A๙ diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-4.c b/gcc/testsuite/gcc.dg/cpp/ucnid-4.c index e41a3f5..dceed66 100644 --- a/gcc/testsuite/gcc.dg/cpp/ucnid-4.c +++ b/gcc/testsuite/gcc.dg/cpp/ucnid-4.c @@ -9,9 +9,9 @@ \u00D6 \u0384 -\u0669 /* { dg-error "not valid at the start of an identifier" } */ +\u0669 A\u0669 0\u00BA 0\u0669 -\u0E59 /* { dg-error "not valid at the start of an identifier" } */ +\u0E59 A\u0E59 diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c b/gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c new file mode 100644 index 0000000..79767b4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/ucnid-5-utf8.c @@ -0,0 +1,17 @@ +/* { dg-do preprocess } */ +/* { dg-options "-std=c99 -pedantic" } */ + +ª +« /* not a preprocessing error because we lex it into its own token */ +¶ /* not a preprocessing error because we lex it into its own token */ +º +À +Ö +΄ /* not a preprocessing error because we lex it into its own token */ + +Ù© /* { dg-error "not valid at the start of an identifier" } */ +AÙ© +0º +0Ù© +๙ /* { dg-error "not valid at the start of an identifier" } */ +A๙ -- cgit v1.1 From 165446a1e81f5bb9597289e783af9ee67e1fe5ba Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 1 Sep 2021 19:13:58 -0400 Subject: Call reduce_vector_comparison_to_scalar_comparison earlier As noted in the PR, we can get an ICE after the introduction of code to reduce a vector comparison to a scalar. The problem is we left the operand cache in an inconsistent state because we called the new function too late. This is trivially fixed by making the transformation before we call update_stmt_if_modified. The irony here is the whole point of calling reduce_vector_comparison_to_scalar_comparison when we did was to expose these kinds of secondary opportunities. In this particular case we collapsed the test to a comparison of constants (thus no SSA operands). Anyway, this fixes the problem in the obvious way. This may all end up being moot if I can twiddle Richi's match.pd pattern to work. It doesn't work as-written due to a couple issues that I haven't worked totally through yet. Installed on the trunk after bootstrap & regression testing on x86 and verifying it addresses the aarch64 issue. gcc/ PR tree-optimization/102152 * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Reduce a vector comparison to a scalar comparison before calling update_stmt_if_modified. gcc/testsuite/ PR tree-optimization/102152 * gcc.dg/pr102152.c: New test --- gcc/testsuite/gcc.dg/pr102152.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr102152.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr102152.c b/gcc/testsuite/gcc.dg/pr102152.c new file mode 100644 index 0000000..4e0c1f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102152.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftree-loop-vectorize -fno-tree-fre" } */ +/* { dg-additional-options "-march=armv8-a+sve" { target aarch64-*-* } } */ + + + +signed char i; + +void +foo (void) +{ + for (i = 0; i < 6; i += 5) + ; +} -- cgit v1.1 From 483e400870601f650c80f867ec781cd5f83507d6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 2 Sep 2021 10:47:35 +0200 Subject: Refine fix for PR78185, improve LIM for code after inner loops This refines the fix for PR78185 after understanding that the code regarding to the comment 'In a loop that is always entered we may proceed anyway. But record that we entered it and stop once we leave it.' was supposed to protect us from leaving possibly infinite inner loops. The simpler fix of moving the misplaced stopping code can then be refined to continue processing when the exited inner loop is finite, improving invariant motion for cases like in the added testcase. 2021-09-02 Richard Biener * tree-ssa-loop-im.c (fill_always_executed_in_1): Refine fix for PR78185 and continue processing when leaving finite inner loops. * gcc.dg/tree-ssa/ssa-lim-16.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c new file mode 100644 index 0000000..741582b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-lim2-details" } */ + +volatile int flag, bar; +double foo (double *valp) +{ + double sum = 0; + for (int i = 0; i < 256; ++i) + { + for (int j = 0; j < 256; ++j) + bar = flag; + if (flag) + sum += 1.; + sum += *valp; // we should move the load of *valp out of the loop + } + return sum; +} + +/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim2" } } */ -- cgit v1.1 From 9695e1c23be5b5c55d572ced152897313ddb96ae Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 2 Sep 2021 09:20:09 -0600 Subject: Improve -Wuninitialized note location. Related: PR tree-optimization/17506 - warning about uninitialized variable points to wrong location PR testsuite/37182 - Revision 139286 caused gcc.dg/pr17506.c and gcc.dg/uninit-15.c gcc/ChangeLog: PR tree-optimization/17506 PR testsuite/37182 * tree-ssa-uninit.c (warn_uninit): Remove conditional guarding note. gcc/testsuite/ChangeLog: PR tree-optimization/17506 PR testsuite/37182 * gcc.dg/diagnostic-tree-expr-ranges-2.c: Add expected output. * gcc.dg/uninit-15-O0.c: Remove xfail. * gcc.dg/uninit-15.c: Same. --- .../gcc.dg/diagnostic-tree-expr-ranges-2.c | 26 +++++++++++++--------- gcc/testsuite/gcc.dg/uninit-15-O0.c | 2 +- gcc/testsuite/gcc.dg/uninit-15.c | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c b/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c index 302e233..1cbcad5 100644 --- a/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c +++ b/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c @@ -3,21 +3,25 @@ int test_uninit_1 (void) { - int result; - return result; /* { dg-warning "uninitialized" } */ -/* { dg-begin-multiline-output "" } - return result; - ^~~~~~ + int result_1; /* { dg-message "declared here" } */ + return result_1; /* { dg-warning "uninitialized" } */ + /* { dg-begin-multiline-output "" } + return result_1; + ^~~~~~~~ + int result_1; + ^~~~~~~~ { dg-end-multiline-output "" } */ } int test_uninit_2 (void) { - int result; - result += 3; /* { dg-warning "uninitialized" } */ -/* { dg-begin-multiline-output "" } - result += 3; - ~~~~~~~^~~~ + int result_2; /* { dg-message "declared here" } */ + result_2 += 3; /* { dg-warning "uninitialized" } */ + /* { dg-begin-multiline-output "" } + result_2 += 3; + ~~~~~~~~~^~~~ + int result_2; + ^~~~~~~~ { dg-end-multiline-output "" } */ - return result; + return result_2; } diff --git a/gcc/testsuite/gcc.dg/uninit-15-O0.c b/gcc/testsuite/gcc.dg/uninit-15-O0.c index 36d9634..1ddddee 100644 --- a/gcc/testsuite/gcc.dg/uninit-15-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-15-O0.c @@ -14,7 +14,7 @@ void baz(); void bar() { - int j; /* { dg-message "was declared here" {} { xfail *-*-* } } */ + int j; /* { dg-message "declared here" } */ for (; foo(j); ++j) /* { dg-warning "is used uninitialized" } */ baz(); } diff --git a/gcc/testsuite/gcc.dg/uninit-15.c b/gcc/testsuite/gcc.dg/uninit-15.c index 85cb116..7352662 100644 --- a/gcc/testsuite/gcc.dg/uninit-15.c +++ b/gcc/testsuite/gcc.dg/uninit-15.c @@ -20,7 +20,7 @@ void baz (void); void bar (void) { - int j; /* { dg-message "note: 'j' was declared here" "" { xfail *-*-* } } */ + int j; /* { dg-message "note: 'j' was declared here" } */ for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" } */ baz (); } -- cgit v1.1 From 8a4602c2e0f81895415ba7ee23bf81dc795d1103 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 6 Sep 2021 10:08:16 +0200 Subject: match.pd: Fix up __builtin_*_overflow arg demotion [PR102207] My earlier patch to demote arguments of __builtin_*_overflow unfortunately caused a wrong-code regression. The builtins operate on infinite precision arguments, outer_prec > inner_prec signed -> signed, unsigned -> unsigned promotions there are just repeating the sign or 0s and can be demoted, similarly unsigned -> signed which also is repeating 0s, but as the testcase shows, signed -> unsigned promotions need to be preserved (unless we'd know the inner arguments can't be negative), because for negative numbers such promotion sets the outer_prec -> inner_prec bits to 1 bit the bits above that to 0 in the infinite precision. So, the following patch avoids the demotions for the signed -> unsigned promotions. 2021-09-06 Jakub Jelinek PR tree-optimization/102207 * match.pd: Don't demote operands of IFN_{ADD,SUB,MUL}_OVERFLOW if they were promoted from signed to wider unsigned type. * gcc.dg/pr102207.c: New test. --- gcc/testsuite/gcc.dg/pr102207.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr102207.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr102207.c b/gcc/testsuite/gcc.dg/pr102207.c new file mode 100644 index 0000000..08540d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102207.c @@ -0,0 +1,24 @@ +/* PR tree-optimization/102207 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2" } */ + +typedef unsigned __int128 u128; + +u128 +foo (unsigned short a) +{ + u128 g; + __builtin_sub_overflow ((unsigned long long) -a, 1, &g); + return g; +} + +int +main () +{ + if (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ != 64 + || __SIZEOF_SHORT__ * __CHAR_BIT__ != 16) + return 0; + if (foo (1) != 0xfffffffffffffffeULL) + __builtin_abort (); + return 0; +} -- cgit v1.1 From aad72d2ea8378e1a56c00d15daa4bdcac8a5ae39 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 22 Jun 2021 10:09:01 +0200 Subject: inline: do not einline when no_profile_instrument_function is different PR gcov-profile/80223 gcc/ChangeLog: * ipa-inline.c (can_inline_edge_p): Similarly to sanitizer options, do not inline when no_profile_instrument_function attributes are different in early inliner. It's fine to inline it after PGO instrumentation. gcc/testsuite/ChangeLog: * gcc.dg/no_profile_instrument_function-attr-2.c: New test. --- .../gcc.dg/no_profile_instrument_function-attr-2.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c b/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c new file mode 100644 index 0000000..472eca8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c @@ -0,0 +1,15 @@ +/* { dg-require-effective-target global_constructor } */ +/* { dg-options "-O2 -fprofile-generate -fprofile-update=single -fdump-tree-optimized" } */ + +__attribute__ ((no_profile_instrument_function)) +int foo() +{ + return 0; +} + +int bar() +{ + return foo(); +} + +/* { dg-final { scan-tree-dump-not" = foo \\(\\)" "optimized"} } */ -- cgit v1.1 From 578cd82af71f978c7ffe5f50d9568df21beb25c4 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Tue, 7 Sep 2021 22:08:49 +0200 Subject: Fix fatal typo in gcc.dg/no_profile_instrument_function-attr-2.c Dejagnu is unfortunately brittle: a syntax error in a directive can abort the test-run for the current "tool" (gcc, g++, gfortran), and if you don't check for this condition or actually read the stdout log yourself, your tools may make you believe the test was successful without regressions. At the very least, always grep for ^ERROR: in the stdout log! With r12-3379, the testsuite got such a fatal syntax error, causing the gcc test-run to abort at (e.g.): ... FAIL: gcc.dg/memchr.c (test for excess errors) FAIL: gcc.dg/memcmp-3.c (test for excess errors) ERROR: (DejaGnu) proc "scan-tree-dump-not\" = foo {\(\)"} optimized" does not exist. The error code is TCL LOOKUP COMMAND scan-tree-dump-not\" The info on the error is: invalid command name "scan-tree-dump-not"" while executing "::tcl_unknown scan-tree-dump-not\" = foo {\(\)"} optimized" ("uplevel" body line 1) invoked from within "uplevel 1 ::tcl_unknown $args" === gcc Summary === # of expected passes 63740 # of unexpected failures 38 # of unexpected successes 2 # of expected failures 351 # of unresolved testcases 3 # of unsupported tests 662 x/cris-elf/gccobj/gcc/xgcc version 12.0.0 20210907 (experimental)\ [master r12-3391-g849d5f5929fc] (GCC) testsuite: * gcc.dg/no_profile_instrument_function-attr-2.c: Fix typo in last change. --- gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c b/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c index 472eca8..2e93ee5 100644 --- a/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c +++ b/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-2.c @@ -12,4 +12,4 @@ int bar() return foo(); } -/* { dg-final { scan-tree-dump-not" = foo \\(\\)" "optimized"} } */ +/* { dg-final { scan-tree-dump-not " = foo \\(\\)" "optimized"} } */ -- cgit v1.1 From a7b626d98a9a821ffb33466818d6aa86cac1d6fd Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 8 Sep 2021 11:25:31 +0200 Subject: i386: Fix up @xorsign3_1 [PR102224] As the testcase shows, we miscompile @xorsign3_1 if both input operands are in the same register, because the splitter overwrites op1 before with op1 & mask before using op0. For dest = xorsign op0, op0 we can actually simplify it from dest = (op0 & mask) ^ op0 to dest = op0 & ~mask (aka abs). The expander change is an optimization improvement, if we at expansion time know it is xorsign op0, op0, we can emit abs right away and get better code through that. The @xorsign3_1 is a fix for the case where xorsign wouldn't be known to have same operands during expansion, but during RTL optimizations they would appear. For non-AVX we need to use earlyclobber, we require dest and op1 to be the same but op0 must be different because we overwrite op1 first. For AVX the constraints ensure that at most 2 of the 3 operands may be the same register and if both inputs are the same, handles that case. This case can be easily tested with the xorsign3 expander change reverted. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Thinking about it more this morning, while this patch fixes the problems revealed in the testcase, the recent PR89984 change was buggy too, but perhaps that can be fixed incrementally. Because for AVX the new code destructively modifies op1. If that is different from dest, say on: float foo (float x, float y) { return x * __builtin_copysignf (1.0f, y) + y; } then we get after RA: (insn 8 7 9 2 (set (reg:SF 20 xmm0 [orig:82 _2 ] [82]) (unspec:SF [ (reg:SF 20 xmm0 [88]) (reg:SF 21 xmm1 [89]) (mem/u/c:V4SF (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S16 A128]) ] UNSPEC_XORSIGN)) "hohoho.c":4:12 649 {xorsignsf3_1} (nil)) (insn 9 8 15 2 (set (reg:SF 20 xmm0 [87]) (plus:SF (reg:SF 20 xmm0 [orig:82 _2 ] [82]) (reg:SF 21 xmm1 [89]))) "hohoho.c":4:44 1021 {*fop_sf_comm} (nil)) but split the xorsign into: vandps .LC0(%rip), %xmm1, %xmm1 vxorps %xmm0, %xmm1, %xmm0 and then the addition: vaddss %xmm1, %xmm0, %xmm0 which means we miscompile it - instead of adding y in the end we add __builtin_copysignf (0.0f, y). So, wonder if we don't want instead in addition to the &Yv <- Yv, 0 alternative (enabled for both pre-AVX and AVX as in this patch) the &Yv <- Yv, Yv where destination must be different from inputs and another Yv <- Yv, Yv where it can be the same but then need a match_scratch (with X for the other alternatives and =Yv for the last one). That way we'd always have a safe register we can store the op1 & mask value into, either the destination (in the first alternative known to be equal to op1 which is needed for non-AVX but ok for AVX too), in the second alternative known to be different from both inputs and in the third which could be used for those float bar (float x, float y) { return x * __builtin_copysignf (1.0f, y); } cases where op1 is naturally xmm1 and dest == op0 naturally xmm0 we'd use some other register like xmm2. 2021-09-08 Jakub Jelinek PR target/102224 * config/i386/i386.md (xorsign3): If operands[1] is equal to operands[2], emit abs2 instead. (@xorsign3_1): Add early-clobbers for output operand, enable first alternative even for avx, add another alternative with =&Yv <- 0, Yv, Yvm constraints. * config/i386/i386-expand.c (ix86_split_xorsign): If op0 is equal to op1, emit vpandn instead. * gcc.dg/pr102224.c: New test. * gcc.target/i386/avx-pr102224.c: New test. --- gcc/testsuite/gcc.dg/pr102224.c | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr102224.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr102224.c b/gcc/testsuite/gcc.dg/pr102224.c new file mode 100644 index 0000000..9f09ba5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102224.c @@ -0,0 +1,49 @@ +/* PR target/102224 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +__attribute__((noipa)) float +foo (float x) +{ + return x * __builtin_copysignf (1.0f, x); +} + +__attribute__((noipa)) float +bar (float x, float y) +{ + return x * __builtin_copysignf (1.0f, y); +} + +__attribute__((noipa)) float +baz (float z, float x) +{ + return x * __builtin_copysignf (1.0f, x); +} + +__attribute__((noipa)) float +qux (float z, float x, float y) +{ + return x * __builtin_copysignf (1.0f, y); +} + +int +main () +{ + if (foo (1.0f) != 1.0f + || foo (-4.0f) != 4.0f) + __builtin_abort (); + if (bar (1.25f, 7.25f) != 1.25f + || bar (1.75f, -3.25f) != -1.75f + || bar (-2.25f, 7.5f) != -2.25f + || bar (-3.0f, -4.0f) != 3.0f) + __builtin_abort (); + if (baz (5.5f, 1.0f) != 1.0f + || baz (4.25f, -4.0f) != 4.0f) + __builtin_abort (); + if (qux (1.0f, 1.25f, 7.25f) != 1.25f + || qux (2.0f, 1.75f, -3.25f) != -1.75f + || qux (3.0f, -2.25f, 7.5f) != -2.25f + || qux (4.0f, -3.0f, -4.0f) != 3.0f) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 7485a52551d71db2e8bbfc4c484196bcc321a1cd Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 8 Sep 2021 14:06:10 +0200 Subject: i386: Fix up xorsign for AVX [PR89984] Thinking about it more this morning, while this patch fixes the problems revealed in the testcase, the recent PR89984 change was buggy too, but perhaps that can be fixed incrementally. Because for AVX the new code destructively modifies op1. If that is different from dest, say on: float foo (float x, float y) { return x * __builtin_copysignf (1.0f, y) + y; } then we get after RA: (insn 8 7 9 2 (set (reg:SF 20 xmm0 [orig:82 _2 ] [82]) (unspec:SF [ (reg:SF 20 xmm0 [88]) (reg:SF 21 xmm1 [89]) (mem/u/c:V4SF (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S16 A128]) ] UNSPEC_XORSIGN)) "hohoho.c":4:12 649 {xorsignsf3_1} (nil)) (insn 9 8 15 2 (set (reg:SF 20 xmm0 [87]) (plus:SF (reg:SF 20 xmm0 [orig:82 _2 ] [82]) (reg:SF 21 xmm1 [89]))) "hohoho.c":4:44 1021 {*fop_sf_comm} (nil)) but split the xorsign into: vandps .LC0(%rip), %xmm1, %xmm1 vxorps %xmm0, %xmm1, %xmm0 and then the addition: vaddss %xmm1, %xmm0, %xmm0 which means we miscompile it - instead of adding y in the end we add __builtin_copysignf (0.0f, y). So, wonder if we don't want instead in addition to the &Yv <- Yv, 0 alternative (enabled for both pre-AVX and AVX as in this patch) the &Yv <- Yv, Yv where destination must be different from inputs and another Yv <- Yv, Yv where it can be the same but then need a match_scratch (with X for the other alternatives and =Yv for the last one). That way we'd always have a safe register we can store the op1 & mask value into, either the destination (in the first alternative known to be equal to op1 which is needed for non-AVX but ok for AVX too), in the second alternative known to be different from both inputs and in the third which could be used for those float bar (float x, float y) { return x * __builtin_copysignf (1.0f, y); } cases where op1 is naturally xmm1 and dest == op0 naturally xmm0 we'd use some other register like xmm2. On Wed, Sep 08, 2021 at 05:23:40PM +0800, Hongtao Liu wrote: > I'm curious why we need the post_reload splitter @xorsign3_1 > for scalar mode, can't we just expand them into and/xor operations in > the expander, just like vector modes did. Following seems to work for all the testcases I've tried (and in some generates better code than the post-reload splitter). 2021-09-08 Jakub Jelinek liuhongt PR target/89984 * config/i386/i386.md (@xorsign3_1): Remove. * config/i386/i386-expand.c (ix86_expand_xorsign): Expand right away into AND with mask and XOR, using paradoxical subregs. (ix86_split_xorsign): Remove. * config/i386/i386-protos.h (ix86_split_xorsign): Remove. * gcc.target/i386/avx-pr102224.c: Fix up PR number. * gcc.dg/pr89984.c: New test. * gcc.target/i386/avx-pr89984.c: New test. --- gcc/testsuite/gcc.dg/pr89984.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr89984.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr89984.c b/gcc/testsuite/gcc.dg/pr89984.c new file mode 100644 index 0000000..471fe92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr89984.c @@ -0,0 +1,20 @@ +/* PR target/89984 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +__attribute__((noipa)) float +foo (float x, float y) +{ + return x * __builtin_copysignf (1.0f, y) + y; +} + +int +main () +{ + if (foo (1.25f, 7.25f) != 1.25f + 7.25f + || foo (1.75f, -3.25f) != -1.75f + -3.25f + || foo (-2.25f, 7.5f) != -2.25f + 7.5f + || foo (-3.0f, -4.0f) != 3.0f + -4.0f) + __builtin_abort (); + return 0; +} -- cgit v1.1 From d081516ae1771984bfacb9f2c402a1973fa70d69 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 8 Sep 2021 14:57:20 +0000 Subject: testsuite: Use explicit -ftree-cselim in tests using -fdump-tree-cselim-details When testing for Nios II (gcc-testresults shows this for various other targets as well), tests scanning cselim dumps produce an UNRESOLVED result because those dumps do not exist. cselim is enabled conditionally by code in toplev.c: if (flag_tree_cselim == AUTODETECT_VALUE) { if (HAVE_conditional_move) flag_tree_cselim = 1; else flag_tree_cselim = 0; } Add explicit -ftree-cselim to dg-options in the affected tests (as already used by some other tests of cselim dumps) so that this dump exists on all architectures. Tested with no regressions with cross to nios2-elf, where this causes the tests in question to PASS instead of being UNRESOLVED. * gcc.dg/tree-ssa/pr89430-1.c, gcc.dg/tree-ssa/pr89430-2.c, gcc.dg/tree-ssa/pr89430-3.c, gcc.dg/tree-ssa/pr89430-4.c, gcc.dg/tree-ssa/pr89430-5.c, gcc.dg/tree-ssa/pr89430-6.c, gcc.dg/tree-ssa/pr89430-7-comp-ref.c, gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c, gcc.dg/tree-ssa/pr99473-1.c: Use -ftree-cselim. --- gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-7-comp-ref.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c index 8ee1850..d9fb2ed 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ unsigned test(unsigned k, unsigned b) { unsigned a[2]; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c index 9b96875..bb39df2 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ int c; unsigned test(unsigned k, unsigned b) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c index 0fac9f9..0016637 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ unsigned a[2]; unsigned test(unsigned k, unsigned b) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c index 54b8c11..127cbdf 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ int *p; unsigned test(unsigned k, unsigned b) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c index b2d0411..6a00f54 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ int test(int b, int k) { struct { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c index 8d3c4f7..ecc083e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ int test(int b, int k) { typedef struct { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-7-comp-ref.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-7-comp-ref.c index c35a2af..4fad2d1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-7-comp-ref.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-7-comp-ref.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ typedef union { int i; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c index f9e66ae..5f93112 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fdump-tree-cselim-details" } */ int *t; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c index a9fd542..0fda566 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr99473-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fallow-store-data-races -fdump-tree-cselim-details" } */ +/* { dg-options "-O2 -ftree-cselim -fallow-store-data-races -fdump-tree-cselim-details" } */ void f (int*); -- cgit v1.1 From d27d694151c5604d2daba23dd2a328ae70b65194 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 8 Sep 2021 15:38:18 +0000 Subject: testsuite: Allow .sdata in more cases in gcc.dg/array-quals-1.c When testing for Nios II (gcc-testresults shows this for MIPS as well), failures of gcc.dg/array-quals-1.c appear where a symbol was found in .sdata rather than one of the expected sections. FAIL: gcc.dg/array-quals-1.c scan-assembler-symbol-section symbol ^_?a$ (found a) has section ^\\.(const|rodata|srodata)|\\[RO\\] (found .sdata) FAIL: gcc.dg/array-quals-1.c scan-assembler-symbol-section symbol ^_?b$ (found b) has section ^\\.(const|rodata|srodata)|\\[RO\\] (found .sdata) FAIL: gcc.dg/array-quals-1.c scan-assembler-symbol-section symbol ^_?c$ (found c) has section ^\\.(const|rodata|srodata)|\\[RO\\] (found .sdata) FAIL: gcc.dg/array-quals-1.c scan-assembler-symbol-section symbol ^_?d$ (found d) has section ^\\.(const|rodata|srodata)|\\[RO\\] (found .sdata) Jakub's commit 0b34dbc0a24864b1674bff7a92fa3cf0f1cbcea1 allowed .sdata for many variables in that test where use of .sdata caused a failure on powerpc-linux. I'm presuming the choice of which variables had .sdata allowed was based only on the code generated for powerpc-linux, not on any reason it would be wrong to allow it for the other variables; thus, this patch adjusts the test to allow .sdata for some more variables where that is needed on Nios II (and in one case where it's not needed on Nios II, but the test results on gcc-testresults suggest that it is needed on MIPS). Tested with no regressions with cross to nios2-elf. * gcc.dg/array-quals-1.c: Allow .sdata section in more cases. --- gcc/testsuite/gcc.dg/array-quals-1.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/array-quals-1.c b/gcc/testsuite/gcc.dg/array-quals-1.c index 2c04164..b9b55f7 100644 --- a/gcc/testsuite/gcc.dg/array-quals-1.c +++ b/gcc/testsuite/gcc.dg/array-quals-1.c @@ -7,26 +7,26 @@ /* { dg-additional-options "-fno-pie" { target pie } } */ /* The MMIX port always switches to the .data section at the end of a file. */ /* { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail powerpc*-*-aix* mmix-*-* x86_64-*-mingw* } } } */ -/* { dg-final { scan-assembler-symbol-section {^_?a$} {^\.(const|rodata|srodata)|\[RO\]} } } */ +/* { dg-final { scan-assembler-symbol-section {^_?a$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ static const int a[2] = { 1, 2 }; /* { dg-final { scan-assembler-symbol-section {^_?a1$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ const int a1[2] = { 1, 2 }; typedef const int ci; -/* { dg-final { scan-assembler-symbol-section {^_?b$} {^\.(const|rodata|srodata)|\[RO\]} } } */ +/* { dg-final { scan-assembler-symbol-section {^_?b$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ static ci b[2] = { 3, 4 }; /* { dg-final { scan-assembler-symbol-section {^_?b1$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ ci b1[2] = { 3, 4 }; typedef int ia[2]; -/* { dg-final { scan-assembler-symbol-section {^_?c$} {^\.(const|rodata|srodata)|\[RO\]} } } */ +/* { dg-final { scan-assembler-symbol-section {^_?c$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ static const ia c = { 5, 6 }; /* { dg-final { scan-assembler-symbol-section {^_?c1$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ const ia c1 = { 5, 6 }; typedef const int cia[2]; -/* { dg-final { scan-assembler-symbol-section {^_?d$} {^\.(const|rodata|srodata)|\[RO\]} } } */ +/* { dg-final { scan-assembler-symbol-section {^_?d$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ static cia d = { 7, 8 }; /* { dg-final { scan-assembler-symbol-section {^_?d1$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ cia d1 = { 7, 8 }; -/* { dg-final { scan-assembler-symbol-section {^_?e$} {^\.(const|rodata|srodata)|\[RO\]} } } */ +/* { dg-final { scan-assembler-symbol-section {^_?e$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ static cia e[2] = { { 1, 2 }, { 3, 4 } }; /* { dg-final { scan-assembler-symbol-section {^_?e1$} {^\.(const|rodata|srodata|sdata)|\[RO\]} } } */ cia e1[2] = { { 1, 2 }, { 3, 4 } }; -- cgit v1.1 From e66b9f6779f46433b0e2c093b58403604ed131cc Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 8 Sep 2021 14:37:19 -0400 Subject: analyzer: fix ICE when discarding result of realloc [PR102225] gcc/analyzer/ChangeLog: PR analyzer/102225 * analyzer.h (compat_types_p): New decl. * constraint-manager.cc (constraint_manager::get_or_add_equiv_class): Guard against NULL type when checking for pointer types. * region-model-impl-calls.cc (region_model::impl_call_realloc): Guard against NULL lhs type/region. Guard against the size value not being of a compatible type for dynamic extents. * region-model.cc (compat_types_p): Make non-static. gcc/testsuite/ChangeLog: PR analyzer/102225 * gcc.dg/analyzer/realloc-1.c (test_10): New. * gcc.dg/analyzer/torture/pr102225.c: New test. --- gcc/testsuite/gcc.dg/analyzer/realloc-1.c | 5 +++++ gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c index 606a19a..ef117ad 100644 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c @@ -88,3 +88,8 @@ void test_9 (void *p) free (p); void *q = realloc (p, 1024); /* { dg-warning "double-'free' of 'p'" } */ } + +void test_10 (char *s, int n) +{ + __builtin_realloc(s, n); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" } */ +} /* { dg-warning "leak" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c new file mode 100644 index 0000000..a7c3249 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr102225.c @@ -0,0 +1,6 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +void bad_realloc(char *s, int n) +{ + char *p = __builtin_realloc(s, n); +} /* { dg-warning "leak" } */ -- cgit v1.1 From 013cfc648405a8a118d07436f103e4d70224fe00 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 9 Sep 2021 11:50:20 +0200 Subject: Improve LIM fill_always_executed_in computation Currently the DOM walk over a loop body does not walk into not always executed subloops to avoid scalability issues since doing so makes the walk quadratic in the loop depth. It turns out this is not an issue in practice and even with a loop depth of 1800 this function is way off the radar. So the following patch removes the limitation, replacing it with a comment. 2021-09-09 Richard Biener * tree-ssa-loop-im.c (fill_always_executed_in_1): Walk into all subloops. * gcc.dg/tree-ssa/ssa-lim-17.c: New testcase. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c new file mode 100644 index 0000000..1c840e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-lim2-details" } */ + +volatile int flag, bar; +double foo (double *valp) +{ + double sum = 0; + for (int i = 0; i < 256; ++i) + { + if (flag) + for (int j = 0; j < 256; ++j) + bar = flag; + if (flag) + sum += 1.; + sum += *valp; // we should move the load of *valp out of the loop + } + return sum; +} + +/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim2" } } */ -- cgit v1.1 From a25e0b5e6ac8a77a71c229e0a7b744603365b0e9 Mon Sep 17 00:00:00 2001 From: qing zhao Date: Thu, 9 Sep 2021 15:44:49 -0700 Subject: Add -ftrivial-auto-var-init option and uninitialized variable attribute. Initialize automatic variables with either a pattern or with zeroes to increase the security and predictability of a program by preventing uninitialized memory disclosure and use. GCC still considers an automatic variable that doesn't have an explicit initializer as uninitialized, -Wuninitialized will still report warning messages on such automatic variables. With this option, GCC will also initialize any padding of automatic variables that have structure or union types to zeroes. You can control this behavior for a specific variable by using the variable attribute "uninitialized" to control runtime overhead. gcc/ChangeLog: 2021-09-09 qing zhao * builtins.c (expand_builtin_memset): Make external visible. * builtins.h (expand_builtin_memset): Declare extern. * common.opt (ftrivial-auto-var-init=): New option. * doc/extend.texi: Document the uninitialized attribute. * doc/invoke.texi: Document -ftrivial-auto-var-init. * flag-types.h (enum auto_init_type): New enumerated type auto_init_type. * gimple-fold.c (clear_padding_type): Add one new parameter. (clear_padding_union): Likewise. (clear_padding_emit_loop): Likewise. (clear_type_padding_in_mask): Likewise. (gimple_fold_builtin_clear_padding): Handle this new parameter. * gimplify.c (gimple_add_init_for_auto_var): New function. (gimple_add_padding_init_for_auto_var): New function. (is_var_need_auto_init): New function. (gimplify_decl_expr): Add initialization to automatic variables per users' requests. (gimplify_call_expr): Add one new parameter for call to __builtin_clear_padding. (gimplify_init_constructor): Add padding initialization in the end. * internal-fn.c (INIT_PATTERN_VALUE): New macro. (expand_DEFERRED_INIT): New function. * internal-fn.def (DEFERRED_INIT): New internal function. * tree-cfg.c (verify_gimple_call): Verify calls to .DEFERRED_INIT. * tree-sra.c (generate_subtree_deferred_init): New function. (scan_function): Avoid setting cannot_scalarize_away_bitmap for calls to .DEFERRED_INIT. (sra_modify_deferred_init): New function. (sra_modify_function_body): Handle calls to DEFERRED_INIT specially. * tree-ssa-structalias.c (find_func_aliases_for_call): Likewise. * tree-ssa-uninit.c (warn_uninit): Handle calls to DEFERRED_INIT specially. (check_defs): Likewise. (warn_uninitialized_vars): Likewise. * tree-ssa.c (ssa_undefined_value_p): Likewise. * tree.c (build_common_builtin_nodes): Build tree node for BUILT_IN_CLEAR_PADDING when needed. gcc/c-family/ChangeLog: 2021-09-09 qing zhao * c-attribs.c (handle_uninitialized_attribute): New function. (c_common_attribute_table): Add "uninitialized" attribute. gcc/testsuite/ChangeLog: 2021-09-09 qing zhao * c-c++-common/auto-init-1.c: New test. * c-c++-common/auto-init-10.c: New test. * c-c++-common/auto-init-11.c: New test. * c-c++-common/auto-init-12.c: New test. * c-c++-common/auto-init-13.c: New test. * c-c++-common/auto-init-14.c: New test. * c-c++-common/auto-init-15.c: New test. * c-c++-common/auto-init-16.c: New test. * c-c++-common/auto-init-2.c: New test. * c-c++-common/auto-init-3.c: New test. * c-c++-common/auto-init-4.c: New test. * c-c++-common/auto-init-5.c: New test. * c-c++-common/auto-init-6.c: New test. * c-c++-common/auto-init-7.c: New test. * c-c++-common/auto-init-8.c: New test. * c-c++-common/auto-init-9.c: New test. * c-c++-common/auto-init-esra.c: New test. * c-c++-common/auto-init-padding-1.c: New test. * c-c++-common/auto-init-padding-2.c: New test. * c-c++-common/auto-init-padding-3.c: New test. * g++.dg/auto-init-uninit-pred-1_a.C: New test. * g++.dg/auto-init-uninit-pred-2_a.C: New test. * g++.dg/auto-init-uninit-pred-3_a.C: New test. * g++.dg/auto-init-uninit-pred-4.C: New test. * gcc.dg/auto-init-sra-1.c: New test. * gcc.dg/auto-init-sra-2.c: New test. * gcc.dg/auto-init-uninit-1.c: New test. * gcc.dg/auto-init-uninit-12.c: New test. * gcc.dg/auto-init-uninit-13.c: New test. * gcc.dg/auto-init-uninit-14.c: New test. * gcc.dg/auto-init-uninit-15.c: New test. * gcc.dg/auto-init-uninit-16.c: New test. * gcc.dg/auto-init-uninit-17.c: New test. * gcc.dg/auto-init-uninit-18.c: New test. * gcc.dg/auto-init-uninit-19.c: New test. * gcc.dg/auto-init-uninit-2.c: New test. * gcc.dg/auto-init-uninit-20.c: New test. * gcc.dg/auto-init-uninit-21.c: New test. * gcc.dg/auto-init-uninit-22.c: New test. * gcc.dg/auto-init-uninit-23.c: New test. * gcc.dg/auto-init-uninit-24.c: New test. * gcc.dg/auto-init-uninit-25.c: New test. * gcc.dg/auto-init-uninit-26.c: New test. * gcc.dg/auto-init-uninit-3.c: New test. * gcc.dg/auto-init-uninit-34.c: New test. * gcc.dg/auto-init-uninit-36.c: New test. * gcc.dg/auto-init-uninit-37.c: New test. * gcc.dg/auto-init-uninit-4.c: New test. * gcc.dg/auto-init-uninit-5.c: New test. * gcc.dg/auto-init-uninit-6.c: New test. * gcc.dg/auto-init-uninit-8.c: New test. * gcc.dg/auto-init-uninit-9.c: New test. * gcc.dg/auto-init-uninit-A.c: New test. * gcc.dg/auto-init-uninit-B.c: New test. * gcc.dg/auto-init-uninit-C.c: New test. * gcc.dg/auto-init-uninit-H.c: New test. * gcc.dg/auto-init-uninit-I.c: New test. * gcc.target/aarch64/auto-init-1.c: New test. * gcc.target/aarch64/auto-init-2.c: New test. * gcc.target/aarch64/auto-init-3.c: New test. * gcc.target/aarch64/auto-init-4.c: New test. * gcc.target/aarch64/auto-init-5.c: New test. * gcc.target/aarch64/auto-init-6.c: New test. * gcc.target/aarch64/auto-init-7.c: New test. * gcc.target/aarch64/auto-init-8.c: New test. * gcc.target/aarch64/auto-init-padding-1.c: New test. * gcc.target/aarch64/auto-init-padding-10.c: New test. * gcc.target/aarch64/auto-init-padding-11.c: New test. * gcc.target/aarch64/auto-init-padding-12.c: New test. * gcc.target/aarch64/auto-init-padding-2.c: New test. * gcc.target/aarch64/auto-init-padding-3.c: New test. * gcc.target/aarch64/auto-init-padding-4.c: New test. * gcc.target/aarch64/auto-init-padding-5.c: New test. * gcc.target/aarch64/auto-init-padding-6.c: New test. * gcc.target/aarch64/auto-init-padding-7.c: New test. * gcc.target/aarch64/auto-init-padding-8.c: New test. * gcc.target/aarch64/auto-init-padding-9.c: New test. * gcc.target/i386/auto-init-1.c: New test. * gcc.target/i386/auto-init-2.c: New test. * gcc.target/i386/auto-init-21.c: New test. * gcc.target/i386/auto-init-22.c: New test. * gcc.target/i386/auto-init-23.c: New test. * gcc.target/i386/auto-init-24.c: New test. * gcc.target/i386/auto-init-3.c: New test. * gcc.target/i386/auto-init-4.c: New test. * gcc.target/i386/auto-init-5.c: New test. * gcc.target/i386/auto-init-6.c: New test. * gcc.target/i386/auto-init-7.c: New test. * gcc.target/i386/auto-init-8.c: New test. * gcc.target/i386/auto-init-padding-1.c: New test. * gcc.target/i386/auto-init-padding-10.c: New test. * gcc.target/i386/auto-init-padding-11.c: New test. * gcc.target/i386/auto-init-padding-12.c: New test. * gcc.target/i386/auto-init-padding-2.c: New test. * gcc.target/i386/auto-init-padding-3.c: New test. * gcc.target/i386/auto-init-padding-4.c: New test. * gcc.target/i386/auto-init-padding-5.c: New test. * gcc.target/i386/auto-init-padding-6.c: New test. * gcc.target/i386/auto-init-padding-7.c: New test. * gcc.target/i386/auto-init-padding-8.c: New test. * gcc.target/i386/auto-init-padding-9.c: New test. --- gcc/testsuite/gcc.dg/auto-init-sra-1.c | 24 +++ gcc/testsuite/gcc.dg/auto-init-sra-2.c | 24 +++ gcc/testsuite/gcc.dg/auto-init-uninit-1.c | 5 + gcc/testsuite/gcc.dg/auto-init-uninit-12.c | 4 + gcc/testsuite/gcc.dg/auto-init-uninit-13.c | 10 ++ gcc/testsuite/gcc.dg/auto-init-uninit-14.c | 4 + gcc/testsuite/gcc.dg/auto-init-uninit-15.c | 26 ++++ gcc/testsuite/gcc.dg/auto-init-uninit-16.c | 25 +++ gcc/testsuite/gcc.dg/auto-init-uninit-17.c | 15 ++ gcc/testsuite/gcc.dg/auto-init-uninit-18.c | 3 + gcc/testsuite/gcc.dg/auto-init-uninit-19.c | 26 ++++ gcc/testsuite/gcc.dg/auto-init-uninit-2.c | 5 + gcc/testsuite/gcc.dg/auto-init-uninit-20.c | 4 + gcc/testsuite/gcc.dg/auto-init-uninit-21.c | 4 + gcc/testsuite/gcc.dg/auto-init-uninit-22.c | 3 + gcc/testsuite/gcc.dg/auto-init-uninit-23.c | 27 ++++ gcc/testsuite/gcc.dg/auto-init-uninit-24.c | 3 + gcc/testsuite/gcc.dg/auto-init-uninit-25.c | 23 +++ gcc/testsuite/gcc.dg/auto-init-uninit-26.c | 23 +++ gcc/testsuite/gcc.dg/auto-init-uninit-3.c | 5 + gcc/testsuite/gcc.dg/auto-init-uninit-34.c | 60 ++++++++ gcc/testsuite/gcc.dg/auto-init-uninit-36.c | 238 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/auto-init-uninit-37.c | 156 +++++++++++++++++++ gcc/testsuite/gcc.dg/auto-init-uninit-4.c | 10 ++ gcc/testsuite/gcc.dg/auto-init-uninit-5.c | 6 + gcc/testsuite/gcc.dg/auto-init-uninit-6.c | 7 + gcc/testsuite/gcc.dg/auto-init-uninit-8.c | 8 + gcc/testsuite/gcc.dg/auto-init-uninit-9.c | 8 + gcc/testsuite/gcc.dg/auto-init-uninit-A.c | 7 + gcc/testsuite/gcc.dg/auto-init-uninit-B.c | 17 +++ gcc/testsuite/gcc.dg/auto-init-uninit-C.c | 5 + gcc/testsuite/gcc.dg/auto-init-uninit-H.c | 5 + gcc/testsuite/gcc.dg/auto-init-uninit-I.c | 3 + 33 files changed, 793 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/auto-init-sra-1.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-sra-2.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-1.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-12.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-13.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-14.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-15.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-16.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-17.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-18.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-19.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-2.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-20.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-21.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-22.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-23.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-24.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-25.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-26.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-3.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-34.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-36.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-37.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-4.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-5.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-6.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-8.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-9.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-A.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-B.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-C.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-H.c create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-I.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/auto-init-sra-1.c b/gcc/testsuite/gcc.dg/auto-init-sra-1.c new file mode 100644 index 0000000..88fd666 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-sra-1.c @@ -0,0 +1,24 @@ +/* Verify that SRA total scalarization will not be confused by padding + and also not confused by auto initialization. */ +/* { dg-do compile } */ +/* { dg-options "-O1 --param sra-max-scalarization-size-Ospeed=16 -fdump-tree-release_ssa -ftrivial-auto-var-init=zero" } */ + +struct S +{ + int i; + unsigned short f1; + char f2; + unsigned short f3, f4; +}; + + +int foo (struct S *p) +{ + struct S l; + + l = *p; + l.i++; + *p = l; +} + +/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa" } } */ diff --git a/gcc/testsuite/gcc.dg/auto-init-sra-2.c b/gcc/testsuite/gcc.dg/auto-init-sra-2.c new file mode 100644 index 0000000..d260f5a --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-sra-2.c @@ -0,0 +1,24 @@ +/* Verify that SRA total scalarization will not be confused by padding + and also not confused by auto initialization. */ +/* { dg-do compile } */ +/* { dg-options "-O1 --param sra-max-scalarization-size-Ospeed=16 -fdump-tree-release_ssa -ftrivial-auto-var-init=pattern" } */ + +struct S +{ + int i; + unsigned short f1; + char f2; + unsigned short f3, f4; +}; + + +int foo (struct S *p) +{ + struct S l; + + l = *p; + l.i++; + *p = l; +} + +/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa" } } */ diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-1.c b/gcc/testsuite/gcc.dg/auto-init-uninit-1.c new file mode 100644 index 0000000..502db59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-1.c @@ -0,0 +1,5 @@ +/* Spurious uninitialized variable warnings, case 1. + Taken from cppfiles.c (merge_include_chains) */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-1.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-12.c b/gcc/testsuite/gcc.dg/auto-init-uninit-12.c new file mode 100644 index 0000000..65da110 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-12.c @@ -0,0 +1,4 @@ +/* PR 23497 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-12.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-13.c b/gcc/testsuite/gcc.dg/auto-init-uninit-13.c new file mode 100644 index 0000000..87dd8b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-13.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +typedef _Complex float C; +C foo() +{ + C f; + __imag__ f = 0; + return f; /* { dg-warning "is used" "unconditional" } */ +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-14.c b/gcc/testsuite/gcc.dg/auto-init-uninit-14.c new file mode 100644 index 0000000..9ffe00a --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-14.c @@ -0,0 +1,4 @@ +/* PR 24931 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-14.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-15.c b/gcc/testsuite/gcc.dg/auto-init-uninit-15.c new file mode 100644 index 0000000..121f0cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-15.c @@ -0,0 +1,26 @@ +/* PR tree-optimization/17506 + We issue an uninitialized variable warning at a wrong location at + line 11, which is very confusing. Make sure we print out a note to + make it less confusing. (not xfailed alternative) + But it is of course ok if we warn in bar about uninitialized use + of j. (not xfailed alternative) */ +/* { dg-do compile } */ +/* { dg-options "-O1 -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +inline int +foo (int i) +{ + if (i) /* { dg-warning "used uninitialized" } */ + return 1; + return 0; +} + +void baz (void); + +void +bar (void) +{ + int j; /* { dg-message "note: 'j' was declared here" "" } */ + for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" "" { xfail *-*-* } } */ + baz (); +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-16.c b/gcc/testsuite/gcc.dg/auto-init-uninit-16.c new file mode 100644 index 0000000..38e1950 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-16.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */ +/* -ftrivial-auto-var-init will make the uninitialized warning for address + taken auto var going away, FIXME later. */ + +int foo, bar; + +static +void decode_reloc(int reloc, int *is_alt) +{ + if (reloc >= 20) + *is_alt = 1; + else if (reloc >= 10) + *is_alt = 0; +} + +void testfunc() +{ + int alt_reloc; + + decode_reloc(foo, &alt_reloc); + + if (alt_reloc) /* { dg-warning "may be used uninitialized" "" { xfail *-*-* } } */ + bar = 42; +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-17.c b/gcc/testsuite/gcc.dg/auto-init-uninit-17.c new file mode 100644 index 0000000..9eec944 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-17.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +typedef _Complex float C; +C foo(int cond) +{ + C f; + __imag__ f = 0; + if (cond) + { + __real__ f = 1; + return f; + } + return f; /* { dg-warning "may be used" "unconditional" } */ +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-18.c b/gcc/testsuite/gcc.dg/auto-init-uninit-18.c new file mode 100644 index 0000000..1c9afa9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-18.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-18.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-19.c b/gcc/testsuite/gcc.dg/auto-init-uninit-19.c new file mode 100644 index 0000000..38d27e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-19.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +/* { dg-additional-options "-finline-small-functions" { target avr-*-* } } */ + +int a, l, m; +float *b; +float c, d, e, g, h; +unsigned char i, k; +void +fn1 (int p1, float *f1, float *f2, float *f3, unsigned char *c1, float *f4, + unsigned char *c2, float *p10) +{ + if (p1 & 8) + b[3] = p10[a]; + /* { dg-warning "may be used uninitialized" "" { target { { nonpic || pie_enabled } || { hppa*64*-*-* *-*-darwin* } } } .-1 } */ +} + +void +fn2 () +{ + float *n; + if (l & 6) + n = &c + m; + fn1 (l, &d, &e, &g, &i, &h, &k, n); + /* { dg-warning "may be used uninitialized" "" { target { ! { { nonpic || pie_enabled } || { hppa*64*-*-* *-*-darwin* } } } } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-2.c b/gcc/testsuite/gcc.dg/auto-init-uninit-2.c new file mode 100644 index 0000000..4c32dc8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-2.c @@ -0,0 +1,5 @@ +/* Spurious uninitialized variable warnings, case 2. + Taken from cpphash.c (macroexpand) */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-2.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-20.c b/gcc/testsuite/gcc.dg/auto-init-uninit-20.c new file mode 100644 index 0000000..d81957e --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-20.c @@ -0,0 +1,4 @@ +/* Spurious uninitialized variable warnings, from gdb */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-20.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-21.c b/gcc/testsuite/gcc.dg/auto-init-uninit-21.c new file mode 100644 index 0000000..cc61746 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-21.c @@ -0,0 +1,4 @@ +/* PR69537, spurious warning because of a missed optimization. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-short-enums -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-21.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-22.c b/gcc/testsuite/gcc.dg/auto-init-uninit-22.c new file mode 100644 index 0000000..1e522ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-22.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Wuninitialized --param vect-max-version-for-alias-checks=20 -ftrivial-auto-var-init=zero" } */ +#include "uninit-22.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-23.c b/gcc/testsuite/gcc.dg/auto-init-uninit-23.c new file mode 100644 index 0000000..f1f7839 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-23.c @@ -0,0 +1,27 @@ +/* PR tree-optimization/78455 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +int ij; + +void +ql (void) +{ + int m5 = 0; + + for (;;) + { + if (0) + for (;;) + { + int *go; + int *t4 = go; /* { dg-warning "is used uninitialized" } */ + + l1: + *t4 = (*t4 != 0) ? 0 : 2; /* { dg-warning "is used uninitialized" } */ + } + + if (ij != 0) + goto l1; + } +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-24.c b/gcc/testsuite/gcc.dg/auto-init-uninit-24.c new file mode 100644 index 0000000..0f839ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-24.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-24.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-25.c b/gcc/testsuite/gcc.dg/auto-init-uninit-25.c new file mode 100644 index 0000000..f36d95f --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-25.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */ + +extern unsigned bar (void); +extern void quux (void); + +unsigned foo (unsigned v) +{ + unsigned u; + if (v != 1) + u = bar (); + + // Prevent the "dom" pass from changing the CFG layout based on the inference + // 'if (v != 1) is false then (v != 2) is true'. (Now it would have to + // duplicate the loop in order to do so, which is deemed expensive.) + for (int i = 0; i < 10; i++) + quux (); + + if (v != 2) + return u; /* { dg-warning "may be used uninitialized" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-26.c b/gcc/testsuite/gcc.dg/auto-init-uninit-26.c new file mode 100644 index 0000000..ae97ecf --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-26.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */ + +extern unsigned bar (void); +extern void quux (void); + +unsigned foo (unsigned v) +{ + unsigned u; + if (v != 100) + u = bar (); + + // Prevent the "dom" pass from changing the CFG layout based on the inference + // 'if (v != 100) is false then (v < 105) is true'. (Now it would have to + // duplicate the loop in order to do so, which is deemed expensive.) + for (int i = 0; i < 10; i++) + quux (); + + if (v < 105) /* v == 100 falls into this range. */ + return u; /* { dg-warning "may be used uninitialized" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-3.c b/gcc/testsuite/gcc.dg/auto-init-uninit-3.c new file mode 100644 index 0000000..5c10920 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-3.c @@ -0,0 +1,5 @@ +/* Spurious uninit variable warnings, case 3. + Inspired by cppexp.c (parse_charconst) */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-3.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-34.c b/gcc/testsuite/gcc.dg/auto-init-uninit-34.c new file mode 100644 index 0000000..1a68765 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-34.c @@ -0,0 +1,60 @@ +/* PR middle-end/10138 - warn for uninitialized arrays passed as const* + arguments + Verify that passing pointers to uninitialized objects to arguments + to functions declared with attribute access is diagnosed where expected. + { dg-do compile } + { dg-options "-O -Wall -ftrivial-auto-var-init=zero" } */ +/* -ftrivial-auto-var-init will make the uninitialized warning for address + taken auto var going away, FIXME later. */ + +#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__))) + +RW (1) RW (3) void +f4pi (int*, int*, int*, int*); // { dg-message "in a call to 'f4pi' declared with attribute 'access \\\(read_write, \[13\]\\\)'" } + + +void nowarn_scalar (void) +{ + int i1 = 0, i2, i3 = 1, i4; + f4pi (&i1, &i2, &i3, &i4); +} + +void warn_scalar_1 (void) +{ + int i1; // { dg-message "declared here" "" { xfail *-*-* } } + int i2, i3 = 1, i4; + + f4pi (&i1, &i2, &i3, &i4); // { dg-warning "'i1' may be used uninitialized" "" { xfail *-*-* } } +} + +void warn_scalar_2 (void) +{ + int j1 = 0, j2, j4; + int j3; + + f4pi (&j1, &j2, &j3, &j4); // { dg-warning "'j3' may be used uninitialized" "" { xfail *-*-* } } +} + + +void nowarn_array_init (void) +{ + int a1[4] = { 0 }, a2[5], a3[6] = { 0 }, a4[7]; + + f4pi (a1, a2, a3, a4); +} + +void warn_array_1 (void) +{ + int a1[4]; // { dg-message "'a1' declared here" } + int a2[5], a3[6] = { 0 }, a4[7]; + + f4pi (a1, a2, a3, a4); // { dg-warning "'a1' may be used uninitialized" } +} + +void warn_array_2 (void) +{ + int a1[4] = { 0 }, a2[5], a4[7]; + int a3[6]; // { dg-message "'a3' declared here" } + + f4pi (a1, a2, a3, a4); // { dg-warning "'a3' may be used uninitialized" } +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-36.c b/gcc/testsuite/gcc.dg/auto-init-uninit-36.c new file mode 100644 index 0000000..64377d3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-36.c @@ -0,0 +1,238 @@ +/* PR middle-end/10138 - warn for uninitialized arrays passed as const* + arguments + Verify that passing pointers to uninitialized objects to const + arguments to built-ins is diagnosed where expected. + { dg-do compile } + { dg-options "-O -Wall -ftrivial-auto-var-init=zero" } + { dg-require-effective-target alloca } */ + +typedef __SIZE_TYPE__ size_t; + +void* alloca (size_t); +void* malloc (size_t); +void* realloc (void*, size_t); + +void* memcpy (void*, const void*, size_t); +char* strcpy (char*, const char*); +size_t strlen (const char*); + +void sink (void*); + +void nowarn_array_memcpy (void *d, unsigned n) +{ + int a[2]; + /* Diagnose this? */ + memcpy (d, a, n /* Non-constant to avoid folding into MEM_REF. */); +} + +void nowarn_array_plus_cst_memcpy (void *d, unsigned n) +{ + int a[3]; + /* Diagnose this? */ + memcpy (d, a + 1, n); +} + +void nowarn_array_plus_var_memcpy (void *d, unsigned n, int i) +{ + int a[4]; + /* Diagnose this? */ + memcpy (d, a + i, n); +} + +void nowarn_array_assign_memcpy (char *d, unsigned n) +{ + int a[3]; + a[1] = 3; + memcpy (d, a, n); +} + +void nowarn_array_init_memcpy (char *d, unsigned n) +{ + int a[4] = { 0 }; + memcpy (d, a, n); +} + +void nowarn_array_compound_memcpy (void *d, unsigned n) +{ + memcpy (d, (int[2]){ 0 }, n); +} + +void nowarn_struct_assign_memcpy (void *d, unsigned n) +{ + struct S { int a, b, c, d; } s; + s.b = 1; + s.d = 2; + memcpy (d, &s, n); +} + + +void nowarn_array_init_strcpy (char *d[], unsigned n) +{ + char a[8] = "012"; + + strcpy (d[0], a); + strcpy (d[1], a + 1); + strcpy (d[1], a + 2); + strcpy (d[1], a + 3); + strcpy (d[1], a + 4); + strcpy (d[1], a + 5); + strcpy (d[1], a + 6); + strcpy (d[1], a + 7); +} + + +void nowarn_array_assign_strcpy (char *d[], unsigned n) +{ + char a[8]; + a[0] = '0'; + a[1] = '1'; + a[2] = '2'; + a[3] = '\0'; + + strcpy (d[0], a); + strcpy (d[1], a + 1); + strcpy (d[1], a + 2); + strcpy (d[1], a + 3); +} + +void warn_array_plus_cst_strcpy (char *d, unsigned n) +{ + char a[8]; + a[0] = '1'; + a[1] = '2'; + a[2] = '3'; + a[3] = '\0'; + + strcpy (d, a + 4); // { dg-warning "\\\[-Wuninitialized" } + strcpy (d, a + 5); // { dg-warning "\\\[-Wuninitialized" } + strcpy (d, a + 6); // { dg-warning "\\\[-Wuninitialized" } + strcpy (d, a + 7); // { dg-warning "\\\[-Wuninitialized" } +} + +void nowarn_array_plus_var_strcpy (char *d, int i) +{ + char a[8]; + a[0] = '1'; + a[1] = '2'; + a[2] = '3'; + a[3] = '\0'; + + strcpy (d, a + i); +} + + +size_t nowarn_array_assign_strlen (const char *s) +{ + char a[8]; + a[0] = s[0]; + a[1] = s[1]; + a[2] = s[2]; + a[3] = s[3]; + + size_t n = 0; + + n += strlen (a); + n += strlen (a + 1); + n += strlen (a + 2); + n += strlen (a + 3); + return n; +} + +size_t warn_array_plus_cst_strlen (const char *s) +{ + char a[8]; + a[0] = s[0]; + a[1] = s[1]; + a[2] = s[2]; + a[3] = s[3]; + + return strlen (a + 4); // { dg-warning "\\\[-Wuninitialized" } +} + +size_t nowarn_array_plus_var_strlen (const char *s, int i) +{ + char a[8]; + a[0] = s[0]; + a[1] = s[1]; + a[2] = s[2]; + a[3] = s[3]; + + return strlen (a + i); +} + + +size_t nowarn_alloca_assign_strlen (int i) +{ + char *p = (char*)alloca (8); + p[i] = '\0'; + return strlen (p); +} + +size_t nowarn_alloca_escape_strlen (int i) +{ + char *p = (char*)alloca (8); + sink (p); + return strlen (p); +} + +size_t warn_alloca_strlen (void) +{ + char *p = (char*)alloca (8); + return strlen (p); // { dg-warning "\\\[-Wuninitialized" } +} + + +size_t nowarn_malloc_assign_strlen (int i) +{ + char *p = (char*)malloc (8); + p[i] = '\0'; + return strlen (p); +} + +size_t nowarn_malloc_escape_strlen (int i) +{ + char *p = (char*)malloc (8); + sink (p); + return strlen (p); +} + +size_t warn_malloc_strlen (void) +{ + char *p = (char*)malloc (8); + return strlen (p); // { dg-warning "\\\[-Wuninitialized" } +} + + +size_t nowarn_realloc_strlen (void *p) +{ + char *q = (char*)realloc (p, 8); + return strlen (q); +} + + +size_t nowarn_vla_assign_strlen (int n, int i) +{ + char vla[n]; + vla[i] = '\0'; + return strlen (vla); +} + +size_t nowarn_vla_strcpy_strlen (int n, const char *s, int i) +{ + char vla[n]; + strcpy (vla, s); + return strlen (vla + i); +} + +size_t nowarn_vla_escape_strlen (int n, int i) +{ + char vla[n]; + sink (vla); + return strlen (vla); +} + +size_t warn_vla_strlen (unsigned n) +{ + char vla[n]; + return strlen (vla); // { dg-warning "\\\[-Wuninitialized" } +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-37.c b/gcc/testsuite/gcc.dg/auto-init-uninit-37.c new file mode 100644 index 0000000..2791b37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-37.c @@ -0,0 +1,156 @@ +/* PR middle-end/10138 - warn for uninitialized arrays passed as const arguments + Verify that -Wuninitialized and -Wmaybe-uninitialized trigger (or don't) + when passing uninitialized variables by reference to functions declared + with or without attribute access and with (or without) const qualified + arguments of array, VLA, or pointer types. + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0 -ftrivial-auto-var-init=zero" } */ +/* -ftrivial-auto-var-init will make the uninitialized warning for address + taken auto var going away, FIXME later. */ + +#define NONE /* none */ +#define RO(...) __attribute__ ((access (read_only, __VA_ARGS__))) +#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__))) +#define WO(...) __attribute__ ((access (write_only, __VA_ARGS__))) +#define X(...) __attribute__ ((access (none, __VA_ARGS__))) + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define UNIQ(pfx) CAT (pfx, __LINE__) + +extern void sink (void*); + + +#define T1(attr, name, type) \ + void UNIQ (CAT (test_, name))(void) { \ + extern attr void UNIQ (name)(type); \ + int x; \ + UNIQ (name)(&x); \ + sink (&x); \ + } + +#define T2(attr, name, types) \ + void UNIQ (CAT (test_, name))(void) { \ + extern attr void UNIQ (name)(types); \ + int x; \ + UNIQ (name)(1, &x); \ + sink (&x); \ + } + + +typedef int IA_[]; +typedef const int CIA_[]; + +T1 (NONE, fia_, IA_); +T1 (NONE, fcia_, CIA_); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (RO (1), froia_, IA_); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T1 (RW (1), frwia_, IA_); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (WO (1), fwoia_, IA_); +T1 (X (1), fxia_, IA_); + + +typedef int IA1[1]; +typedef const int CIA1[1]; + +T1 (NONE, fia1, IA1); +T1 (NONE, fcia1, CIA1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (RO (1), froia1, IA1); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T1 (RW (1), frwia1, IA1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (WO (1), fwoia1, IA1); +T1 (X (1), fxia1, IA1); + + +#define IARS1 int[restrict static 1] +#define CIARS1 const int[restrict static 1] + +T1 (NONE, fiars1, IARS1); +T1 (NONE, fciars1, CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (WO (1), fwoiars1, IARS1); +T1 (X (1), fxiars1, IARS1); + + +#define IAS1 int[static 1] +#define CIAS1 const int[static 1] + +T1 (NONE, fias1, IAS1); +T1 (NONE, fcias1, CIAS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (RO (1), froias1, IAS1); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T1 (RW (1), frwias1, IAS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (WO (1), fwoias1, IAS1); +T1 (X (1), fxias1, IAS1); + + +#define IAX int[*] +#define CIAX const int[*] + +T1 (NONE, fiax, IAX); +T1 (NONE, fciax, CIAX); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (RO (1), froiax, IAX); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T1 (RW (1), frwiax, IAX); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (WO (1), fwoiax, IAX); +T1 (X (1), fxiax, IAX); + + +#define IAN int n, int[n] +#define CIAN int n, const int[n] + +T2 (NONE, fian, IAN); +T2 (NONE, fcian, CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T2 (RO (2, 1), froian, IAN); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T2 (RW (2, 1), frwian, IAN); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T2 (WO (2, 1), fwoian, IAN); +T2 (X (2, 1), fxian, IAN); + + +typedef int* IP; +typedef const int* CIP; + +T1 (NONE, fip, IP); +T1 (NONE, fcip, CIP); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (RO (1), froip, IP); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } } +T1 (RW (1), frwip, IP); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } } +T1 (WO (1), fwoip, IP); +T1 (X (1), fxip, IP); + + +/* Verify that the notes printed after the warning mention attribute + access only when the attribute is explicitly used in the declaration + and not otherwise. */ + +void test_note_cst_restrict (void) +{ + extern void + fccar (const char[restrict]); // { dg-message "by argument 1 of type 'const char\\\[restrict]' to 'fccar'" "note" } + + char a[1]; // { dg-message "'a' declared here" "note" } + fccar (a); // { dg-warning "'a' may be used uninitialized" } +} + +void test_note_vla (int n) +{ + extern void + fccvla (const char[n]); // { dg-message "by argument 1 of type 'const char\\\[n]' to 'fccvla'" "note" } + + char a[2]; // { dg-message "'a' declared here" "note" } + fccvla (a); // { dg-warning "'a' may be used uninitialized" } +} + +void test_note_ro (void) +{ + extern RO (1) void + frocar (char[restrict]); // { dg-message "in a call to 'frocar' declared with attribute 'access \\\(read_only, 1\\\)'" "note" } + + char a[3]; // { dg-message "'a' declared here" "note" } + frocar (a); // { dg-warning "'a' is used uninitialized" } +} + +void test_note_rw (void) +{ + extern RW (1) void + frwcar (char[restrict]); // { dg-message "in a call to 'frwcar' declared with attribute 'access \\\(read_write, 1\\\)'" "note" } + + char a[4]; // { dg-message "'a' declared here" "note" } + frwcar (a); // { dg-warning "'a' may be used uninitialized" } +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-4.c b/gcc/testsuite/gcc.dg/auto-init-uninit-4.c new file mode 100644 index 0000000..29ec860 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-4.c @@ -0,0 +1,10 @@ +/* Spurious uninit variable warnings, case 4. + Simplified version of cppexp.c (cpp_parse_expr). + + This one is really fragile, it gets it right if you take out case + 1, or if the structure is replaced by an int, or if the structure + has fewer members (!) */ + +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-4.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-5.c b/gcc/testsuite/gcc.dg/auto-init-uninit-5.c new file mode 100644 index 0000000..65b251a --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-5.c @@ -0,0 +1,6 @@ +/* Spurious uninitialized-variable warnings. */ +/* Disable jump threading, etc to test compiler analysis. */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -fno-tree-dce -fno-tree-vrp -fno-tree-dominator-opts -ftrivial-auto-var-init=zero" } */ + +#include "uninit-5.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-6.c b/gcc/testsuite/gcc.dg/auto-init-uninit-6.c new file mode 100644 index 0000000..7c10dfc --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-6.c @@ -0,0 +1,7 @@ +/* Spurious uninitialized variable warnings. + This one inspired by java/class.c:build_utf8_ref. */ + +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +#include "uninit-6.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-8.c b/gcc/testsuite/gcc.dg/auto-init-uninit-8.c new file mode 100644 index 0000000..eaa9c0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-8.c @@ -0,0 +1,8 @@ +/* Uninitialized variable warning tests... + Inspired by part of optabs.c:expand_binop. + May be the same as uninit-1.c. */ + +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +#include "uninit-8.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-9.c b/gcc/testsuite/gcc.dg/auto-init-uninit-9.c new file mode 100644 index 0000000..6dccf01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-9.c @@ -0,0 +1,8 @@ +/* Spurious uninitialized variable warnings. Slight variant on the + documented case, inspired by reg-stack.c:record_asm_reg_life. */ + +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +/* { dg-require-effective-target alloca } */ + +#include "uninit-9.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-A.c b/gcc/testsuite/gcc.dg/auto-init-uninit-A.c new file mode 100644 index 0000000..0ef1d92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-A.c @@ -0,0 +1,7 @@ +/* Inspired by part of java/parse.y. + May be a real bug in CSE. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -ftrivial-auto-var-init=zero" } */ + +#include "uninit-A.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-B.c b/gcc/testsuite/gcc.dg/auto-init-uninit-B.c new file mode 100644 index 0000000..b6d3efd --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-B.c @@ -0,0 +1,17 @@ +/* Origin: PR c/179 from Gray Watson , adapted as a testcase + by Joseph Myers . */ +/* -ftrivial-auto-var-init will make the uninitialized warning for address + taken auto var going away, FIXME later. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */ +extern void foo (int *); +extern void bar (int); + +void +baz (void) +{ + int i; + if (i) /* { dg-warning "is used uninitialized" "uninit i warning" { xfail *-*-* } } */ + bar (i); + foo (&i); +} diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-C.c b/gcc/testsuite/gcc.dg/auto-init-uninit-C.c new file mode 100644 index 0000000..be19796 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-C.c @@ -0,0 +1,5 @@ +/* Spurious uninitialized variable warning, inspired by libgcc2.c. */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ + +#include "uninit-C.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-H.c b/gcc/testsuite/gcc.dg/auto-init-uninit-H.c new file mode 100644 index 0000000..e442fab --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-H.c @@ -0,0 +1,5 @@ +/* PR 14204 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wall -Werror -ftrivial-auto-var-init=zero" } */ + +#include "uninit-H.c" diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-I.c b/gcc/testsuite/gcc.dg/auto-init-uninit-I.c new file mode 100644 index 0000000..4f9ae6c --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-uninit-I.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */ +#include "uninit-H.c" -- cgit v1.1 From 1dae802b685937b1dc52e49d0641c75f3186ba14 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 10 Sep 2021 10:17:24 +0200 Subject: middle-end/102269 - avoid auto-init of empty types This avoids initializing empty types for which we'll eventually leave a .DEFERRED_INIT call without a LHS. 2021-09-10 Richard Biener PR middle-end/102269 * gimplify.c (is_var_need_auto_init): Empty types do not need initialization. * gcc.dg/pr102269.c: New testcase. --- gcc/testsuite/gcc.dg/pr102269.c | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr102269.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr102269.c b/gcc/testsuite/gcc.dg/pr102269.c new file mode 100644 index 0000000..9d41b8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102269.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-ftrivial-auto-var-init=zero" } */ + +void fn() { int a[0]; } -- cgit v1.1 From 79f488de3036a4a4be08df2a782e6eb02419db19 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 10 Sep 2021 12:28:09 +0200 Subject: middle-end/102273 - avoid ICE with auto-init and nested functions This refactors expansion to consider non-decl LHS. I suspect the is_val argument is not needed. 2021-09-10 Richard Biener PR middle-end/102273 * internal-fn.c (expand_DEFERRED_INIT): Always expand non-SSA vars. * gcc.dg/pr102273.c: New testcase. --- gcc/testsuite/gcc.dg/pr102273.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr102273.c (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/pr102273.c b/gcc/testsuite/gcc.dg/pr102273.c new file mode 100644 index 0000000..568e44e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102273.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-ftrivial-auto-var-init=zero" } */ + +void bar(); + +struct A { char d; }; +void foo() +{ + struct A e; + void baz() { bar(e); } +} -- cgit v1.1 From 01b5038718056b024b370b74a874fbd92c5bbab3 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 9 Sep 2021 20:30:28 +0200 Subject: Disable threading through latches until after loop optimizations. The motivation for this patch was enabling the use of global ranges in the path solver, but this caused certain properties of loops being destroyed which made subsequent loop optimizations to fail. Consequently, this patch's mail goal is to disable jump threading involving the latch until after loop optimizations have run. As can be seen in the test adjustments, we mostly shift the threading from the early threaders (ethread, thread[12] to the late threaders thread[34]). I have nuked some of the early notes in the testcases that came as part of the jump threader rewrite. They're mostly noise now. Note that we could probably relax some other restrictions in profitable_path_p when loop optimizations have completed, but it would require more testing, and I'm hesitant to touch more things than needed at this point. I have added a reminder to the function to keep this in mind. Finally, perhaps as a follow-up, we should apply the same restrictions to the forward threader. At some point I'd like to combine the cost models. Tested on x86-64 Linux. p.s. There is a thorough discussion involving the limitations of jump threading involving loops here: https://gcc.gnu.org/pipermail/gcc/2021-September/237247.html gcc/ChangeLog: * tree-pass.h (PROP_loop_opts_done): New. * gimple-range-path.cc (path_range_query::internal_range_of_expr): Intersect with global range. * tree-ssa-loop.c (tree_ssa_loop_done): Set PROP_loop_opts_done. * tree-ssa-threadbackward.c (back_threader_profitability::profitable_path_p): Disable threading through latches until after loop optimizations have run. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/ssa-dom-thread-2b.c: Adjust for disabling of threading through latches. * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Same. Co-authored-by: Michael Matz --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c | 4 +-- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c | 37 ++--------------------- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 17 +---------- 3 files changed, 5 insertions(+), 53 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c index e1c33e8..823ada9 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-dom2-stats -fdisable-tree-ethread" } */ +/* { dg-options "-O2 -fdump-tree-thread3-stats -fdump-tree-dom2-stats -fdisable-tree-ethread" } */ void foo(); void bla(); @@ -26,4 +26,4 @@ void thread_latch_through_header (void) case. And we want to thread through the header as well. These are both caught by threading in DOM. */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom2"} } */ -/* { dg-final { scan-tree-dump-times "Jumps threaded: 1" 1 "thread1"} } */ +/* { dg-final { scan-tree-dump-times "Jumps threaded: 1" 1 "thread3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c index c7bf867..ee46759 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c @@ -1,41 +1,8 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread2-details" } */ +/* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread3-details" } */ -/* All the threads in the thread1 dump start on a X->BB12 edge, as can - be seen in the dump: - - Registering FSM jump thread: (x, 12) incoming edge; ... - etc - etc - - Before the new evrp, we were threading paths that started at the - following edges: - - Registering FSM jump thread: (10, 12) incoming edge - Registering FSM jump thread: (6, 12) incoming edge - Registering FSM jump thread: (9, 12) incoming edge - - This was because the PHI at BB12 had constant values coming in from - BB10, BB6, and BB9: - - # state_10 = PHI - - Now with the new evrp, we get: - - # state_10 = PHI <0(7), 0(10), state_11(5), 1(6), 0(8), 2(9), 1(11)> - - Thus, we have 3 more paths that are known to be constant and can be - threaded. Which means that by the second threading pass, we can - only find one profitable path. - - For the record, all these extra constants are better paths coming - out of switches. For example: - - SWITCH_BB -> BBx -> BBy -> BBz -> PHI - - We now know the value of the switch index at PHI. */ /* { dg-final { scan-tree-dump-times "Registering FSM jump" 6 "thread1" } } */ -/* { dg-final { scan-tree-dump-times "Registering FSM jump" 1 "thread2" } } */ +/* { dg-final { scan-tree-dump-times "Registering FSM jump" 1 "thread3" } } */ int sum0, sum1, sum2, sum3; int foo (char *s, char **ret) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index 5fc2145..ba07942 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -1,23 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-dom2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */ -/* Here we have the same issue as was commented in ssa-dom-thread-6.c. - The PHI coming into the threader has a lot more constants, so the - threader can thread more paths. - -$ diff clean/a.c.105t.mergephi2 a.c.105t.mergephi2 -252c252 -< # s_50 = PHI ---- -> # s_50 = PHI -272a273 - - I spot checked a few and they all have the same pattern. We are - basically tracking the switch index better through multiple - paths. */ - /* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread1" } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread3" } } */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom2" } } */ /* aarch64 has the highest CASE_VALUES_THRESHOLD in GCC. It's high enough -- cgit v1.1 From 8122fbff770bcff183a9c3c72e8092c0ca32150b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 10 Sep 2021 20:41:33 +0200 Subject: openmp: Implement OpenMP 5.1 atomics, so far for C only This patch implements OpenMP 5.1 atomics (with clarifications from upcoming 5.2). The most important changes are that it is now possible to write (for C/C++, for Fortran it was possible before already) min/max atomics and more importantly compare and exchange in various forms. Also, acq_rel is now allowed on read/write and acq_rel/acquire are allowed on update, and there are new compare, weak and fail clauses. 2021-09-10 Jakub Jelinek gcc/ * tree-core.h (enum omp_memory_order): Add OMP_MEMORY_ORDER_MASK, OMP_FAIL_MEMORY_ORDER_UNSPECIFIED, OMP_FAIL_MEMORY_ORDER_RELAXED, OMP_FAIL_MEMORY_ORDER_ACQUIRE, OMP_FAIL_MEMORY_ORDER_RELEASE, OMP_FAIL_MEMORY_ORDER_ACQ_REL, OMP_FAIL_MEMORY_ORDER_SEQ_CST and OMP_FAIL_MEMORY_ORDER_MASK enumerators. (OMP_FAIL_MEMORY_ORDER_SHIFT): Define. * gimple-pretty-print.c (dump_gimple_omp_atomic_load, dump_gimple_omp_atomic_store): Print [weak] for weak atomic load/store. * gimple.h (enum gf_mask): Change GF_OMP_ATOMIC_MEMORY_ORDER to 6-bit mask, adjust GF_OMP_ATOMIC_NEED_VALUE value and add GF_OMP_ATOMIC_WEAK. (gimple_omp_atomic_weak_p, gimple_omp_atomic_set_weak): New inline functions. * tree.h (OMP_ATOMIC_WEAK): Define. * tree-pretty-print.c (dump_omp_atomic_memory_order): Adjust for fail memory order being encoded in the same enum and also print fail clause if present. (dump_generic_node): Print weak clause if OMP_ATOMIC_WEAK. * gimplify.c (goa_stabilize_expr): Add target_expr and rhs arguments, handle pre_p == NULL case as a test mode that only returns value but doesn't change gimplify nor change anything otherwise, adjust recursive calls, add MODIFY_EXPR, ADDR_EXPR, COND_EXPR, TARGET_EXPR and CALL_EXPR handling, adjust COMPOUND_EXPR handling for __builtin_clear_padding calls, for !rhs gimplify as lvalue rather than rvalue. (gimplify_omp_atomic): Adjust goa_stabilize_expr caller. Handle COND_EXPR rhs. Set weak flag on gimple load/store for OMP_ATOMIC_WEAK. * omp-expand.c (omp_memory_order_to_fail_memmodel): New function. (omp_memory_order_to_memmodel): Adjust for fail clause encoded in the same enum. (expand_omp_atomic_cas): New function. (expand_omp_atomic_pipeline): Use omp_memory_order_to_fail_memmodel function. (expand_omp_atomic): Attempt to optimize atomic compare and exchange using expand_omp_atomic_cas. gcc/c-family/ * c-common.h (c_finish_omp_atomic): Add r and weak arguments. * c-omp.c: Include gimple-fold.h. (c_finish_omp_atomic): Add r and weak arguments. Add support for OpenMP 5.1 atomics. gcc/c/ * c-parser.c (c_parser_conditional_expression): If omp_atomic_lhs and cond.value is >, < or == with omp_atomic_lhs as one of the operands, don't call build_conditional_expr, instead build a COND_EXPR directly. (c_parser_binary_expression): Avoid calling parser_build_binary_op if omp_atomic_lhs even in more cases for >, < or ==. (c_parser_omp_atomic): Update function comment for OpenMP 5.1 atomics, parse OpenMP 5.1 atomics and fail, compare and weak clauses, allow acq_rel on atomic read/write and acq_rel/acquire clauses on update. * c-typeck.c (build_binary_op): For flag_openmp only handle MIN_EXPR/MAX_EXPR. gcc/cp/ * parser.c (cp_parser_omp_atomic): Allow acq_rel on atomic read/write and acq_rel/acquire clauses on update. * semantics.c (finish_omp_atomic): Adjust c_finish_omp_atomic caller. gcc/testsuite/ * c-c++-common/gomp/atomic-17.c (foo): Add tests for atomic read, write or update with acq_rel clause and atomic update with acquire clause. * c-c++-common/gomp/atomic-18.c (foo): Adjust expected diagnostics wording, remove tests moved to atomic-17.c. * c-c++-common/gomp/atomic-21.c: Expect only 2 omp atomic release and 2 omp atomic acq_rel directives instead of 4 omp atomic release. * c-c++-common/gomp/atomic-25.c: New test. * c-c++-common/gomp/atomic-26.c: New test. * c-c++-common/gomp/atomic-27.c: New test. * c-c++-common/gomp/atomic-28.c: New test. * c-c++-common/gomp/atomic-29.c: New test. * c-c++-common/gomp/atomic-30.c: New test. * c-c++-common/goacc-gomp/atomic.c: Expect 1 omp atomic release and 1 omp atomic_acq_rel instead of 2 omp atomic release directives. * gcc.dg/gomp/atomic-5.c: Adjust expected error diagnostic wording. * g++.dg/gomp/atomic-18.C:Expect 4 omp atomic release and 1 omp atomic_acq_rel instead of 5 omp atomic release directives. libgomp/ * testsuite/libgomp.c-c++-common/atomic-19.c: New test. * testsuite/libgomp.c-c++-common/atomic-20.c: New test. * testsuite/libgomp.c-c++-common/atomic-21.c: New test. --- gcc/testsuite/gcc.dg/gomp/atomic-5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-5.c b/gcc/testsuite/gcc.dg/gomp/atomic-5.c index 70cfb35..36d1422 100644 --- a/gcc/testsuite/gcc.dg/gomp/atomic-5.c +++ b/gcc/testsuite/gcc.dg/gomp/atomic-5.c @@ -27,7 +27,7 @@ void f1(void) #pragma omp atomic bar() += 1; /* { dg-error "lvalue required" } */ #pragma omp atomic a /* { dg-error "expected end of line" } */ - x++; /* { dg-error "expected 'read', 'write', 'update', 'capture', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" "" { target *-*-* } .-1 } */ + x++; /* { dg-error "expected 'read', 'write', 'update', 'capture', 'compare', 'weak', 'fail', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" "" { target *-*-* } .-1 } */ #pragma omp atomic ; /* { dg-error "expected expression" } */ #pragma omp atomic -- cgit v1.1 From a7f59856ea8ea02d6f09d2e9e793ce2800ebbe4b Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Mon, 13 Sep 2021 14:25:15 +0200 Subject: Adjust ssa-dom-thread-7.c on aarch64. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust for aarch64. --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index ba07942..e3d4b31 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -2,7 +2,7 @@ /* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-dom2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */ /* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread1" } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread3" } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread3" { target { ! aarch64*-*-* } } } } */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom2" } } */ /* aarch64 has the highest CASE_VALUES_THRESHOLD in GCC. It's high enough -- cgit v1.1 From c7a669af0aeb639eb78f1614cbecb72a98d81ce8 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Sat, 11 Sep 2021 17:33:25 +0200 Subject: Remove references to FSM threads. Now that the jump thread back registry has been split into the generic copier and the custom (old) copier, it becomes trivial to remove the FSM bits from the jump threaders. First, there's no need for an EDGE_FSM_THREAD type. The only reason we were looking at the threading type was to determine what type of copier to use, and now that the copier has been split, there's no need to even look. However, there is one check in register_jump_thread where we verify that only the generic copier can thread through back-edges. I've removed that check in favor of a flag passed to the constructor. I've also removed all the FSM references from the code and tests. Interestingly, some tests weren't even testing the right thing. They were testing for "FSM" which would catch jump thread paths as well as the backward threader *failing* on registering a path. *big eye roll* The only remaining code that was actually checking for EDGE_FSM_THREAD was adjust_paths_after_duplication, and the checks could be written without looking at the edge type at all. For the record, the code there is horrible: it's convoluted, hard to read, and doesn't have any tests. I'd smack myself if I could go back in time. All that remains are the FSM references in the --param's themselves. I think we should s/fsm/threader/, since I envision a day when we can share the cost basis code between the threaders. However, I don't know what the proper procedure is for renaming existing compiler options. By the way, param_fsm_maximum_phi_arguments is no longer relevant after the rewrite. We can nuke that one right away. Tested on x86-64 Linux. gcc/ChangeLog: * tree-ssa-threadbackward.c (back_threader_profitability::profitable_path_p): Remove FSM references. (back_threader_registry::register_path): Same. * tree-ssa-threadedge.c (jump_threader::simplify_control_stmt_condition): Same. * tree-ssa-threadupdate.c (jt_path_registry::jt_path_registry): Add backedge_threads argument. (fwd_jt_path_registry::fwd_jt_path_registry): Pass backedge_threads argument. (back_jt_path_registry::back_jt_path_registry): Same. (dump_jump_thread_path): Adjust for FSM removal. (back_jt_path_registry::rewire_first_differing_edge): Same. (back_jt_path_registry::adjust_paths_after_duplication): Same. (back_jt_path_registry::update_cfg): Same. (jt_path_registry::register_jump_thread): Same. * tree-ssa-threadupdate.h (enum jump_thread_edge_type): Remove EDGE_FSM_THREAD. (class back_jt_path_registry): Add backedge_threads to constructor. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr21417.c: Adjust for FSM removal. * gcc.dg/tree-ssa/pr66752-3.c: Same. * gcc.dg/tree-ssa/pr68198.c: Same. * gcc.dg/tree-ssa/pr69196-1.c: Same. * gcc.dg/tree-ssa/pr70232.c: Same. * gcc.dg/tree-ssa/pr77445.c: Same. * gcc.dg/tree-ssa/ranger-threader-4.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-18.c: Same. * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Same. * gcc.dg/tree-ssa/ssa-thread-12.c: Same. * gcc.dg/tree-ssa/ssa-thread-13.c: Same. --- gcc/testsuite/gcc.dg/tree-ssa/pr21417.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/pr68198.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr70232.c | 12 ++++++------ gcc/testsuite/gcc.dg/tree-ssa/pr77445.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c | 7 +++---- gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c | 2 +- 11 files changed, 21 insertions(+), 22 deletions(-) (limited to 'gcc/testsuite/gcc.dg') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c index fc14af4..b934c9c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c @@ -49,5 +49,5 @@ L23: /* We should thread the backedge to the top of the loop; ie we only execute the if (expr->common.code != 142) test once per loop iteration. */ -/* { dg-final { scan-tree-dump-times "FSM jump thread" 1 "thread4" } } */ +/* { dg-final { scan-tree-dump-times "jump thread" 1 "thread4" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c index 896c8bf..e1464e2 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c @@ -32,9 +32,9 @@ foo (int N, int c, int b, int *a) pt--; } -/* There are 4 FSM jump threading opportunities, all of which will be +/* There are 4 jump threading opportunities, all of which will be realized, which will eliminate testing of FLAG, completely. */ -/* { dg-final { scan-tree-dump-times "Registering FSM" 4 "thread1"} } */ +/* { dg-final { scan-tree-dump-times "Registering jump" 4 "thread1"} } */ /* There should be no assignments or references to FLAG, verify they're eliminated as early as possible. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c index 59d562e..af8b7a5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c @@ -37,5 +37,5 @@ c_finish_omp_clauses (tree clauses) } } -/* There are 3 FSM jump threading opportunities. */ -/* { dg-final { scan-tree-dump-times "Registering FSM" 3 "thread1"} } */ +/* There are 3 jump threading opportunities. */ +/* { dg-final { scan-tree-dump-times "Registering jump" 3 "thread1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c index 960491f..dfabb48 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c @@ -1,7 +1,7 @@ /* { dg-do compile { target sparc*-*-* i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -fdump-tree-thread1-details -fdisable-tree-ethread" } */ -/* { dg-final { scan-tree-dump "FSM did not thread around loop and would copy too many statements" "thread1" } } */ +/* { dg-final { scan-tree-dump "Did not thread around loop and would copy too many statements" "thread1" } } */ typedef __builtin_va_list __gnuc_va_list; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr70232.c b/gcc/testsuite/gcc.dg/tree-ssa/pr70232.c index 6cc987a..d636672 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr70232.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr70232.c @@ -1,12 +1,12 @@ /* { dg-do compile } */ /* { dg-options "-O2 -w -fdump-tree-vrp1-details -fdump-tree-vrp2-details -fdump-tree-dom2-details -fdump-tree-dom3-details" } */ -/* All the threads found by the FSM threader should have too - many statements to be profitable. */ -/* { dg-final { scan-tree-dump-not "Registering FSM " "dom2"} } */ -/* { dg-final { scan-tree-dump-not "Registering FSM " "dom3"} } */ -/* { dg-final { scan-tree-dump-not "Registering FSM " "vrp1"} } */ -/* { dg-final { scan-tree-dump-not "Registering FSM " "vrp2"} } */ +/* All the threads found by the threader should have too many + statements to be profitable. */ +/* { dg-final { scan-tree-dump-not "Registering jump " "dom2"} } */ +/* { dg-final { scan-tree-dump-not "Registering jump " "dom3"} } */ +/* { dg-final { scan-tree-dump-not "Registering jump " "vrp1"} } */ +/* { dg-final { scan-tree-dump-not "Registering jump " "vrp2"} } */ typedef _Bool bool; typedef unsigned char uint8_t; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr77445.c b/gcc/testsuite/gcc.dg/tree-ssa/pr77445.c index 98eb0f2..883a63d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr77445.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr77445.c @@ -25,5 +25,5 @@ main (int argc) if (b) test2 (); } -/* { dg-final { scan-tree-dump-times "Registering FSM jump thread" 2 "thread3" } } */ +/* { dg-final { scan-tree-dump-times "Registering jump thread" 2 "thread3" } } */ /* { dg-final { scan-tree-dump-not "Invalid sum" "thread3" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c index e8d1cfc..d5aa2e8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ranger-threader-4.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-additional-options "-O2 -fdump-tree-vrp-details -fdump-tree-thread1-details --param logical-op-non-short-circuit=1" } */ -/* { dg-final { scan-tree-dump-times "Registering FSM jump" 8 "thread1" } } */ +/* { dg-final { scan-tree-dump-times "Registering jump" 8 "thread1" } } */ /* Copied from ssa-thread-14. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c index 03872e7..60d4f76 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-18.c @@ -21,5 +21,5 @@ condition. All the cases are picked up by VRP1 as jump threads. */ -/* { dg-final { scan-tree-dump-times "Registering FSM jump" 6 "thread1" } } */ +/* { dg-final { scan-tree-dump-times "Registering jump" 6 "thread1" } } */ /* { dg-final { scan-tree-dump-times "Threaded" 2 "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c index ee46759..b0a7d42 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread3-details" } */ -/* { dg-final { scan-tree-dump-times "Registering FSM jump" 6 "thread1" } } */ -/* { dg-final { scan-tree-dump-times "Registering FSM jump" 1 "thread3" } } */ +/* { dg-final { scan-tree-dump-times "Registering jump" 6 "thread1" } } */ +/* { dg-final { scan-tree-dump-times "Registering jump" 1 "thread3" } } */ int sum0, sum1, sum2, sum3; int foo (char *s, char **ret) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c index 8f55464..08c0b8d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c @@ -1,8 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-thread2-details -fdump-tree-thread3-details -fdump-tree-thread4-details -fno-finite-loops --param early-inlining-insns=14 -fno-inline-functions" } */ -/* { dg-final { scan-tree-dump "FSM" "thread2" } } */ -/* { dg-final { scan-tree-dump "FSM" "thread3" } } */ -/* { dg-final { scan-tree-dump "FSM" "thread4" } } */ +/* { dg-options "-O2 -fdump-tree-thread3-details -fdump-tree-thread4-details -fno-finite-loops --param early-inlining-insns=14 -fno-inline-functions" } */ +/* { dg-final { scan-tree-dump "Registering jump thread" "thread3" } } */ +/* { dg-final { scan-tree-dump "Registering jump thread" "thread4" } } */ typedef struct bitmap_head_def *bitmap; typedef const struct bitmap_head_def *const_bitmap; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c index 061f223..ad38b89 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-ethread-details" } */ -/* { dg-final { scan-tree-dump "FSM" "ethread" } } */ +/* { dg-final { scan-tree-dump "Registering jump thread" "ethread" } } */ typedef struct rtx_def *rtx; typedef const struct rtx_def *const_rtx; -- cgit v1.1