Hi,
  This patch checks available optabs for scalar modes used in by
pieces operations. It fixes the regression cases caused by previous
patch. Now both scalar and vector modes are examined by the same
approach.

  Bootstrapped and tested on x86 and powerpc64-linux BE and LE with no
regressions. Is this OK for trunk?

Thanks
Gui Haochen


ChangeLog
Expand: Checking available optabs for scalar modes in by pieces operations

The former patch (f08ca5903c7) examines the scalar modes by target
hook scalar_mode_supported_p.  It causes some i386 regression cases
as XImode and OImode are not enabled in i386 target function.  This
patch examines the scalar mode by checking if the corresponding optabs
are available for the mode.

gcc/
        PR target/111449
        * expr.cc (qi_vector_mode_supported_p): Rename to...
        (by_pieces_mode_supported_p): ...this, and extends it to do
        the checking for both scalar and vector mode.
        (widest_fixed_size_mode_for_size): Call
        by_pieces_mode_supported_p to examine the mode.
        (op_by_pieces_d::smallest_fixed_size_mode_for_size): Likewise.

patch.diff
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 7aac575eff8..2af9fcbed18 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -1000,18 +1000,21 @@ can_use_qi_vectors (by_pieces_operation op)
 /* Return true if optabs exists for the mode and certain by pieces
    operations.  */
 static bool
-qi_vector_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
+by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
 {
+  if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
+    return false;
+
   if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
-      && optab_handler (vec_duplicate_optab, mode) != CODE_FOR_nothing)
-    return true;
+      && VECTOR_MODE_P (mode)
+      && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
+    return false;

   if (op == COMPARE_BY_PIECES
-      && optab_handler (mov_optab, mode) != CODE_FOR_nothing
-      && can_compare_p (EQ, mode, ccp_jump))
-    return true;
+      && !can_compare_p (EQ, mode, ccp_jump))
+    return false;

-  return false;
+  return true;
 }

 /* Return the widest mode that can be used to perform part of an
@@ -1035,7 +1038,7 @@ widest_fixed_size_mode_for_size (unsigned int size, 
by_pieces_operation op)
          {
            if (GET_MODE_SIZE (candidate) >= size)
              break;
-           if (qi_vector_mode_supported_p (candidate, op))
+           if (by_pieces_mode_supported_p (candidate, op))
              result = candidate;
          }

@@ -1049,7 +1052,7 @@ widest_fixed_size_mode_for_size (unsigned int size, 
by_pieces_operation op)
     {
       mode = tmode.require ();
       if (GET_MODE_SIZE (mode) < size
-         && targetm.scalar_mode_supported_p (mode))
+         && by_pieces_mode_supported_p (mode, op))
       result = mode;
     }

@@ -1454,7 +1457,7 @@ op_by_pieces_d::smallest_fixed_size_mode_for_size 
(unsigned int size)
              break;

            if (GET_MODE_SIZE (candidate) >= size
-               && qi_vector_mode_supported_p (candidate, m_op))
+               && by_pieces_mode_supported_p (candidate, m_op))
              return candidate;
          }
     }

Reply via email to