diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index cf30d8e343e..342581667ae 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -1547,14 +1547,15 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx) } else { - if (tree_to_uhwi (idx) < low) + unsigned tidx = tree_to_uhwi (idx); + if (tidx < low) { t = handle_operand (rhs1, idx); if (m_first) m_data[save_data_cnt + 2] = build_int_cst (NULL_TREE, m_data_cnt); } - else if (tree_to_uhwi (idx) < high) + else if (tidx < high) { t = handle_operand (rhs1, size_int (low)); if (m_first) @@ -1587,7 +1588,9 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx) m_data_cnt = tree_to_uhwi (m_data[save_data_cnt + 2]); if (TYPE_UNSIGNED (rhs_type)) t = build_zero_cst (m_limb_type); - else if (m_bb && m_data[save_data_cnt]) + else if (m_bb + && m_data[save_data_cnt] + && ((tidx & 1) == 0 || tidx != low + 1)) t = m_data[save_data_cnt]; else t = m_data[save_data_cnt + 1]; diff --git a/gcc/testsuite/gcc.dg/torture/bitint-76.c b/gcc/testsuite/gcc.dg/torture/bitint-76.c new file mode 100644 index 00000000000..df478575e8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-76.c @@ -0,0 +1,19 @@ +/* PR tree-optimization/119707 */ +/* { dg-do run { target bitint } } */ + +#if __BITINT_MAXWIDTH__ >= 256 +__attribute__((noipa)) unsigned _BitInt(256) +foo (unsigned _BitInt(256) x, _BitInt(129) y) +{ + return x + (unsigned _BitInt(255)) y; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 256 + if (foo (0, -1) != 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffuwb) + __builtin_abort (); +#endif +}