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.


Reply via email to