Hi Richard,
I am trying to "if covert the store" in the below test case and later help it
to get vectorized under -Ofast -ftree-loop-if-convert-stores -fno-common
#define LEN 4096
__attribute__((aligned(32))) float array[LEN]; void test() { for (int i = 0; i
< LEN; i++) {
if (array[i] > (float)0.)
array[i] =3 ;
}
}
Currently in GCC 5.2 does not vectorize it.
https://goo.gl/9nS6Pd
However ICC seems to vectorize it
https://goo.gl/y1yGHx
As discussed with you earlier, to allow "if convert store" I am checking the
following:
(1) We already read the reference "array[i]" unconditionally once .
(2) I am now checking if we are conditionally writing to memory which is
defined as read and write and is bound to the definition we are seeing.
With this change, I get able to if convert and the vectorize the case also.
/build/gcc/xgcc -B ./build/gcc/ ifconv.c -Ofast -fopt-info-vec -S
-ftree-loop-if-convert-stores -fno-common
ifconv.c:2:63: note: loop vectorized
Patch
------
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index f201ab5..6475cc0 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -727,6 +727,34 @@ write_memrefs_written_at_least_once (gimple *stmt,
return true;
}
+static bool
+write_memrefs_safe_to_access_unconditionally (gimple *stmt,
+
vec<data_reference_p> drs)
+{
+ int i;
+ data_reference_p a;
+ bool found = false;
+
+ for (i = 0; drs.iterate (i, &a); i++)
+ {
+ if (DR_STMT (a) == stmt
+ && DR_IS_WRITE (a)
+ && (DR_WRITTEN_AT_LEAST_ONCE (a) == 0)
+ && (DR_RW_UNCONDITIONALLY (a) == 1))
+ {
+ tree base = get_base_address (DR_REF (a));
+ found = false;
+ if (DECL_P (base)
+ && decl_binds_to_current_def_p (base)
+ && !TREE_READONLY (base))
+ {
+ found = true;
+ }
+ }
+ }
+ return found;
+}
+
/* Return true when the memory references of STMT won't trap in the
if-converted code. There are two things that we have to check for:
@@ -748,8 +776,20 @@ write_memrefs_written_at_least_once (gimple *stmt,
static bool
ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> refs)
{
- return write_memrefs_written_at_least_once (stmt, refs)
- && memrefs_read_or_written_unconditionally (stmt, refs);
+ bool memrefs_written_once, memrefs_read_written_unconditionally;
+ bool memrefs_safe_to_access;
+
+ memrefs_written_once
+ = write_memrefs_written_at_least_once (stmt, refs);
+
+ memrefs_read_written_unconditionally
+ = memrefs_read_or_written_unconditionally (stmt, refs);
+
+ memrefs_safe_to_access
+ = write_memrefs_safe_to_access_unconditionally (stmt, refs);
+
+ return ((memrefs_written_once || memrefs_safe_to_access)
+ && memrefs_read_written_unconditionally);
}
/* Wrapper around gimple_could_trap_p refined for the needs of the
do I need this function write_memrefs_written_at_least_once anymore?
Please suggest if there a better way to do this.
Bootstrapped and regression tested on x86_64.
I am not adding change log and comments now, as I wanted to check approach
first.
Regards,
Venkat.