]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport: [Patch AArch64] Reinstate CANNOT_CHANGE_MODE_CLASS to fix pr67609
authorJames Greenhalgh <james.greenhalgh@arm.com>
Tue, 12 Jan 2016 14:04:26 +0000 (14:04 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Tue, 12 Jan 2016 14:04:26 +0000 (14:04 +0000)
gcc/

Backport from mainline.
2015-12-09  James Greenhalgh  <james.greenhalgh@arm.com>

PR rtl-optimization/67609
* config/aarch64/aarch64.c
(aarch64_cannot_change_mode_class): Don't permit word_mode
subregs of full vector modes.
* config/aarch64/aarch64.md (aarch64_movdi_<mode>low): Use
zero_extract rather than truncate.
(aarch64_movdi_<mode>high): Likewise.

gcc/testsuite/

Backport from mainline.
2015-12-09  James Greenhalgh  <james.greenhalgh@arm.com>

PR rtl-optimization/67609
* gcc.dg/torture/pr67609.c: New.

From-SVN: r232270

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr67609.c [new file with mode: 0644]

index 9d1a4418122022c9f8693638962c609f30429738..ddecc22573819546c22e4ff6dd8f2f4d3971dd19 100644 (file)
@@ -1,3 +1,16 @@
+2016-01-12  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       Backport from mainline.
+       2015-12-09  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       PR rtl-optimization/67609
+       * config/aarch64/aarch64.c
+       (aarch64_cannot_change_mode_class): Don't permit word_mode
+       subregs of full vector modes.
+       * config/aarch64/aarch64.md (aarch64_movdi_<mode>low): Use
+       zero_extract rather than truncate.
+       (aarch64_movdi_<mode>high): Likewise.
+
 2016-01-11  John David Anglin  <danglin@gcc.gnu.org>
 
        * config/pa/pa.c (pa_emit_move_sequence): Handle floating point
index 81539975e3c8f26db30a9e0438233d4f9c0c33ac..5ca38b6f79720ccb3b890c70f48b3535772c4db1 100644 (file)
@@ -8405,6 +8405,18 @@ aarch64_cannot_change_mode_class (enum machine_mode from,
                                  enum machine_mode to,
                                  enum reg_class rclass)
 {
+  /* We cannot allow word_mode subregs of full vector modes.
+     Otherwise the middle-end will assume it's ok to store to
+     (subreg:DI (reg:TI 100) 0) in order to modify only the low 64 bits
+     of the 128-bit register.  However, after reload the subreg will
+     be dropped leaving a plain DImode store.  See PR67609 for a more
+     detailed dicussion.  In some other cases we can be permissive and
+     return false.  */
+  if (reg_classes_intersect_p (FP_REGS, rclass)
+      && GET_MODE_SIZE (to) == UNITS_PER_WORD
+      && GET_MODE_SIZE (from) > UNITS_PER_WORD)
+    return true;
+
   /* Full-reg subregs are allowed on general regs or any class if they are
      the same size.  */
   if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
index 24bb029bd70b0719f64b60bf2a1112251e84957f..d6c6b1e38dc350206a5bf789bfbea0b39089c9a9 100644 (file)
 
 (define_insn "aarch64_movdi_<mode>low"
   [(set (match_operand:DI 0 "register_operand" "=r")
-        (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
+       (zero_extract:DI (match_operand:TX 1 "register_operand" "w")
+                        (const_int 64) (const_int 0)))]
   "reload_completed || reload_in_progress"
   "fmov\\t%x0, %d1"
   [(set_attr "type" "f_mrc")
 
 (define_insn "aarch64_movdi_<mode>high"
   [(set (match_operand:DI 0 "register_operand" "=r")
-        (truncate:DI
-         (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
-                      (const_int 64))))]
+       (zero_extract:DI (match_operand:TX 1 "register_operand" "w")
+                        (const_int 64) (const_int 64)))]
   "reload_completed || reload_in_progress"
   "fmov\\t%x0, %1.d[1]"
   [(set_attr "type" "f_mrc")
index cce93ed356c8b542d0320dbdb3733540b67733e6..fd5de3e05f7dad89210bad109e5b3650eaa2ecf9 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-12  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       Backport from mainline.
+       2015-12-09  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       PR rtl-optimization/67609
+       * gcc.dg/torture/pr67609.c: New.
+
 2016-01-11  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/66616
diff --git a/gcc/testsuite/gcc.dg/torture/pr67609.c b/gcc/testsuite/gcc.dg/torture/pr67609.c
new file mode 100644 (file)
index 0000000..817857d
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+typedef union
+{
+  double v[2];
+  double s __attribute__ ((vector_size (16)));
+} data;
+
+data reg;
+
+void __attribute__ ((noinline))
+set_lower (double b)
+{
+  data stack_var;
+  double __attribute__ ((vector_size (16))) one = { 1.0, 1.0 };
+  stack_var.s = reg.s;
+  stack_var.s += one;
+  stack_var.v[0] += b;
+  reg.s = stack_var.s;
+}
+
+int
+main (int argc, char ** argv)
+{
+  reg.v[0] = 1.0;
+  reg.v[1] = 1.0;
+  /* reg should contain { 1.0, 1.0 }.  */
+  set_lower (2.0);
+  /* reg should contain { 4.0, 2.0 }.  */
+  if ((int) reg.v[0] != 4 || (int) reg.v[1] != 2)
+    __builtin_abort ();
+  return 0;
+}