[GCC] PR target/86487: fix the way 'uses_hard_regs_p' handles paradoxical
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Wed, 20 Feb 2019 14:11:43 +0000 (14:11 +0000)
committerAndre Vieira <avieira@gcc.gnu.org>
Wed, 20 Feb 2019 14:11:43 +0000 (14:11 +0000)
subregs

gcc/ChangeLog:
2019-02-20 Andre Vieira  <andre.simoesdiasvieira@arm.com>

PR target/86487
* lra-constraints.c(uses_hard_regs_p): Fix handling of
paradoxical SUBREGS.

gcc/testsuite/ChangeLog:
2019-02-20 Andre Vieira  <andre.simoesdiasvieira@arm.com>

PR target/86487
* gcc.target/arm/pr86487.c: New.

From-SVN: r269039

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr86487.c [new file with mode: 0644]

index b18b23cef5effddc82e0660d16cc51a86918eff3..b544e089e57475f12ee63af4075b50a0f534b0c3 100644 (file)
@@ -1,3 +1,9 @@
+2019-02-20 Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+       PR target/86487
+       * lra-constraints.c(uses_hard_regs_p): Fix handling of
+       paradoxical SUBREGS.
+
 2019-02-20  Li Jia He  <helijia@linux.ibm.com>
 
        PR target/88100
index 17ea2c53bbc487ac9868c85b65814827afd1bcaf..629dc5dae1f7515d0073103e128b14954a8fb472 100644 (file)
@@ -1770,14 +1770,24 @@ uses_hard_regs_p (rtx x, HARD_REG_SET set)
     return false;
   code = GET_CODE (x);
   mode = GET_MODE (x);
+
   if (code == SUBREG)
     {
+      /* For all SUBREGs we want to check whether the full multi-register
+        overlaps the set.  For normal SUBREGs this means 'get_hard_regno' of
+        the inner register, for paradoxical SUBREGs this means the
+        'get_hard_regno' of the full SUBREG and for complete SUBREGs either is
+        fine.  Use the wider mode for all cases.  */
+      rtx subreg = SUBREG_REG (x);
       mode = wider_subreg_mode (x);
-      x = SUBREG_REG (x);
-      code = GET_CODE (x);
+      if (mode == GET_MODE (subreg))
+       {
+         x = subreg;
+         code = GET_CODE (x);
+       }
     }
 
-  if (REG_P (x))
+  if (REG_P (x) || SUBREG_P (x))
     {
       x_hard_regno = get_hard_regno (x, true);
       return (x_hard_regno >= 0
index cd45bc56c7fd20c3f2ad7da8e7eb401eb1ecb239..3b415cd2564a8e691884b8e2a22553412b106689 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-20 Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+       PR target/86487
+       * gcc.target/arm/pr86487.c: New.
+
 2019-02-20  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/84536
diff --git a/gcc/testsuite/gcc.target/arm/pr86487.c b/gcc/testsuite/gcc.target/arm/pr86487.c
new file mode 100644 (file)
index 0000000..1c1db78
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-skip-if "" { *-*-* } { "-march=armv[0-6]*" "-mthumb" } { "" } } */
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-O1 -mbig-endian" } */
+/* { dg-add-options arm_neon } */
+int a, b, c, d;
+long long fn1(long long p2) { return p2 == 0 ? -1 : -1 % p2; }
+void fn2(long long p1, short p2, long p3) {
+  b = fn1((d || 6) & a);
+  c = b | p3;
+}