On Thu, Aug 13, 2026 at 5:29 PM H.J. Lu <[email protected]> wrote:
>
> On Thu, Aug 13, 2026 at 3:11 PM Richard Biener
> <[email protected]> wrote:
> >
> > On Wed, Aug 12, 2026 at 4:16 PM H.J. Lu <[email protected]> wrote:
> > >
> > > On Tue, Aug 11, 2026 at 8:09 PM Richard Biener
> > > <[email protected]> wrote:
> > > >
> > > > On Tue, Aug 11, 2026 at 2:06 PM Richard Biener
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Tue, Aug 11, 2026 at 1:53 PM H.J. Lu <[email protected]> wrote:
> > > > > >
> > > > > > On Tue, Aug 11, 2026 at 7:20 PM Richard Biener
> > > > > > <[email protected]> wrote:
> > > > > > >
> > > > > > > On Tue, Aug 11, 2026 at 1:13 PM H.J. Lu <[email protected]>
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > "(type) minmax ((wide_type) a, (wide_type) b) to minmax (a, b)"
> > > > > > > > is limited
> > > > > > > > to the single use of the result. It doesn't support:
> > > > > > > >
> > > > > > > > typedef int v2si __attribute__((vector_size (8)));
> > > > > > > > typedef long long v2di __attribute__((vector_size (16)));
> > > > > > > >
> > > > > > > > v2si
> > > > > > > > func (v2si a, v2si b, v2di *p)
> > > > > > > > {
> > > > > > > > v2di x = __builtin_convertvector (a, v2di);
> > > > > > > > v2di y = __builtin_convertvector (b, v2di);
> > > > > > > > v2di z = x < y ? x : y;
> > > > > > > > *p = z;
> > > > > > > > return __builtin_convertvector (z, v2si);
> > > > > > > > }
> > > > > > > >
> > > > > > > > Change it to
> > > > > > > >
> > > > > > > > minmax ((wide_type) a, (wide_type) b) -> (wide_type) minmax (a,
> > > > > > > > b)
> > > > > > > >
> > > > > > > > instead and add "(type) ((wide_type) a) -> a" for integer
> > > > > > > > types. Now
> > > > > > > > we generate
> > > > > > > >
> > > > > > > > pminsd %xmm1, %xmm0
> > > > > > > > pmovsxdq %xmm0, %xmm1
> > > > > > > > movaps %xmm1, (%rdi)
> > > > > > > >
> > > > > > > > instead of
> > > > > > > >
> > > > > > > > pmovsxdq %xmm0, %xmm2
> > > > > > > > pmovsxdq %xmm1, %xmm1
> > > > > > > > movdqa %xmm2, %xmm0
> > > > > > > > movdqa %xmm2, %xmm3
> > > > > > > > pcmpgtq %xmm1, %xmm0
> > > > > > > > pblendvb %xmm0, %xmm1, %xmm3
> > > > > > > > movdqa %xmm3, %xmm0
> > > > > > > > movaps %xmm3, (%rdi)
> > > > > > > > shufps $232, %xmm3, %xmm0
> > > > > > > >
> > > > > > > > gcc/
> > > > > > >
> > > > > > > (simplify
> > > > > > > - (convert (minmax:c@4 (convert@2 @0) (convert@3 @1)))
> > > > > > > + (minmax:c (convert@2 @0) (convert@3 @1))
> > > > > > >
> > > > > > > no need for :c on minmax
> > > > > >
> > > > > > Removed.
> > > > > >
> > > > > > > (if (ANY_INTEGRAL_TYPE_P (type)
> > > > > > > - && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@2))
> > > > > > > - && types_match (type, TREE_TYPE (@0))
> > > > > > > - && types_match (type, TREE_TYPE (@1))
> > > > > > > - && types_match (TREE_TYPE (@2), TREE_TYPE (@3))
> > > > > > > - && element_precision (TREE_TYPE (@2)) > element_precision
> > > > > > > (type)
> > > > > > > - && TYPE_UNSIGNED (TREE_TYPE (@2)) == TYPE_UNSIGNED (type)
> > > > > > > + && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
> > > > > > > + && types_match (type, TREE_TYPE (@2))
> > > > > > > + && types_match (type, TREE_TYPE (@3))
> > > > > > >
> > > > > > > the last two are redundant
> > > > > >
> > > > > > Removed.
> > > > > >
> > > > > > > + && types_match (TREE_TYPE (@0), TREE_TYPE (@1))
> > > > > > > + && element_precision (TREE_TYPE (@0)) < element_precision
> > > > > > > (type)
> > > > > > > + && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (type)
> > > > > > >
> > > > > > > +/* (type) ((wide_type) a) -> a. */
> > > > > > > +(simplify
> > > > > > > + (convert (convert@1 @0))
> > > > > > > + (if (ANY_INTEGRAL_TYPE_P (type)
> > > > > > > + && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1))
> > > > > > > + && types_match (type, TREE_TYPE (@0))
> > > > > > > + && element_precision (type) < element_precision
> > > > > > > (TREE_TYPE (@1)))
> > > > > > > + @0))
> > > > > > >
> > > > > > > two-level conversions are already handled elsewhere, no need to
> > > > > > > add a
> > > > > > > new pattern.
> > > > > >
> > > > > > Where is it handled? Without it, I got
> > > > >
> > > > > It should be handled by
> > > > >
> > > > > /* Handle cases of two conversions in a row. */
> > > > > (for ocvt (convert float fix_trunc)
> > > > > (for icvt (convert float)
> > > > > (simplify
> > > > > (ocvt (icvt@1 @0))
> > > > > (with
> > > > > {
> > > > > ...
> > > > >
> > > > > Possibly
> > > > >
> > > > > /* In addition to the cases of two conversions in a row
> > > > > handled below, if we are converting something to its own
> > > > > type via an object of identical or wider precision, neither
> > > > > conversion is needed. */
> > > > > (if (((GIMPLE && useless_type_conversion_p (type, inside_type))
> > > > > || (GENERIC
> > > > > && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT
> > > > > (inside_type)))
> > > > > && (((inter_int || inter_ptr) && final_int)
> > > > > || (inter_float && final_float))
> > > > > && inter_prec >= final_prec)
> > > > > (ocvt @0))
> > > > >
> > > > > is too strict in that inter_int checks INTEGRAL_TYPE_P, not
> > > > > ANY_INTEGRAL_TYPE_P.
> > > > > To avoid adjusting everything I'd add inside_any_int, etc. variables,
> > > > > otherwise
> > > > > a conservative transform would be to use ANY_INTEGRAL_TYPE_P for
> > > > > inside_int, etc.
> > > > > and replace uses with inside_int && !inside_vec, omitting !inside_vec
> > > > > for cases we have
> > > > > convinced ourselves are fine.
> > > >
> > > > Just to say, inside_float and friends _do_ include vector float types
> > > > (and complex float types).
> > > > So consistency would ask for the use of ANY_INTEGRAL_TYPE and opting
> > > > out of vectors
> > > > (and complex?) explicitly where needed.
> > > >
> > >
> > > Here is the v2 patch. There are no regressions on Linux/x86-64.
> >
> > @@ -5856,7 +5853,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > (if (((inter_int && inside_int) || (inter_float && inside_float))
> > && (final_int || final_float)
> > && inter_prec >= inside_prec
> > - && (inter_float || inter_unsignedp == inside_unsignedp))
> > + && (inter_float
> > + || ((!inter_vec
> > + || target_supports_op_p (TREE_TYPE (@0), ocvt,
> > optab_vector))
> > + && inter_unsignedp == inside_unsignedp)))
> >
> > as you are touching this - since the inter_float also includes vector types
> > this
> > shows the patterns lack vector validation completely. Instead (note
> > inside_vec == inter_vec == final_vec in all cases) this should be
> >
> > && (!inter_vec || <... vector support check ...>)
> >
> > I'll note that target_suppoorts_op_p is not the correct check here as
> > conversion
> > support of course depends on both the source and the destination type. The
> > appropriate function to use should be
> >
> > supportable_convert_operation (ocvt, type, TREE_TYPE (@0), &vcode)
> >
> > the last argument is redundant, I'll remove it. Let me handle the
> > conversion
> > pattern adjustments, the minmax part of the patch is OK.
>
> I will wait for your adjustments. My minmax change triggered these
> issues. You can use my minmax change + tests to validate the
> adjustments.
>
Here is the v3 patch only with the minmax change. I am going to check it in.
--
H.J.
----
"(type) minmax ((wide_type) a, (wide_type) b) to minmax (a, b)" is limited
to the single use of the result. It doesn't support:
typedef int v2si __attribute__((vector_size (8)));
typedef long long v2di __attribute__((vector_size (16)));
v2si
func (v2si a, v2si b, v2di *p)
{
v2di x = __builtin_convertvector (a, v2di);
v2di y = __builtin_convertvector (b, v2di);
v2di z = x < y ? x : y;
*p = z;
return __builtin_convertvector (z, v2si);
}
Change it to
minmax ((wide_type) a, (wide_type) b) -> (wide_type) minmax (a, b)
instead. Now we generate
pminsd %xmm1, %xmm0
pmovsxdq %xmm0, %xmm1
movaps %xmm1, (%rdi)
instead of
pmovsxdq %xmm0, %xmm2
pmovsxdq %xmm1, %xmm1
movdqa %xmm2, %xmm0
movdqa %xmm2, %xmm3
pcmpgtq %xmm1, %xmm0
pblendvb %xmm0, %xmm1, %xmm3
movdqa %xmm3, %xmm0
movaps %xmm3, (%rdi)
shufps $232, %xmm3, %xmm0
gcc/
PR middle-end/126784
* match.pd ((type) minmax ((wide_type) a, (wide_type) b)): Changed
to ...
(minmax ((wide_type) a, (wide_type) b)): This.
gcc/testsuite/
PR middle-end/126784
* g++.dg/tree-ssa/vec-narrow-1.C: Use -msse4 and require int128
for x86.
* g++.dg/tree-ssa/vec-narrow-minmax-2.C: Likewise.
* g++.target/i386/pr126784-1.C: New test.
* g++.target/i386/pr126784-2.C: Likewise.
* gcc.target/i386/pr126784-1.c: Likewise.
* gcc.target/i386/pr126784-2.c: Likewise.
* gcc.target/i386/pr126784-3.c: Likewise.
* gcc.target/i386/pr126784-4.c: Likewise.
* gcc.target/i386/pr126784-5.c: Likewise.
* gcc.target/i386/pr126784-6.c: Likewise.
From ded12acff16364f7e93c2aef0bba4013fc60b857 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Tue, 11 Aug 2026 12:39:54 +0800
Subject: [PATCH v3] match.pd: Change the MIN/MAX narrowing to MIN/MAX +
convert
"(type) minmax ((wide_type) a, (wide_type) b) to minmax (a, b)" is limited
to the single use of the result. It doesn't support:
typedef int v2si __attribute__((vector_size (8)));
typedef long long v2di __attribute__((vector_size (16)));
v2si
func (v2si a, v2si b, v2di *p)
{
v2di x = __builtin_convertvector (a, v2di);
v2di y = __builtin_convertvector (b, v2di);
v2di z = x < y ? x : y;
*p = z;
return __builtin_convertvector (z, v2si);
}
Change it to
minmax ((wide_type) a, (wide_type) b) -> (wide_type) minmax (a, b)
instead. Now we generate
pminsd %xmm1, %xmm0
pmovsxdq %xmm0, %xmm1
movaps %xmm1, (%rdi)
instead of
pmovsxdq %xmm0, %xmm2
pmovsxdq %xmm1, %xmm1
movdqa %xmm2, %xmm0
movdqa %xmm2, %xmm3
pcmpgtq %xmm1, %xmm0
pblendvb %xmm0, %xmm1, %xmm3
movdqa %xmm3, %xmm0
movaps %xmm3, (%rdi)
shufps $232, %xmm3, %xmm0
gcc/
PR middle-end/126784
* match.pd ((type) minmax ((wide_type) a, (wide_type) b)): Changed
to ...
(minmax ((wide_type) a, (wide_type) b)): This.
gcc/testsuite/
PR middle-end/126784
* g++.dg/tree-ssa/vec-narrow-1.C: Use -msse4 and require int128
for x86.
* g++.dg/tree-ssa/vec-narrow-minmax-2.C: Likewise.
* g++.target/i386/pr126784-1.C: New test.
* g++.target/i386/pr126784-2.C: Likewise.
* gcc.target/i386/pr126784-1.c: Likewise.
* gcc.target/i386/pr126784-2.c: Likewise.
* gcc.target/i386/pr126784-3.c: Likewise.
* gcc.target/i386/pr126784-4.c: Likewise.
* gcc.target/i386/pr126784-5.c: Likewise.
* gcc.target/i386/pr126784-6.c: Likewise.
Signed-off-by: H.J. Lu <[email protected]>
---
gcc/match.pd | 19 ++++++-------
gcc/testsuite/g++.dg/tree-ssa/vec-narrow-1.C | 3 +-
.../g++.dg/tree-ssa/vec-narrow-minmax-2.C | 2 ++
gcc/testsuite/g++.target/i386/pr126784-1.C | 26 +++++++++++++++++
gcc/testsuite/g++.target/i386/pr126784-2.C | 28 +++++++++++++++++++
gcc/testsuite/gcc.target/i386/pr126784-1.c | 24 ++++++++++++++++
gcc/testsuite/gcc.target/i386/pr126784-2.c | 27 ++++++++++++++++++
gcc/testsuite/gcc.target/i386/pr126784-3.c | 11 ++++++++
gcc/testsuite/gcc.target/i386/pr126784-4.c | 26 +++++++++++++++++
gcc/testsuite/gcc.target/i386/pr126784-5.c | 21 ++++++++++++++
gcc/testsuite/gcc.target/i386/pr126784-6.c | 25 +++++++++++++++++
11 files changed, 200 insertions(+), 12 deletions(-)
create mode 100644 gcc/testsuite/g++.target/i386/pr126784-1.C
create mode 100644 gcc/testsuite/g++.target/i386/pr126784-2.C
create mode 100644 gcc/testsuite/gcc.target/i386/pr126784-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr126784-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr126784-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr126784-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr126784-5.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr126784-6.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 02684d8a302..8841464fa1a 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4714,7 +4714,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& !TYPE_OVERFLOW_SANITIZED (type))
(minus (minmax @0 @1) @2))))
-/* (type) minmax ((wide_type) a, (wide_type) b) -> minmax (a, b)
+/* minmax ((wide_type) a, (wide_type) b) -> (wide_type) minmax (a, b)
when type matches the type of a and b, and wide_type is a wider
type with the same signedness as type. Extension is monotone, so it
commutes with the comparison, and the truncation is then exact. The
@@ -4724,18 +4724,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(for minmax (min max)
MINMAX (MIN_EXPR MAX_EXPR)
(simplify
- (convert (minmax:c@4 (convert@2 @0) (convert@3 @1)))
+ (minmax (convert @0) (convert @1))
(if (ANY_INTEGRAL_TYPE_P (type)
- && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@2))
- && types_match (type, TREE_TYPE (@0))
- && types_match (type, TREE_TYPE (@1))
- && types_match (TREE_TYPE (@2), TREE_TYPE (@3))
- && element_precision (TREE_TYPE (@2)) > element_precision (type)
- && TYPE_UNSIGNED (TREE_TYPE (@2)) == TYPE_UNSIGNED (type)
+ && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && types_match (TREE_TYPE (@0), TREE_TYPE (@1))
+ && element_precision (TREE_TYPE (@0)) < element_precision (type)
+ && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (type)
&& (!VECTOR_TYPE_P (type)
- || (single_use (@4)
- && target_supports_op_p (type, MINMAX, optab_vector))))
- (minmax @0 @1))))
+ || target_supports_op_p (TREE_TYPE (@0), MINMAX, optab_vector)))
+ (convert (minmax @0 @1)))))
/* max (a, a + CST) -> a + CST where CST is positive. */
/* max (a, a + CST) -> a where CST is negative. */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-1.C b/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-1.C
index cec5b0ba345..1f863b1d4a2 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-1.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-1.C
@@ -1,6 +1,7 @@
// { dg-do compile }
// { dg-options "-O2 -fdump-tree-optimized" }
-// { dg-additional-options "-mavx512vl -mavx512dq" { target { i?86-*-* x86_64-*-* } } }
+// { dg-additional-options "-msse4" { target { i?86-*-* x86_64-*-* } } }
+// { dg-require-effective-target int128 { target { i?86-*-* x86_64-*-* } } }
// Extension is monotone, so it commutes with the comparison and the outer
// truncation is exact. The argument is lanewise, so a widened vector
// MIN/MAX feeding a truncating conversion narrows.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-minmax-2.C b/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-minmax-2.C
index d7fb7f06f16..7df25de0942 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-minmax-2.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/vec-narrow-minmax-2.C
@@ -1,5 +1,7 @@
// { dg-do compile }
// { dg-options "-O2 -fdump-tree-optimized" }
+// { dg-additional-options "-msse4" { target { i?86-*-* x86_64-*-* } } }
+// { dg-require-effective-target int128 { target { i?86-*-* x86_64-*-* } } }
typedef int v2si __attribute__((vector_size (8)));
typedef long long v2di __attribute__((vector_size (16)));
diff --git a/gcc/testsuite/g++.target/i386/pr126784-1.C b/gcc/testsuite/g++.target/i386/pr126784-1.C
new file mode 100644
index 00000000000..611d67ed37a
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr126784-1.C
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -march=x86-64 -msse4 -std=c++17" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**_Z4funcDv2_iS_:
+**.LFB0:
+** .cfi_startproc
+** pminsd %xmm1, %xmm0
+** ret
+** .cfi_endproc
+**...
+*/
+
+typedef int v2si __attribute__((vector_size (8)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+v2si
+func (v2si a, v2si b)
+{
+ v2di x = __builtin_convertvector (a, v2di);
+ v2di y = __builtin_convertvector (b, v2di);
+ v2di z = x < y ? x : y;
+ return __builtin_convertvector (z, v2si);
+}
diff --git a/gcc/testsuite/g++.target/i386/pr126784-2.C b/gcc/testsuite/g++.target/i386/pr126784-2.C
new file mode 100644
index 00000000000..d93762f95dd
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr126784-2.C
@@ -0,0 +1,28 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -march=x86-64 -msse4 -std=c++17" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**_Z4funcDv2_iS_PDv2_x:
+**.LFB0:
+** .cfi_startproc
+** pminsd %xmm1, %xmm0
+** pmovsxdq %xmm0, %xmm1
+** movaps %xmm1, \(%[er]di\)
+** ret
+**...
+*/
+
+typedef int v2si __attribute__((vector_size (8)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+v2si
+func (v2si a, v2si b, v2di *p)
+{
+ v2di x = __builtin_convertvector (a, v2di);
+ v2di y = __builtin_convertvector (b, v2di);
+ v2di z = x < y ? x : y;
+ *p = z;
+ return __builtin_convertvector (z, v2si);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126784-1.c b/gcc/testsuite/gcc.target/i386/pr126784-1.c
new file mode 100644
index 00000000000..73b581b0e7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126784-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+** .cfi_startproc
+** cmpl %esi, %edi
+** movl %esi, %eax
+** cmovle %edi, %eax
+** ret
+**...
+*/
+
+int
+func (int a, int b)
+{
+ long long int x = a;
+ long long int y = b;
+ long long int z = x < y ? x : y;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126784-2.c b/gcc/testsuite/gcc.target/i386/pr126784-2.c
new file mode 100644
index 00000000000..660e98c76f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126784-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+** .cfi_startproc
+** cmpl %esi, %edi
+** movl %esi, %eax
+** cmovle %edi, %eax
+** movslq %eax, %rcx
+** movq %rcx, \(%[er]dx\)
+** ret
+**...
+*/
+
+int
+func (int a, int b, long long int *p)
+{
+ long long int x = a;
+ long long int y = b;
+ long long int z = x < y ? x : y;
+ *p = z;
+ return z;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126784-3.c b/gcc/testsuite/gcc.target/i386/pr126784-3.c
new file mode 100644
index 00000000000..928140e64ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126784-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+extern char *var1;
+extern int var2;
+
+void
+func (void)
+{
+ var2 = var1[1] + var1[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126784-4.c b/gcc/testsuite/gcc.target/i386/pr126784-4.c
new file mode 100644
index 00000000000..e344480c3ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126784-4.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+** .cfi_startproc
+** movdqa .LC0\(%rip\), %xmm0
+** movups %xmm0, var\(%rip\)
+** movdqa .LC1\(%rip\), %xmm0
+** movups %xmm0, var\+16\(%rip\)
+** ret
+**...
+*/
+
+extern unsigned int var[8];
+
+void
+func (void)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ var[i] = (float) i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126784-5.c b/gcc/testsuite/gcc.target/i386/pr126784-5.c
new file mode 100644
index 00000000000..3b6a26e2e70
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126784-5.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+** .cfi_startproc
+** movl \$34, var\(%rip\)
+** ret
+**...
+*/
+
+extern unsigned int var;
+
+void
+func (void)
+{
+ var = (float) 34;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126784-6.c b/gcc/testsuite/gcc.target/i386/pr126784-6.c
new file mode 100644
index 00000000000..403239039c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126784-6.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+** .cfi_startproc
+** movl %edi, %edi
+** pxor %xmm0, %xmm0
+** cvtsi2ssq %rdi, %xmm0
+** cvttss2siq %xmm0, %rax
+** movl %eax, var\(%rip\)
+** ret
+**...
+*/
+
+extern unsigned int var;
+
+void
+func (unsigned int i)
+{
+ var = (float) i;
+}
--
2.55.0