PR114061 added support for dropping prefetches during vectorization but that
version doesn't work when the prefetch is conditional.
The conditionality introduces a non-if-convertible block in the CFG. The
vectorizer removes the prefetch later on but it can't modify the CFG and as
such the block where the prefetch was in remains with just a VUSEs chain.
This change now drops them during if-conversion. While this patch at the moment
removes them, it makes it easier for later on, should we want to start
vectorizing these instead to just update predicate_statements.
For now this follows the same approach as PR114061 and just drops them.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.
Pushed.
Thanks,
Tamar
gcc/ChangeLog:
PR tree-optimization/120164
* tree-if-conv.cc (if_convertible_stmt_p): Detect prefetches.
(predicate_statements): Drop them during predication.
gcc/testsuite/ChangeLog:
PR tree-optimization/120164
* gcc.dg/vect/vect-prefetch-drop_2.c: New test.
---
diff --git a/gcc/testsuite/gcc.dg/vect/vect-prefetch-drop_2.c
b/gcc/testsuite/gcc.dg/vect/vect-prefetch-drop_2.c
new file mode 100644
index
0000000000000000000000000000000000000000..3ac4effb679c004ecad03eeecb0108984d35ccf2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-prefetch-drop_2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+void foo(int *restrict a, int *b, int n)
+{
+ for(int i=0; i<n; ++i){
+ a[i] = a[i] + b[i];
+ if (a[i] > 0)
+ __builtin_prefetch(&(b[i+8]));
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index
d728f7c5221c66c2fd963d3e3ab55b232e628cb0..272241e84415d3c240bef82aa0a6172e68fd989e
100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -1202,6 +1202,12 @@ if_convertible_stmt_p (gimple *stmt,
vec<data_reference_p> refs)
}
}
+ /* Check if it's a prefetch. Many ISAs contain vectorized and/or
+ conditional prefetches so if-convert should convert them or remove
+ them. Mark them as supported. */
+ if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
+ return true;
+
/* There are some IFN_s that are used to replace builtins but have the
same semantics. Even if MASK_CALL cannot handle them vectorable_call
will insert the proper selection, so do not block conversion. */
@@ -3126,6 +3132,16 @@ predicate_statements (loop_p loop)
release_defs (stmt);
continue;
}
+ /* For now, just drop prefetches. Do it now to remove any possible
+ aliasing check failures from the address calculations of the
+ prefetch. Vect would be too late in that regard. */
+ else if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
+ }
else if (gimple_plf (stmt, GF_PLF_2)
&& (is_gimple_assign (stmt)
|| (gimple_call_builtin_p (stmt)
--
diff --git a/gcc/testsuite/gcc.dg/vect/vect-prefetch-drop_2.c b/gcc/testsuite/gcc.dg/vect/vect-prefetch-drop_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..3ac4effb679c004ecad03eeecb0108984d35ccf2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-prefetch-drop_2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+void foo(int *restrict a, int *b, int n)
+{
+ for(int i=0; i<n; ++i){
+ a[i] = a[i] + b[i];
+ if (a[i] > 0)
+ __builtin_prefetch(&(b[i+8]));
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index d728f7c5221c66c2fd963d3e3ab55b232e628cb0..272241e84415d3c240bef82aa0a6172e68fd989e 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -1202,6 +1202,12 @@ if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
}
}
+ /* Check if it's a prefetch. Many ISAs contain vectorized and/or
+ conditional prefetches so if-convert should convert them or remove
+ them. Mark them as supported. */
+ if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
+ return true;
+
/* There are some IFN_s that are used to replace builtins but have the
same semantics. Even if MASK_CALL cannot handle them vectorable_call
will insert the proper selection, so do not block conversion. */
@@ -3126,6 +3132,16 @@ predicate_statements (loop_p loop)
release_defs (stmt);
continue;
}
+ /* For now, just drop prefetches. Do it now to remove any possible
+ aliasing check failures from the address calculations of the
+ prefetch. Vect would be too late in that regard. */
+ else if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
+ }
else if (gimple_plf (stmt, GF_PLF_2)
&& (is_gimple_assign (stmt)
|| (gimple_call_builtin_p (stmt)