For targets that set the "extended" flag in TARGET_C_BITINT_TYPE_INFO,
we assume small _BitInts to be internally extended after arithmetic
operations. In this case, an extra extension during RTL expansion
can be avoided.

gcc/ChangeLog:

        * expr.cc (expand_expr_real_1): Do not call
        reduce_to_bit_field_precision if the target assume the _BitInt
        results to be already extended.
        (EXTEND_BITINT): Same.
---
 gcc/expr.cc | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/expr.cc b/gcc/expr.cc
index ac4fdfaa218..a3d73edffd5 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -11268,6 +11268,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
   tree ssa_name = NULL_TREE;
   gimple *g;
 
+  type = TREE_TYPE (exp);
+  mode = TYPE_MODE (type);
+  unsignedp = TYPE_UNSIGNED (type);
+
   /* Some ABIs define padding bits in _BitInt uninitialized.  Normally, RTL
      expansion sign/zero extends integral types with less than mode precision
      when reading from bit-fields and after arithmetic operations (see
@@ -11278,8 +11282,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
      objects in memory, or function arguments, return value).  Because we
      internally extend after arithmetic operations, we can avoid doing that
      when reading from SSA_NAMEs of vars.  */
+
 #define EXTEND_BITINT(expr) \
   ((TREE_CODE (type) == BITINT_TYPE                                    \
+    && !bitint_type_info.extended                                      \
     && reduce_bit_field                                                        
\
     && mode != BLKmode                                                 \
     && modifier != EXPAND_MEMORY                                       \
@@ -11288,9 +11294,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
     && modifier != EXPAND_CONST_ADDRESS)                               \
    ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
 
-  type = TREE_TYPE (exp);
-  mode = TYPE_MODE (type);
-  unsignedp = TYPE_UNSIGNED (type);
+  struct bitint_info bitint_type_info;
+  if (TREE_CODE (type) == BITINT_TYPE)
+    {
+      bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type),
+                                           &bitint_type_info);
+      gcc_assert (ok);
+    }
 
   treeop0 = treeop1 = treeop2 = NULL_TREE;
   if (!VL_EXP_CLASS_P (exp))
@@ -11631,12 +11641,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
       {
        if (TREE_CODE (type) == BITINT_TYPE)
          {
-           unsigned int prec = TYPE_PRECISION (type);
-           struct bitint_info info;
-           bool ok = targetm.c.bitint_type_info (prec, &info);
-           gcc_assert (ok);
            scalar_int_mode limb_mode
-             = as_a <scalar_int_mode> (info.limb_mode);
+             = as_a <scalar_int_mode> (bitint_type_info.limb_mode);
+           unsigned int prec = TYPE_PRECISION (type);
            unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
            if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
              {
-- 
2.46.0

Reply via email to