summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2023-04-20 13:10:40 -0400
committerJakub Jelinek <jakub@redhat.com>2023-04-21 08:20:25 +0200
commitf980561c60b0446cc427595198d7f3f4f90e0924 (patch)
tree6f2efdff08db086fcedca39a8417b0446bf0c398
parente841eee33087d45b04a5b51232d6f4b3ff150148 (diff)
downloadgcc-f980561c60b0446cc427595198d7f3f4f90e0924.tar.gz
Do not ignore UNDEFINED ranges when determining PHI equivalences.
Do not ignore UNDEFINED name arguments when registering two-way equivalences from PHIs. PR tree-optimization/109564 gcc/ * gimple-range-fold.cc (fold_using_range::range_of_phi): Do no ignore UNDEFINED range names when deciding if all PHI arguments are the same, gcc/testsuite/ * gcc.dg/torture/pr109564-1.c: New testcase. * gcc.dg/torture/pr109564-2.c: Likewise. * gcc.dg/tree-ssa/evrp-ignore.c: XFAIL. * gcc.dg/tree-ssa/vrp06.c: Likewise. (cherry picked from commit 17aa9ddb34581855dd013745c8be27dda024de4a)
-rw-r--r--gcc/gimple-range-fold.cc16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr109564-1.c74
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr109564-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp-ignore.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp06.c2
5 files changed, 117 insertions, 10 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 429734f954a..180f349eda9 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -771,16 +771,16 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src)
if (gimple_range_ssa_p (arg) && src.gori ())
src.gori ()->register_dependency (phi_def, arg);
+ }
- // Track if all arguments are the same.
- if (!seen_arg)
- {
- seen_arg = true;
- single_arg = arg;
- }
- else if (single_arg != arg)
- single_arg = NULL_TREE;
+ // Track if all arguments are the same.
+ if (!seen_arg)
+ {
+ seen_arg = true;
+ single_arg = arg;
}
+ else if (single_arg != arg)
+ single_arg = NULL_TREE;
// Once the value reaches varying, stop looking.
if (r.varying_p () && single_arg == NULL_TREE)
diff --git a/gcc/testsuite/gcc.dg/torture/pr109564-1.c b/gcc/testsuite/gcc.dg/torture/pr109564-1.c
new file mode 100644
index 00000000000..e7c855f1edf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr109564-1.c
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+struct libkeccak_spec {
+ long int bitrate;
+};
+
+struct libkeccak_generalised_spec {
+ long int bitrate;
+ long int state_size;
+ long int word_size;
+};
+
+int __attribute__((noipa))
+libkeccak_degeneralise_spec(struct libkeccak_generalised_spec *restrict spec,
+ struct libkeccak_spec *restrict output_spec)
+{
+ long int state_size, word_size, bitrate, output;
+ const int have_state_size = spec->state_size != (-65536L);
+ const int have_word_size = spec->word_size != (-65536L);
+ const int have_bitrate = spec->bitrate != (-65536L);
+
+ if (have_state_size)
+ {
+ state_size = spec->state_size;
+ if (state_size <= 0)
+ return 1;
+ if (state_size > 1600)
+ return 2;
+ }
+
+ if (have_word_size)
+ {
+ word_size = spec->word_size;
+ if (word_size <= 0)
+ return 4;
+ if (word_size > 64)
+ return 5;
+ if (have_state_size && state_size != word_size * 25)
+ return 6;
+ else if (!have_state_size) {
+ spec->state_size = 1;
+ state_size = word_size * 25;
+ }
+ }
+
+ if (have_bitrate)
+ bitrate = spec->bitrate;
+
+ if (!have_bitrate)
+ {
+ state_size = (have_state_size ? state_size : (1600L));
+ output = ((state_size << 5) / 100L + 7L) & ~0x07L;
+ bitrate = output << 1;
+ }
+
+ output_spec->bitrate = bitrate;
+
+ return 0;
+}
+
+int main ()
+{
+ struct libkeccak_generalised_spec gspec;
+ struct libkeccak_spec spec;
+ spec.bitrate = -1;
+ gspec.bitrate = -65536;
+ gspec.state_size = -65536;
+ gspec.word_size = -65536;
+ if (libkeccak_degeneralise_spec(&gspec, &spec))
+ __builtin_abort ();
+ if (spec.bitrate != 1024)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr109564-2.c b/gcc/testsuite/gcc.dg/torture/pr109564-2.c
new file mode 100644
index 00000000000..eeab437c0b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr109564-2.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+struct libkeccak_generalised_spec {
+ int state_size;
+ int word_size;
+} main_gspec;
+
+long gvar;
+
+int libkeccak_degeneralise_spec(struct libkeccak_generalised_spec *spec)
+{
+ int state_size;
+ int have_state_size = spec->state_size != -1;
+ int have_word_size = spec->word_size;
+
+ if (have_state_size)
+ state_size = spec->state_size;
+ if (have_word_size)
+ gvar = 12345;
+ if (have_state_size && state_size != spec->word_size)
+ return 1;
+ if (spec)
+ gvar++;
+ return 0;
+}
+
+int main()
+{
+ main_gspec.state_size = -1;
+ if (libkeccak_degeneralise_spec(&main_gspec))
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp-ignore.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp-ignore.c
index 9bfaed6a50a..ee93e5ad9f6 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/evrp-ignore.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp-ignore.c
@@ -25,4 +25,4 @@ void foo (int x, int y, int z)
kill();
}
-/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
+/* { dg-final { scan-tree-dump-not "kill" "evrp" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
index 898477e42fb..8f5f86021c8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
@@ -30,4 +30,4 @@ foo (int i, int j, int a)
/* { dg-final { scan-tree-dump-times "Folding predicate \[i|j\]_\[0-9\]+.*0 to 0" 1 "vrp1" } } */
/* { dg-final { scan-tree-dump-times "Folding predicate \[i|j\]_\[0-9\]+.*0 to 1" 1 "vrp1" } } */
-/* { dg-final { scan-tree-dump-times "Folding predicate i_\[0-9]+.*j_\[0-9\]+.* to 0" 1 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "Folding predicate i_\[0-9]+.*j_\[0-9\]+.* to 0" 1 "vrp1" { xfail *-*-* } } } */