re PR target/64019 (ICE in extract_constrain_insn)
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Wed, 3 Dec 2014 18:39:22 +0000 (18:39 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 3 Dec 2014 18:39:22 +0000 (18:39 +0000)
[gcc]
2014-12-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/64019
* config/rs6000/rs6000.c (rs6000_legitimize_reload_address): Do
not create LO_SUM address for constant addresses if the type can
go in Altivec registers.

[gcc/testsuite]
2014-12-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/64019
* gcc.target/powerpc/pr64019.c: New file.

From-SVN: r218327

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr64019.c [new file with mode: 0644]

index 42a55e1..928b6b8 100644 (file)
@@ -1,3 +1,10 @@
+2014-12-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/64019
+       * config/rs6000/rs6000.c (rs6000_legitimize_reload_address): Do
+       not create LO_SUM address for constant addresses if the type can
+       go in Altivec registers.
+
 2014-12-03  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR fortran/44054
index cdb9de9..5062337 100644 (file)
@@ -7575,7 +7575,11 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
         naturally aligned.  Since we say the address is good here, we
         can't disable offsets from LO_SUMs in mem_operand_gpr.
         FIXME: Allow offset from lo_sum for other modes too, when
-        mem is sufficiently aligned.  */
+        mem is sufficiently aligned.
+
+        Also disallow this if the type can go in VMX/Altivec registers, since
+        those registers do not have d-form (reg+offset) address modes.  */
+      && !reg_addr[mode].scalar_in_vmx_p
       && mode != TFmode
       && mode != TDmode
       && (mode != TImode || !TARGET_VSX_TIMODE)
index f39ea80..8c68f51 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/64019
+       * gcc.target/powerpc/pr64019.c: New file.
+
 2014-12-03  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR fortran/44054
diff --git a/gcc/testsuite/gcc.target/powerpc/pr64019.c b/gcc/testsuite/gcc.target/powerpc/pr64019.c
new file mode 100644 (file)
index 0000000..a39b219
--- /dev/null
@@ -0,0 +1,71 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-options "-O2 -ffast-math -mcpu=power7" } */
+
+#include <math.h>
+
+typedef struct
+{
+  double x, y, z;
+  double q, a, b, mass;
+  double vx, vy, vz, vw, dx, dy, dz;
+}
+ATOM;
+int
+u_f_nonbon (lambda)
+     double lambda;
+{
+  double r, r0, xt, yt, zt;
+  double lcutoff, cutoff, get_f_variable ();
+  double rdebye;
+  int inbond, inangle, i;
+  ATOM *a1, *a2, *bonded[10], *angled[10];
+  ATOM *(*use)[];
+  int uselist (), nuse, used;
+  ATOM *cp, *bp;
+  int a_number (), inbuffer;
+  double (*buffer)[], xx, yy, zz, k;
+  int invector, atomsused, ii, jj, imax;
+  double (*vector)[];
+  ATOM *(*atms)[];
+  double dielectric;
+  rdebye = cutoff / 2.;
+  dielectric = get_f_variable ("dielec");
+  imax = a_number ();
+  for (jj = 1; jj < imax; jj++, a1 = bp)
+    {
+      if ((*use)[used] == a1)
+       {
+         used += 1;
+       }
+      while ((*use)[used] != a1)
+       {
+         for (i = 0; i < inbuffer; i++)
+           {
+           }
+         xx = a1->x + lambda * a1->dx;
+         yy = a1->y + lambda * a1->dy;
+         zz = a1->z + lambda * a1->dz;
+         for (i = 0; i < inbuffer; i++)
+           {
+             xt = xx - (*buffer)[3 * i];
+             yt = yy - (*buffer)[3 * i + 1];
+             zt = zz - (*buffer)[3 * i + 2];
+             r = xt * xt + yt * yt + zt * zt;
+             r0 = sqrt (r);
+             xt = xt / r0;
+             zt = zt / r0;
+             k =
+               -a1->q * (*atms)[i]->q * dielectric * exp (-r0 / rdebye) *
+               (1. / (rdebye * r0) + 1. / r);
+             k += a1->a * (*atms)[i]->a / r / r0 * 6;
+             k -= a1->b * (*atms)[i]->b / r / r / r0 * 12;
+             (*vector)[3 * i] = xt * k;
+             (*vector)[3 * i + 1] = yt * k;
+             (*vector)[3 * i + 2] = zt * k;
+           }
+       }
+    }
+}