mp = CEIL (min_prec, limb_prec) * limb_prec;
if (mp == 0)
mp = 1;
- if (mp >= (unsigned) TYPE_PRECISION (TREE_TYPE (op)))
+ if (mp >= (unsigned) TYPE_PRECISION (TREE_TYPE (op))
+ && (TREE_CODE (TREE_TYPE (op)) == BITINT_TYPE
+ || TYPE_PRECISION (TREE_TYPE (op)) <= limb_prec))
type = TREE_TYPE (op);
else
type = build_bitint_type (mp, 1);
if (TYPE_PRECISION (type) <= limb_prec)
type = m_limb_type;
else
- /* This case is for targets which e.g. have 64-bit
- limb but categorize up to 128-bits _BitInts as
- small. We could use type of m_limb_type[2] and
- similar instead to save space. */
- type = build_bitint_type (mid_min_prec, 1);
+ {
+ while (bitint_precision_kind (mp) == bitint_prec_small)
+ mp += limb_prec;
+ /* This case is for targets which e.g. have 64-bit
+ limb but categorize up to 128-bits _BitInts as
+ small. We could use type of m_limb_type[2] and
+ similar instead to save space. */
+ type = build_bitint_type (mp, 1);
+ }
}
if (prec_stored)
{
--- /dev/null
+/* PR tree-optimization/113361 */
+/* { dg-do run { target { bitint && int128 } } } */
+/* { dg-options "-std=gnu23" } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 129
+int
+foo (_BitInt(65) x)
+{
+ return __builtin_mul_overflow_p ((__int128) 0xffffffff << 64, x, (_BitInt(129)) 0);
+}
+
+int
+bar (_BitInt(63) x)
+{
+ return __builtin_mul_overflow_p ((__int128) 0xffffffff << 64, x, (_BitInt(129)) 0);
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 129
+ if (!foo (5167856845))
+ __builtin_abort ();
+ if (!bar (5167856845))
+ __builtin_abort ();
+#endif
+ return 0;
+}