[expand] Checking available optabs for scalar modes in by pieces operations

Message ID 7b83825b-0b3c-b9ab-56dc-6eca343d8f0c@linux.ibm.com
State Unresolved
Headers
Series [expand] Checking available optabs for scalar modes in by pieces operations |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

HAO CHEN GUI Oct. 27, 2023, 7:29 a.m. UTC
  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
  

Comments

Richard Sandiford Oct. 27, 2023, 9:29 a.m. UTC | #1
HAO CHEN GUI <guihaoc@linux.ibm.com> writes:
> 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.

OK, thanks.

Richard

> 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;
>  	  }
>      }
  
HAO CHEN GUI Oct. 30, 2023, 3:05 a.m. UTC | #2
Committed as r14-5001.

Thanks
Gui Haochen

在 2023/10/27 17:29, Richard Sandiford 写道:
> HAO CHEN GUI <guihaoc@linux.ibm.com> writes:
>> 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.
> 
> OK, thanks.
> 
> Richard
> 
>> 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;
>>  	  }
>>      }
  

Patch

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;
 	  }
     }