diff options
-rw-r--r-- | gcc/config/i386/i386-expand.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr114184.c | 22 |
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; +} |