]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end: check if target can do extract first for early breaks [PR113199]
authorTamar Christina <tamar.christina@arm.com>
Tue, 9 Jan 2024 13:35:49 +0000 (13:35 +0000)
committerTamar Christina <tamar.christina@arm.com>
Tue, 9 Jan 2024 13:38:04 +0000 (13:38 +0000)
I was generating the vector reverse mask without checking if the target
actually supported such an operation.

This patch changes it to if the bitstart is 0 then use BIT_FIELD_REF instead
to extract the first element since this is supported by all targets.

This is good for now since masks always come from whilelo.  But in the future
when masks can come from other sources we will need the old code back.

gcc/ChangeLog:

PR tree-optimization/113199
* tree-vect-loop.cc (vectorizable_live_operation_1): Use
BIT_FIELD_REF.

gcc/testsuite/ChangeLog:

PR tree-optimization/113199
* gcc.target/gcn/pr113199.c: New test.

gcc/testsuite/gcc.target/gcn/pr113199.c [new file with mode: 0644]
gcc/tree-vect-loop.cc

diff --git a/gcc/testsuite/gcc.target/gcn/pr113199.c b/gcc/testsuite/gcc.target/gcn/pr113199.c
new file mode 100644 (file)
index 0000000..8a641e5
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2" } */
+
+typedef long unsigned int size_t;
+typedef int wchar_t;
+struct tm
+{
+  int tm_mon;
+  int tm_year;
+};
+int abs (int);
+struct lc_time_T { const char *month[12]; };
+struct __locale_t * __get_current_locale (void) { }
+const struct lc_time_T * __get_time_locale (struct __locale_t *locale) { }
+const wchar_t * __ctloc (wchar_t *buf, const char *elem, size_t *len_ret) { return buf; }
+size_t
+__strftime (wchar_t *s, size_t maxsize, const wchar_t *format,
+     const struct tm *tim_p, struct __locale_t *locale)
+{
+  size_t count = 0;
+  const wchar_t *ctloc;
+  wchar_t ctlocbuf[256];
+  size_t i, ctloclen;
+  const struct lc_time_T *_CurrentTimeLocale = __get_time_locale (locale);
+    {
+      switch (*format)
+ {
+ case L'B':
+   (ctloc = __ctloc (ctlocbuf, _CurrentTimeLocale->month[tim_p->tm_mon], &ctloclen));
+   for (i = 0; i < ctloclen; i++)
+     {
+       if (count < maxsize - 1)
+  s[count++] = ctloc[i];
+       else
+  return 0;
+       {
+  int century = tim_p->tm_year >= 0
+    ? tim_p->tm_year / 100 + 1900 / 100
+    : abs (tim_p->tm_year + 1900) / 100;
+       }
+   }
+ }
+    }
+}
index cfea9074830aa60a8c1ac7eaadf9e02f84896357..b50b5cf480e2ac9c6b2a9ba3d13d8be559dbcc37 100644 (file)
@@ -10607,7 +10607,17 @@ vectorizable_live_operation_1 (loop_vec_info loop_vinfo,
 
   gimple_seq stmts = NULL;
   tree new_tree;
-  if (LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo))
+
+  /* If bitstart is 0 then we can use a BIT_FIELD_REF  */
+  if (integer_zerop (bitstart))
+    {
+      tree scalar_res = gimple_build (&stmts, BIT_FIELD_REF, TREE_TYPE (vectype),
+                                  vec_lhs_phi, bitsize, bitstart);
+
+      /* Convert the extracted vector element to the scalar type.  */
+      new_tree = gimple_convert (&stmts, lhs_type, scalar_res);
+    }
+  else if (LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo))
     {
       /* Emit:
 
@@ -10633,12 +10643,6 @@ vectorizable_live_operation_1 (loop_vec_info loop_vinfo,
       tree last_index = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (len),
                                     len, bias_minus_one);
 
-      /* This needs to implement extraction of the first index, but not sure
-        how the LEN stuff works.  At the moment we shouldn't get here since
-        there's no LEN support for early breaks.  But guard this so there's
-        no incorrect codegen.  */
-      gcc_assert (!LOOP_VINFO_EARLY_BREAKS (loop_vinfo));
-
       /* SCALAR_RES = VEC_EXTRACT <VEC_LHS, LEN + BIAS - 1>.  */
       tree scalar_res
        = gimple_build (&stmts, CFN_VEC_EXTRACT, TREE_TYPE (vectype),
@@ -10663,32 +10667,6 @@ vectorizable_live_operation_1 (loop_vec_info loop_vinfo,
                                      &LOOP_VINFO_MASKS (loop_vinfo),
                                      1, vectype, 0);
       tree scalar_res;
-
-      /* For an inverted control flow with early breaks we want EXTRACT_FIRST
-        instead of EXTRACT_LAST.  Emulate by reversing the vector and mask. */
-      if (restart_loop && LOOP_VINFO_EARLY_BREAKS (loop_vinfo))
-       {
-         /* First create the permuted mask.  */
-         tree perm_mask = perm_mask_for_reverse (TREE_TYPE (mask));
-         tree perm_dest = copy_ssa_name (mask);
-         gimple *perm_stmt
-               = gimple_build_assign (perm_dest, VEC_PERM_EXPR, mask,
-                                      mask, perm_mask);
-         vect_finish_stmt_generation (loop_vinfo, stmt_info, perm_stmt,
-                                      &gsi);
-         mask = perm_dest;
-
-         /* Then permute the vector contents.  */
-         tree perm_elem = perm_mask_for_reverse (vectype);
-         perm_dest = copy_ssa_name (vec_lhs_phi);
-         perm_stmt
-               = gimple_build_assign (perm_dest, VEC_PERM_EXPR, vec_lhs_phi,
-                                      vec_lhs_phi, perm_elem);
-         vect_finish_stmt_generation (loop_vinfo, stmt_info, perm_stmt,
-                                      &gsi);
-         vec_lhs_phi = perm_dest;
-       }
-
       gimple_seq_add_seq (&stmts, tem);
 
       scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST, scalar_type,