diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2016-01-15 15:42:40 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-01-29 07:57:56 -0800 |
commit | 32da7a3306d31568f6e12aa95f36279e122454ec (patch) | |
tree | 2eb7bb6a4200b503171a9ea7fab7af6109f24dde | |
parent | 4758dc397a505efc8cd7df72dd1547376400cdc9 (diff) | |
download | gcc-32da7a3306d31568f6e12aa95f36279e122454ec.tar.gz |
Use define_memory_constraint on Bm constraint
Given
(insn 144 143 145 21 (set (reg:V2DF 253 [ vect__24.23 ])
(float_extend:V2DF (vec_select:V2SF (reg:V4SF 254)
(parallel [
(const_int 0 [0])
(const_int 1 [0x1])
])))) x.i:10 2440 {sse2_cvtps2pd}
(nil))
which matches
[(set (match_operand:V2DF 0 "register_operand" "=v")
(float_extend:V2DF
(vec_select:V2SF
(match_operand:V4SF 1 "vector_operand" "vBm")
(parallel [(const_int 0) (const_int 1)]))))]
LRA doesn't consider that the Bm constraint is an alternative match for
(reg:V4SF 254) since it isn't a memory constraint. Change Bm to a
memory constraint fixes this issue.
However documentation says that define_memory_constraint is for MEM
constraints where if they are not satisfied they can be made to satisfy
by forcing the address into a register. But that is not the case here,
if a MEM is misaligned, no equivalent changes to the XEXP (mem, 0) will
make it aligned. This restriction shows up in LRA process_alt_operands.
This patch also changes LRA to skip bad MEM. Although there are no
regressions on x86-64, there could be latent issues.
gcc/
PR target/69299
* lra-constraints.c (process_alt_operands): Skip bad memory
operand.
* config/i386/constraints.md (Bm): Use define_memory_constraint.
gcc/testsuite/
PR target/69299
* gcc.target/i386/pr69299.c: New test.
-rw-r--r-- | gcc/config/i386/constraints.md | 2 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr69299.c | 16 |
3 files changed, 25 insertions, 3 deletions
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 3b0b7c79dc1..49e74af318b 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -162,7 +162,7 @@ "@internal GOT memory operand." (match_operand 0 "GOT_memory_operand")) -(define_constraint "Bm" +(define_memory_constraint "Bm" "@internal Vector memory operand." (match_operand 0 "vector_memory_operand")) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index fb194165d49..d445f8fa75b 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2010,8 +2010,14 @@ process_alt_operands (int only_alternative) if (MEM_P (op) && satisfies_memory_constraint_p (op, cn)) win = true; - else if (spilled_pseudo_p (op)) - win = true; + else + { + if (MEM_P (op)) + /* Skip bad memory operand. */ + break; + if (spilled_pseudo_p (op)) + win = true; + } /* If we didn't already win, we can reload constants via force_const_mem or put the pseudo value into diff --git a/gcc/testsuite/gcc.target/i386/pr69299.c b/gcc/testsuite/gcc.target/i386/pr69299.c new file mode 100644 index 00000000000..0d44969f3b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr69299.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-Ofast -mno-avx -msse2 -mtune=bdver2" } */ + +float *a, *b; +int c, d, e, f; +void +foo (void) +{ + for (; c; c++) + a[c] = 0; + if (!d) + for (; c < f; c++) + b[c] = (double) e / b[c]; +} + +/* { dg-final { scan-assembler-not "cvtps2pd\[^\n\r\]*(%xmm|xmm)\[0-9\]+,\[^\n\r\]*(%xmm|xmm)\[0-9\]+" } } */ |