For targets that treat small _BitInts like the fundamental
integral types, we should allow their machine modes to be promoted
in the same way.

gcc/ChangeLog:

        * explow.cc (promote_function_mode): Add a case for
        small/medium _BitInts.
        (promote_mode): Same.
---
 gcc/explow.cc | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/gcc/explow.cc b/gcc/explow.cc
index 7799a98053b..00d0380c664 100644
--- a/gcc/explow.cc
+++ b/gcc/explow.cc
@@ -856,7 +856,21 @@ promote_function_mode (const_tree type, machine_mode mode, 
int *punsignedp,
     {
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
     case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
-    case POINTER_TYPE:   case REFERENCE_TYPE:
+    case POINTER_TYPE:   case REFERENCE_TYPE:  case BITINT_TYPE:
+      /* Handle _BitInt(N) that does not require promotion.  */
+      if (TREE_CODE (type) == BITINT_TYPE)
+       {
+         if (TYPE_MODE (type) == BLKmode)
+           return mode;
+
+         struct bitint_info info;
+         bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
+         gcc_assert (ok);
+
+         if (!info.extended)
+           return mode;
+       }
+
       return targetm.calls.promote_function_mode (type, mode, punsignedp, 
funtype,
                                                  for_return);
 
@@ -895,6 +909,21 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, 
machine_mode mode,
     {
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
     case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
+    case BITINT_TYPE:
+      /* Handle _BitInt(N) that does not require promotion.  */
+      if (code == BITINT_TYPE)
+       {
+         if (TYPE_MODE (type) == BLKmode)
+           return mode;
+
+         struct bitint_info info;
+         bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
+         gcc_assert (ok);
+
+         if (!info.extended)
+           return mode;
+       }
+
       /* Values of these types always have scalar mode.  */
       smode = as_a <scalar_mode> (mode);
       PROMOTE_MODE (smode, unsignedp, type);
-- 
2.46.0

Reply via email to