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