--- /dev/null
+/* PR tree-optimization/113753 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-std=gnu23" } */
+
+_BitInt(161) a = 1461501637330902918203684832716283019655932542975wb / 2wb * 2wb;
+_BitInt(160) b = 730750818665451459101842416358141509827966271487wb / 2wb * 2wb;
+_BitInt(159) c = 365375409332725729550921208179070754913983135743wb / 2wb * 2wb;
+_BitInt(129) d = 340282366920938463463374607431768211455wb / 2wb * 2wb;
+_BitInt(128) e = 170141183460469231731687303715884105727wb / 2wb * 2wb;
+_BitInt(161) f = (-1461501637330902918203684832716283019655932542975wb - 1wb) / 2wb * 2wb;
+_BitInt(160) g = (-730750818665451459101842416358141509827966271487wb - 1wb) / 2wb * 2wb;
+_BitInt(159) h = (-365375409332725729550921208179070754913983135743wb - 1wb) / 2wb * 2wb;
+_BitInt(129) i = (-340282366920938463463374607431768211455wb - 1wb) / 2wb * 2wb;
+_BitInt(128) j = (-170141183460469231731687303715884105727wb - 1wb) / 2wb * 2wb;
+_BitInt(161) k = 1461501637330902918203684832716283019655932542975wb / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(161\\\)' results in" } */
+_BitInt(160) l = 730750818665451459101842416358141509827966271487wb / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(160\\\)' results in" } */
+_BitInt(159) m = 365375409332725729550921208179070754913983135743wb / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(159\\\)' results in" } */
+_BitInt(129) n = 340282366920938463463374607431768211455wb / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(129\\\)' results in" } */
+_BitInt(128) o = 170141183460469231731687303715884105727wb / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(128\\\)' results in" } */
+_BitInt(161) p = (-1461501637330902918203684832716283019655932542975wb - 1wb) / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(161\\\)' results in" } */
+_BitInt(160) q = (-730750818665451459101842416358141509827966271487wb - 1wb) / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(160\\\)' results in" } */
+_BitInt(159) r = (-365375409332725729550921208179070754913983135743wb - 1wb) / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(159\\\)' results in" } */
+_BitInt(129) s = (-340282366920938463463374607431768211455wb - 1wb) / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(129\\\)' results in" } */
+_BitInt(128) t = (-170141183460469231731687303715884105727wb - 1wb) / 2wb * 3wb; /* { dg-warning "integer overflow in expression of type '_BitInt\\\(128\\\)' results in" } */
--- /dev/null
+/* PR tree-optimization/113753 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 129
+unsigned _BitInt(128)
+foo (unsigned u, unsigned _BitInt(128) a, unsigned _BitInt(128) b)
+{
+ unsigned _BitInt(129) m = a % b;
+ return u * m / u;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 129
+ if (foo (0xfa637c33, 0x37af7fe8b0000000000000000wb,
+ 0xfffffffff0000000000000000wb)
+ != 0x16f7e93f6d726b38b38d0b753wb)
+ __builtin_abort ();
+#endif
+}
}
/* We do unsigned mul and then correct it. */
- wi_unpack (u, op1val, op1len, half_blocks_needed, prec, SIGNED);
- wi_unpack (v, op2val, op2len, half_blocks_needed, prec, SIGNED);
+ wi_unpack (u, op1val, op1len, half_blocks_needed, prec, UNSIGNED);
+ wi_unpack (v, op2val, op2len, half_blocks_needed, prec, UNSIGNED);
/* The 2 is for a full mult. */
memset (r, 0, half_blocks_needed * 2
r[j + half_blocks_needed] = k;
}
+ unsigned int shift;
+ if ((high || needs_overflow) && (shift = prec % HOST_BITS_PER_WIDE_INT) != 0)
+ {
+ /* The high or needs_overflow code assumes that the high bits
+ only appear from r[half_blocks_needed] up to
+ r[half_blocks_needed * 2 - 1]. If prec is not a multiple
+ of HOST_BITS_PER_WIDE_INT, shift the bits above prec up
+ to make that code simple. */
+ if (shift == HOST_BITS_PER_HALF_WIDE_INT)
+ memmove (&r[half_blocks_needed], &r[half_blocks_needed - 1],
+ sizeof (r[0]) * half_blocks_needed);
+ else
+ {
+ unsigned int skip = shift < HOST_BITS_PER_HALF_WIDE_INT;
+ if (!skip)
+ shift -= HOST_BITS_PER_HALF_WIDE_INT;
+ for (i = 2 * half_blocks_needed - 1; i >= half_blocks_needed; i--)
+ r[i] = ((r[i - skip] << (-shift % HOST_BITS_PER_HALF_WIDE_INT))
+ | (r[i - skip - 1] >> shift));
+ }
+ }
+
/* We did unsigned math above. For signed we must adjust the
product (assuming we need to see that). */
if (sgn == SIGNED && (high || needs_overflow))
top = 0;
else
{
- top = r[(half_blocks_needed) - 1];
- top = SIGN_MASK (top << (HOST_BITS_PER_WIDE_INT / 2));
+ top = r[half_blocks_needed - 1
+ - ((-prec % HOST_BITS_PER_WIDE_INT)
+ >= HOST_BITS_PER_HALF_WIDE_INT)];
+ top = SIGN_MASK (((unsigned HOST_WIDE_INT) top)
+ << (HOST_BITS_PER_WIDE_INT / 2
+ + (-prec % HOST_BITS_PER_HALF_WIDE_INT)));
top &= mask;
}