On Fri, Aug 14, 2026 at 6:33 PM Richard Biener <[email protected]> wrote:
>
> On Fri, 14 Aug 2026, H.J. Lu wrote:
>
> > On Fri, Aug 14, 2026 at 12:06 PM H.J. Lu <[email protected]> wrote:
> > >
> > > On Fri, Aug 14, 2026 at 11:59 AM H.J. Lu <[email protected]> wrote:
> > > >
> > > > On Thu, Aug 13, 2026 at 9:09 PM Richard Biener <[email protected]>
> > > > wrote:
> > > > >
> > > > > The last match.pd update for double-conversion folding didn't handle
> > > > > the case where a vector conversion would go away because
> > > > > supportable_convert_operation doesn't consider a noop conversion
> > > > > (or a sign conversion). The following rectifies this, allowing
> > > > > a NOP_EXPR and VIEW_CONVERT_EXPR for same mode types as supportable
> > > > > conversion as we can RTL expand that just fine.
> > > > >
> > > > > Bootstrap and regtest running on x86_64-unknown-linux-gnu.
> > > > >
> > > > > I'll note that the .VEC_CONVERT IFNs from initial
> > > > > __builtin_convertvector
> > > > > lowering survive unfolded until the veclower pass where, if the
> > > > > conversions are not supported, they will be open-coded and not
> > > > > folded either. I wonder why we chose to expand to .VEC_CONVERT
> > > > > instead of using FLOAT_EXPR/FIX_TRUNC_EXPR/NOP_EXPR as appropriate
> > > > > and lower those if not supported? At least I don't look forward to
> > > > > add .VEC_CONVERT support to all conversion foldings?
> > > > >
> > > > > I'll also note that the guards I put in place when adding
> > > > > vector integer support to double-conversion folding will now
> > > > > pessimize the case where neither (one of?) the former nor the
> > > > > new conversion would be supported because of the type not
> > > > > having vector mode.
> > > > >
> > > > > PR middle-end/126788
> > > > > * optabs-tree.cc (supportable_convert_operation): For same
> > > > > modes allow NOP_EXPR and VIEW_CONVERT_EXPR.
> > > > >
> > > > > * gcc.target/i386/pr126788.c: New testcase.
> > > > > ---
> > > > > gcc/optabs-tree.cc | 4 ++++
> > > > > gcc/testsuite/gcc.target/i386/pr126788.c | 24
> > > > > ++++++++++++++++++++++++
> > > > > 2 files changed, 28 insertions(+)
> > > > > create mode 100644 gcc/testsuite/gcc.target/i386/pr126788.c
> > > > >
> > > > > diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc
> > > > > index 5fbdcd3a730..5360a509f8d 100644
> > > > > --- a/gcc/optabs-tree.cc
> > > > > +++ b/gcc/optabs-tree.cc
> > > > > @@ -375,6 +375,10 @@ supportable_convert_operation (enum tree_code
> > > > > code,
> > > > > if (!VECTOR_MODE_P (m1) || !VECTOR_MODE_P (m2))
> > > > > return false;
> > > > >
> > > > > + if (m1 == m2
> > > > > + && (CONVERT_EXPR_CODE_P (code) || code == VIEW_CONVERT_EXPR))
> > > > > + return true;
> > > > > +
> > > > > /* First check if we can done conversion directly. */
> > > > > if ((code == FIX_TRUNC_EXPR
> > > > > && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)
> > > > > diff --git a/gcc/testsuite/gcc.target/i386/pr126788.c
> > > > > b/gcc/testsuite/gcc.target/i386/pr126788.c
> > > > > new file mode 100644
> > > > > index 00000000000..0448284e8f6
> > > > > --- /dev/null
> > > > > +++ b/gcc/testsuite/gcc.target/i386/pr126788.c
> > > > > @@ -0,0 +1,24 @@
> > > > > +/* { dg-do compile } */
> > > > > +/* { dg-options "-O -msse2" } */
> > > > > +
> > > > > +typedef int v2si __attribute__((vector_size (8)));
> > > > > +typedef unsigned int v2usi __attribute__((vector_size (8)));
> > > > > +typedef long long v2di __attribute__((vector_size (16)));
> > > > > +
> > > > > +v2si
> > > > > +f1 (v2si a, v2si b)
> > > > > +{
> > > > > +
> > > > > + v2di z = __builtin_convertvector (a, v2di);
> > > > > + return __builtin_convertvector (z, v2si);
> > > > > +}
> > > > > +
> > > > > +v2usi
> > > > > +f2 (v2si a, v2si b)
> > > > > +{
> > > > > +
> > > > > + v2di z = __builtin_convertvector (a, v2di);
> > > > > + return __builtin_convertvector (z, v2usi);
> > > > > +}
> > > > > +
> > > > > +/* { dg-final { scan-assembler-not "xmm" { target { ! ia32 } } } } */
> > > > > --
> > > >
> > > > I think this may cause:
> > > >
> > > > FAIL: gcc.dg/bitint-98.c 1 blank line(s) in output
> > > > FAIL: gcc.dg/bitint-98.c 1 blank line(s) in output
> > > > FAIL: gcc.dg/bitint-98.c (internal compiler error: verify_gimple failed)
> > > > FAIL: gcc.dg/bitint-98.c (internal compiler error: verify_gimple failed)
> > > > FAIL: gcc.dg/bitint-98.c (test for excess errors)
> > > > FAIL: gcc.dg/bitint-98.c (test for excess errors)
> > > > FAIL: gcc.dg/torture/bitint-16.c -O2 2 blank line(s) in output
> > > > FAIL: gcc.dg/torture/bitint-16.c -O2 2 blank line(s) in output
> > > > FAIL: gcc.dg/torture/bitint-16.c -O2 (internal compiler error:
> > > > verify_gimple failed)
> > > > FAIL: gcc.dg/torture/bitint-16.c -O2 (internal compiler error:
> > > > verify_gimple failed)
> > > > FAIL: gcc.dg/torture/bitint-16.c -O2 (test for excess errors)
> > > > FAIL: gcc.dg/torture/bitint-16.c -O2 (test for excess errors)
> > > > FAIL: gcc.dg/vect/vect-over-widen-23.c -flto -ffat-lto-objects
> > > > scan-tree-dump vect "VIEW_CONVERT_EXPR<vector[^ ]* unsigned"
> > > > FAIL: gcc.dg/vect/vect-over-widen-23.c -flto -ffat-lto-objects
> > > > scan-tree-dump vect "VIEW_CONVERT_EXPR<vector[^ ]* unsigned"
> > > > FAIL: gcc.dg/vect/vect-over-widen-23.c scan-tree-dump vect
> > > > "VIEW_CONVERT_EXPR<vector[^ ]* unsigned"
> > > > FAIL: gcc.dg/vect/vect-over-widen-23.c scan-tree-dump vect
> > > > "VIEW_CONVERT_EXPR<vector[^ ]* unsigned"
> > > > FAIL: gcc.target/i386/avx512f-pr114157.c 1 blank line(s) in output
> > > > FAIL: gcc.target/i386/avx512f-pr114157.c 1 blank line(s) in output
> > > > FAIL: gcc.target/i386/avx512f-pr114157.c (internal compiler error:
> > > > verify_gimple failed)
> > > > FAIL: gcc.target/i386/avx512f-pr114157.c (internal compiler error:
> > > > verify_gimple failed)
> > > > FAIL: gcc.target/i386/avx512f-pr114157.c (test for excess errors)
> > > > FAIL: gcc.target/i386/avx512f-pr114157.c (test for excess errors)
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_d-1.c scan-tree-dump optimized
> > > > ".COND_ADD"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_d-1.c scan-tree-dump optimized
> > > > ".COND_ADD"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_d-1.c scan-tree-dump optimized
> > > > ".COND_MUL"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_d-1.c scan-tree-dump optimized
> > > > ".COND_MUL"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_d-1.c scan-tree-dump optimized
> > > > ".COND_SUB"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_d-1.c scan-tree-dump optimized
> > > > ".COND_SUB"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_q-1.c scan-tree-dump optimized
> > > > ".COND_ADD"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_q-1.c scan-tree-dump optimized
> > > > ".COND_MUL"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_q-1.c scan-tree-dump optimized
> > > > ".COND_SUB"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_w-1.c scan-tree-dump optimized
> > > > ".COND_ADD"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_w-1.c scan-tree-dump optimized
> > > > ".COND_ADD"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_w-1.c scan-tree-dump optimized
> > > > ".COND_MUL"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_w-1.c scan-tree-dump optimized
> > > > ".COND_MUL"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_w-1.c scan-tree-dump optimized
> > > > ".COND_SUB"
> > > > FAIL: gcc.target/i386/cond_op_addsubmul_w-1.c scan-tree-dump optimized
> > > > ".COND_SUB"
> > > > FAIL: gfortran.dg/bind-c-contiguous-3.f90 -O3 -fomit-frame-pointer
> > > > -funroll-loops -fpeel-loops -ftracer -finline-functions (internal
> > > > compiler error: verify_gimple failed)
> > > > FAIL: gfortran.dg/bind-c-contiguous-3.f90 -O3 -fomit-frame-pointer
> > > > -funroll-loops -fpeel-loops -ftracer -finline-functions (test for
> > > > excess errors)
> > > > FAIL: gfortran.dg/intrinsic_ifunction_1.f90 -O3 -fomit-frame-pointer
> > > > -funroll-loops -fpeel-loops -ftracer -finline-functions (internal
> > > > compiler error: verify_gimple failed)
> > > > FAIL: gfortran.dg/intrinsic_ifunction_1.f90 -O3 -fomit-frame-pointer
> > > > -funroll-loops -fpeel-loops -ftracer -finline-functions (test for
> > > > excess errors)
> > > >
> > > > with
> > > >
> > > > $ make check RUNTESTFLAGS="--target_board='unix{-m32\
> > > > -march=x86-64-v4}'"
> > > >
> > > > --
> > > > H.J.
> > >
> > > Also
> > >
> > > $ make check RUNTESTFLAGS="--target_board='unix{-march=x86-64-v4}'"
> > >
> >
> > This seems to avoid ICE:
> >
> > diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> > index 55bd8aee5f8..bd44a4e63bf 100644
> > --- a/gcc/tree-ssa-forwprop.cc
> > +++ b/gcc/tree-ssa-forwprop.cc
> > @@ -4256,7 +4256,9 @@ simplify_vector_constructor (gimple_stmt_iterator
> > *gsi)
> > tree mask_type, perm_type;
> > perm_type = TREE_TYPE (orig[0]);
> > if (conv_code != ERROR_MARK
> > - && !supportable_convert_operation (conv_code, type, conv_src_type))
> > + && ((type == conv_src_type && refnelts != nelts)
> > + || !supportable_convert_operation (conv_code, type,
> > + conv_src_type)))
> > return false;
> >
> > /* Now that we know the number of elements of the source build the
>
> This is better:
>
> diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> index 55bd8aee5f8..0044293b7c5 100644
> --- a/gcc/tree-ssa-forwprop.cc
> +++ b/gcc/tree-ssa-forwprop.cc
> @@ -4363,6 +4363,7 @@ simplify_vector_constructor (gimple_stmt_iterator
> *gsi)
> /* For a real orig[1] (no splat, constant etc.) we might need to
> nop-convert it. Do so here. */
> if (orig[1] && orig[1] != error_mark_node
> + && !converted_orig1
> && !useless_type_conversion_p (perm_type, TREE_TYPE (orig[1]))
> && tree_nop_conversion_p (TREE_TYPE (perm_type),
> TREE_TYPE (TREE_TYPE (orig[1]))))
>
> I still have to investigate the other testsuite fails.
>
Some of the test failures I saw above require
$ make check RUNTESTFLAGS="--target_board='unix{-m32\
-march=znver4,-march=znver4}"
--
H.J.