summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-01-15 15:42:40 -0800
committerH.J. Lu <hjl.tools@gmail.com>2016-01-29 07:57:56 -0800
commit32da7a3306d31568f6e12aa95f36279e122454ec (patch)
tree2eb7bb6a4200b503171a9ea7fab7af6109f24dde
parent4758dc397a505efc8cd7df72dd1547376400cdc9 (diff)
downloadgcc-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.md2
-rw-r--r--gcc/lra-constraints.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr69299.c16
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\]+" } } */