https://gcc.gnu.org/g:0accf2b4dff933915ae75a154d268c79fc7ea5b9
commit r16-7068-g0accf2b4dff933915ae75a154d268c79fc7ea5b9 Author: Robin Dapp <[email protected]> Date: Sat Jan 24 22:07:07 2026 +0100 forwprop: Pun with integer type if needed [PR123799]. We cannot directly build vectors from BitInts, which this patch circumvents by punning the conversion element type with an integer type. This results in two separate conversions at the gimple level. Those don't appear to cause worse final code, though. It is possible to merge those two conversions at the construction site but from what I can tell would involve more changes than necessary now, so I refrained from it. Before this patch we would check tree_nop_conversion_p for e.g. BitInt _12 = BIT_FIELD_REF (vector unsigned int). This is a "nop conversion" but the implicit assumption is that we can build a vector type from the lhs type that can be nop-converted back to the original type. This is not true for BitInt. Bootstrapped and regtested on x86, power10, and aarch64. Regtested on riscv64. PR tree-optimization/123799 gcc/ChangeLog: * tree-ssa-forwprop.cc (simplify_vector_constructor): Pun conversion element type with integer type. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr123799.c: New test. Diff: --- gcc/testsuite/gcc.dg/torture/pr123799.c | 26 ++++++++++++++++++++++++++ gcc/tree-ssa-forwprop.cc | 15 +++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr123799.c b/gcc/testsuite/gcc.dg/torture/pr123799.c new file mode 100644 index 000000000000..aadf6e8dbd53 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr123799.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target bitint } } */ +/* { dg-additional-options "-O3" } */ +/* { dg-additional-options "-mavx10.1" { target x86_64-*-* i?86-*-* } } */ + +union { + _Complex long a[3]; + _BitInt (64) b[5]; + unsigned _BitInt (512) c; +} u; +int g; + +void +bar (int j) +{ + __builtin_add_overflow (1, j, &g); + u.c /= g; + int __z; + __builtin_sub_overflow (0, u.b[4], &__z); + u.a[2] *= (_Complex double) __z; +} + +void +foo () +{ + bar (1); +} diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 51de6308a091..cea5e70dd75b 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -4139,12 +4139,17 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) perm_type = TREE_TYPE (orig[0]); /* Determine the element type for the conversion source. As orig_elem_type keeps track of the original type, check - if we need to perform a sign swap after permuting. */ + if we need to perform a sign swap after permuting. + We need to be able to construct a vector type from the element + type which is not possible for e.g. BitInt or pointers + so pun with an integer type if needed. */ tree conv_elem_type = TREE_TYPE (perm_type); if (conv_code != ERROR_MARK && orig_elem_type[0] - && tree_nop_conversion_p (orig_elem_type[0], conv_elem_type)) - conv_elem_type = orig_elem_type[0]; + && TYPE_SIGN (orig_elem_type[0]) != TYPE_SIGN (conv_elem_type)) + conv_elem_type = signed_or_unsigned_type_for (TYPE_UNSIGNED + (orig_elem_type[0]), + conv_elem_type); conv_src_type = build_vector_type (conv_elem_type, nelts); if (conv_code != ERROR_MARK && !supportable_convert_operation (conv_code, type, conv_src_type, @@ -4272,7 +4277,9 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) TYPE_SIZE (conv_code != ERROR_MARK ? conv_src_type : type), bitsize_zero_node); - /* Otherwise, we can still have an intermediate sign change. */ + /* Otherwise, we can still have an intermediate sign change. + ??? In that case we have two subsequent conversions. + We should be able to merge them. */ else if (conv_code != ERROR_MARK && tree_nop_conversion_p (conv_src_type, perm_type)) res = gimple_build (&stmts, VIEW_CONVERT_EXPR, conv_src_type, res);
