[v2] Explicitly view_convert_expr mask to signed type when folding pblendvb builtins.
Checks
Commit Message
> I think this is a better patch and will always be correct and still
> get folded at the gimple level (correctly):
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index d4ff56ee8dd..02bf5ba93a5 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -18561,8 +18561,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
> ? intSI_type_node : intDI_type_node;
> type = get_same_sized_vectype (itype, type);
> - arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
> }
> + else
> + type = signed_type_for (type);
> + arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
> tree zero_vec = build_zero_cst (type);
> tree cmp_type = truth_type_for (type);
> tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
>
>
Yes, thanks.
Here's the updated patch:
Since mask < 0 will be always false for vector char when
-funsigned-char, but vpblendvb needs to check the most significant
bit. The patch explicitly VCE to vector signed char.
gcc/ChangeLog:
PR target/110108
* config/i386/i386.cc (ix86_gimple_fold_builtin): Explicitly
view_convert_expr mask to signed type when folding pblendvb
builtins.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr110108-2.c: New test.
---
gcc/config/i386/i386.cc | 4 +++-
gcc/testsuite/gcc.target/i386/pr110108-2.c | 14 ++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr110108-2.c
Comments
On Tue, Jun 6, 2023 at 4:23 PM liuhongt <hongtao.liu@intel.com> wrote:
>
> > I think this is a better patch and will always be correct and still
> > get folded at the gimple level (correctly):
> > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> > index d4ff56ee8dd..02bf5ba93a5 100644
> > --- a/gcc/config/i386/i386.cc
> > +++ b/gcc/config/i386/i386.cc
> > @@ -18561,8 +18561,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> > tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
> > ? intSI_type_node : intDI_type_node;
> > type = get_same_sized_vectype (itype, type);
> > - arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
> > }
> > + else
> > + type = signed_type_for (type);
> > + arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
> > tree zero_vec = build_zero_cst (type);
> > tree cmp_type = truth_type_for (type);
> > tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
> >
> >
>
> Yes, thanks.
>
> Here's the updated patch:
>
> Since mask < 0 will be always false for vector char when
> -funsigned-char, but vpblendvb needs to check the most significant
> bit. The patch explicitly VCE to vector signed char.
>
Pushed to trunk and backport to GCC-13/GCC-12 release branch.(No need
for GCC-11 and earlier since the bug is introduced in GCC12).
>
> gcc/ChangeLog:
>
> PR target/110108
> * config/i386/i386.cc (ix86_gimple_fold_builtin): Explicitly
> view_convert_expr mask to signed type when folding pblendvb
> builtins.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr110108-2.c: New test.
> ---
> gcc/config/i386/i386.cc | 4 +++-
> gcc/testsuite/gcc.target/i386/pr110108-2.c | 14 ++++++++++++++
> 2 files changed, 17 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/gcc.target/i386/pr110108-2.c
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index da20c2c49de..4e594a9c88e 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -18561,8 +18561,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
> ? intSI_type_node : intDI_type_node;
> type = get_same_sized_vectype (itype, type);
> - arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
> }
> + else
> + type = signed_type_for (type);
> + arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
> tree zero_vec = build_zero_cst (type);
> tree cmp_type = truth_type_for (type);
> tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
> diff --git a/gcc/testsuite/gcc.target/i386/pr110108-2.c b/gcc/testsuite/gcc.target/i386/pr110108-2.c
> new file mode 100644
> index 00000000000..2d1d2fd4991
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr110108-2.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mavx2 -O2 -funsigned-char" } */
> +/* { dg-final { scan-assembler-times "vpblendvb" 2 } } */
> +
> +#include <immintrin.h>
> +__m128i do_stuff_128(__m128i X0, __m128i X1, __m128i X2) {
> + __m128i Result = _mm_blendv_epi8(X0, X1, X2);
> + return Result;
> +}
> +
> +__m256i do_stuff_256(__m256i X0, __m256i X1, __m256i X2) {
> + __m256i Result = _mm256_blendv_epi8(X0, X1, X2);
> + return Result;
> +}
> --
> 2.39.1.388.g2fc9e9ca3c
>
@@ -18561,8 +18561,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
? intSI_type_node : intDI_type_node;
type = get_same_sized_vectype (itype, type);
- arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
}
+ else
+ type = signed_type_for (type);
+ arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
tree zero_vec = build_zero_cst (type);
tree cmp_type = truth_type_for (type);
tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx2 -O2 -funsigned-char" } */
+/* { dg-final { scan-assembler-times "vpblendvb" 2 } } */
+
+#include <immintrin.h>
+__m128i do_stuff_128(__m128i X0, __m128i X1, __m128i X2) {
+ __m128i Result = _mm_blendv_epi8(X0, X1, X2);
+ return Result;
+}
+
+__m256i do_stuff_256(__m256i X0, __m256i X1, __m256i X2) {
+ __m256i Result = _mm256_blendv_epi8(X0, X1, X2);
+ return Result;
+}