aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-09-29 11:08:18 +0200
committerRichard Biener <rguenther@suse.de>2023-09-29 11:50:14 +0200
commit962ca7149d652e4077a2259886e5cd2ea3cea0ab (patch)
treef169a8095f996064259b51e5a5e4883edf1a329c
parent59cda1f9525702d5d6560002c874f12c0103f7df (diff)
downloadgcc-962ca7149d652e4077a2259886e5cd2ea3cea0ab.zip
gcc-962ca7149d652e4077a2259886e5cd2ea3cea0ab.tar.gz
gcc-962ca7149d652e4077a2259886e5cd2ea3cea0ab.tar.bz2
tree-optimization/111583 - loop distribution issue
The following conservatively fixes loop distribution to only recognize memset/memcpy and friends when at least one element is going to be processed. This avoids having an unconditional builtin call in the IL that might imply the source and destination pointers are non-NULL when originally pointers were not always dereferenced. With -Os loop header copying is less likely to ensure this. PR tree-optimization/111583 * tree-loop-distribution.cc (find_single_drs): Ensure the load/store are always executed. * gcc.dg/tree-ssa/pr111583-1.c: New testcase. * gcc.dg/tree-ssa/pr111583-2.c: Likewise.
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr111583-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr111583-2.c36
-rw-r--r--gcc/tree-loop-distribution.cc15
3 files changed, 81 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr111583-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr111583-1.c
new file mode 100644
index 0000000..1dd8dbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr111583-1.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+short a, f, i;
+static const int *e;
+short *g;
+long h;
+int main()
+{
+ {
+ unsigned j = i;
+ a = 1;
+ for (; a; a++) {
+ {
+ long b = j, d = h;
+ int c = 0;
+ while (d--)
+ *(char *)b++ = c;
+ }
+ if (e)
+ break;
+ }
+ j && (*g)--;
+ const int **k = &e;
+ *k = 0;
+ }
+ if (f != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr111583-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr111583-2.c
new file mode 100644
index 0000000..0ee2185
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr111583-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+int b, c, d;
+char e;
+short f;
+const unsigned short **g;
+char h(char k) {
+ if (k)
+ return '0';
+ return 0;
+}
+int l() {
+ b = 0;
+ return 1;
+}
+static short m(unsigned k) {
+ const unsigned short *n[65];
+ g = &n[4];
+ k || l();
+ long a = k;
+ char i = 0;
+ unsigned long j = k;
+ while (j--)
+ *(char *)a++ = i;
+ c = h(d);
+ f = k;
+ return 0;
+}
+int main() {
+ long o = (e < 0) << 5;
+ m(o);
+ if (f != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc
index a28470b..39fd440 100644
--- a/gcc/tree-loop-distribution.cc
+++ b/gcc/tree-loop-distribution.cc
@@ -1574,6 +1574,7 @@ find_single_drs (class loop *loop, struct graph *rdg, const bitmap &partition_st
basic_block bb_ld = NULL;
basic_block bb_st = NULL;
+ edge exit = single_exit (loop);
if (single_ld)
{
@@ -1589,6 +1590,14 @@ find_single_drs (class loop *loop, struct graph *rdg, const bitmap &partition_st
bb_ld = gimple_bb (DR_STMT (single_ld));
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb_ld))
return false;
+
+ /* The data reference must also be executed before possibly exiting
+ the loop as otherwise we'd for example unconditionally execute
+ memset (ptr, 0, n) which even with n == 0 implies ptr is non-NULL. */
+ if (bb_ld != loop->header
+ && (!exit
+ || !dominated_by_p (CDI_DOMINATORS, exit->src, bb_ld)))
+ return false;
}
if (single_st)
@@ -1604,6 +1613,12 @@ find_single_drs (class loop *loop, struct graph *rdg, const bitmap &partition_st
bb_st = gimple_bb (DR_STMT (single_st));
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb_st))
return false;
+
+ /* And before exiting the loop. */
+ if (bb_st != loop->header
+ && (!exit
+ || !dominated_by_p (CDI_DOMINATORS, exit->src, bb_st)))
+ return false;
}
if (single_ld && single_st)