diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2007-05-26 00:36:10 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2007-05-26 00:36:10 +0200 |
commit | 4d2a42a1f639e644da9f14af8bb895f7f0710a0c (patch) | |
tree | d2ea079379840422a1a173736a1a1f4988842dc9 /gcc/config | |
parent | 5b98f74d38bb1ec9dfbeedd7d2d39d4e22a37d34 (diff) | |
download | gcc-4d2a42a1f639e644da9f14af8bb895f7f0710a0c.zip gcc-4d2a42a1f639e644da9f14af8bb895f7f0710a0c.tar.gz gcc-4d2a42a1f639e644da9f14af8bb895f7f0710a0c.tar.bz2 |
re PR target/32065 (Many dfp testsuite failures for -msse targets)
PR target/32065
* target/i386/i386.c (ix86_expand_vector_move): Force SUBREGs of
constants into memory. Expand unaligned memory references for
SSE modes via x86_expand_vector_move_misalign() function.
testsuite/ChangeLog:
PR target/32065
* gcc.target/i386/pr32065.c: New test.
From-SVN: r125077
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ca5df2d..dae841c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9727,6 +9727,7 @@ void ix86_expand_vector_move (enum machine_mode mode, rtx operands[]) { rtx op0 = operands[0], op1 = operands[1]; + unsigned int align = GET_MODE_ALIGNMENT (mode); /* Force constants other than zero into memory. We do not know how the instructions used to build constants modify the upper 64 bits @@ -9734,10 +9735,39 @@ ix86_expand_vector_move (enum machine_mode mode, rtx operands[]) to handle some of them more efficiently. */ if ((reload_in_progress | reload_completed) == 0 && register_operand (op0, mode) - && CONSTANT_P (op1) + && (CONSTANT_P (op1) + || (GET_CODE (op1) == SUBREG + && CONSTANT_P (SUBREG_REG (op1)))) && standard_sse_constant_p (op1) <= 0) op1 = validize_mem (force_const_mem (mode, op1)); + /* TDmode values are passed as TImode on the stack. Timode values + are moved via xmm registers, and moving them to stack can result in + unaligned memory access. Use ix86_expand_vector_move_misalign() + if memory operand is not aligned correctly. */ + if (!no_new_pseudos + && SSE_REG_MODE_P (mode) + && ((MEM_P (op0) && (MEM_ALIGN (op0) < align)) + || (MEM_P (op1) && (MEM_ALIGN (op1) < align)))) + { + rtx tmp[2]; + + /* ix86_expand_vector_move_misalign() does not like constants ... */ + if (CONSTANT_P (op1) + || (GET_CODE (op1) == SUBREG + && CONSTANT_P (SUBREG_REG (op1)))) + op1 = validize_mem (force_const_mem (mode, op1)); + + /* ... nor both arguments in memory. */ + if (!register_operand (op0, mode) + && !register_operand (op1, mode)) + op1 = force_reg (mode, op1); + + tmp[0] = op0; tmp[1] = op1; + ix86_expand_vector_move_misalign (mode, tmp); + return; + } + /* Make operand1 a register if it isn't already. */ if (!no_new_pseudos && !register_operand (op0, mode) |