aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/i386-expand.cc14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr114184.c22
2 files changed, 36 insertions, 0 deletions
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index c98e0f8..3b1685a 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -451,6 +451,20 @@ ix86_expand_move (machine_mode mode, rtx operands[])
&& GET_MODE (SUBREG_REG (op1)) == DImode
&& SUBREG_BYTE (op1) == 0)
op1 = gen_rtx_ZERO_EXTEND (TImode, SUBREG_REG (op1));
+ /* As not all values in XFmode are representable in real_value,
+ we might be called with unfoldable SUBREGs of constants. */
+ if (mode == XFmode
+ && CONSTANT_P (SUBREG_REG (op1))
+ && can_create_pseudo_p ())
+ {
+ machine_mode imode = GET_MODE (SUBREG_REG (op1));
+ rtx r = force_const_mem (imode, SUBREG_REG (op1));
+ if (r)
+ r = validize_mem (r);
+ else
+ r = force_reg (imode, SUBREG_REG (op1));
+ op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
+ }
break;
}
diff --git a/gcc/testsuite/gcc.target/i386/pr114184.c b/gcc/testsuite/gcc.target/i386/pr114184.c
new file mode 100644
index 0000000..360b3b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114184.c
@@ -0,0 +1,22 @@
+/* PR target/114184 */
+/* { dg-do compile } */
+/* { dg-options "-Og -mavx2" } */
+
+typedef unsigned char V __attribute__((vector_size (32)));
+typedef unsigned char W __attribute__((vector_size (16)));
+
+_Complex long double
+foo (void)
+{
+ _Complex long double d;
+ *(V *)&d = (V) { 149, 136, 89, 42, 38, 240, 196, 194 };
+ return d;
+}
+
+long double
+bar (void)
+{
+ long double d;
+ *(W *)&d = (W) { 149, 136, 89, 42, 38, 240, 196, 194 };
+ return d;
+}