re PR middle-end/85196 (ICE in extract_insn, at recog.c:2311: unrecognizable insn)
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 6 Apr 2018 22:30:05 +0000 (22:30 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 6 Apr 2018 22:30:05 +0000 (22:30 +0000)
PR target/85196
* config/sparc/sparc.c (sparc_expand_move): Deal with symbolic operands
based on LABEL_REF.  Remove useless assertion.
(pic_address_needs_scratch): Fix formatting.
(sparc_legitimize_pic_address): Minor tweaks.
(sparc_delegitimize_address): Adjust assertion accordingly.
* config/sparc/sparc.md (movsi_pic_label_ref): Change label_ref_operand
into symbolic_operand.
(movsi_high_pic_label_ref): Likewise.
(movsi_lo_sum_pic_label_ref): Likewise.
(movdi_pic_label_ref): Likewise.
(movdi_high_pic_label_ref): Likewise.
(movdi_lo_sum_pic_label_ref): Likewise.

From-SVN: r259194

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr85196.C [new file with mode: 0644]

index 08f7d51df502c2c30460085e1210f2a4777176af..f5273744037695d0097183e2258a42cd0979b1e4 100644 (file)
@@ -1,3 +1,19 @@
+2018-04-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/85196
+       * config/sparc/sparc.c (sparc_expand_move): Deal with symbolic operands
+       based on LABEL_REF.  Remove useless assertion.
+       (pic_address_needs_scratch): Fix formatting.
+       (sparc_legitimize_pic_address): Minor tweaks.
+       (sparc_delegitimize_address): Adjust assertion accordingly.
+       * config/sparc/sparc.md (movsi_pic_label_ref): Change label_ref_operand
+       into symbolic_operand.
+       (movsi_high_pic_label_ref): Likewise.
+       (movsi_lo_sum_pic_label_ref): Likewise.
+       (movdi_pic_label_ref): Likewise.
+       (movdi_high_pic_label_ref): Likewise.
+       (movdi_lo_sum_pic_label_ref): Likewise.
+
 2018-04-06  Amaan Cheval  <amaan.cheval@gmail.com>
 
        * config.gcc (x86_64-*-rtems*): Add rtems.h to tm_file for
index 7126b57ba0110559e0b7e01fd0d8def4f2b36fa9..4026d4933d8df3c40c001ff0c39e700ab03dd7a2 100644 (file)
@@ -2236,7 +2236,7 @@ sparc_expand_move (machine_mode mode, rtx *operands)
        }
     }
 
-  /* Fixup TLS cases.  */
+  /* Fix up TLS cases.  */
   if (TARGET_HAVE_TLS
       && CONSTANT_P (operands[1])
       && sparc_tls_referenced_p (operands [1]))
@@ -2245,15 +2245,20 @@ sparc_expand_move (machine_mode mode, rtx *operands)
       return false;
     }
 
-  /* Fixup PIC cases.  */
+  /* Fix up PIC cases.  */
   if (flag_pic && CONSTANT_P (operands[1]))
     {
       if (pic_address_needs_scratch (operands[1]))
        operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX);
 
       /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases.  */
-      if (GET_CODE (operands[1]) == LABEL_REF
-         && can_use_mov_pic_label_ref (operands[1]))
+      if ((GET_CODE (operands[1]) == LABEL_REF
+          && can_use_mov_pic_label_ref (operands[1]))
+         || (GET_CODE (operands[1]) == CONST
+             && GET_CODE (XEXP (operands[1], 0)) == PLUS
+             && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
+             && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
+             && can_use_mov_pic_label_ref (XEXP (XEXP (operands[1], 0), 0))))
        {
          if (mode == SImode)
            {
@@ -2263,7 +2268,6 @@ sparc_expand_move (machine_mode mode, rtx *operands)
 
          if (mode == DImode)
            {
-             gcc_assert (TARGET_ARCH64);
              emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
              return true;
            }
@@ -4280,10 +4284,11 @@ int
 pic_address_needs_scratch (rtx x)
 {
   /* An address which is a symbolic plus a non SMALL_INT needs a temp reg.  */
-  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
       && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-      && ! SMALL_INT (XEXP (XEXP (x, 0), 1)))
+      && !SMALL_INT (XEXP (XEXP (x, 0), 1)))
     return 1;
 
   return 0;
@@ -4750,16 +4755,15 @@ sparc_legitimize_tls_address (rtx addr)
 static rtx
 sparc_legitimize_pic_address (rtx orig, rtx reg)
 {
-  bool gotdata_op = false;
-
   if (GET_CODE (orig) == SYMBOL_REF
       /* See the comment in sparc_expand_move.  */
       || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig)))
     {
+      bool gotdata_op = false;
       rtx pic_ref, address;
       rtx_insn *insn;
 
-      if (reg == 0)
+      if (!reg)
        {
          gcc_assert (can_create_pseudo_p ());
          reg = gen_reg_rtx (Pmode);
@@ -4770,8 +4774,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
          /* If not during reload, allocate another temp reg here for loading
             in the address, so that these instructions can be optimized
             properly.  */
-         rtx temp_reg = (! can_create_pseudo_p ()
-                         ? reg : gen_reg_rtx (Pmode));
+         rtx temp_reg = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : reg;
 
          /* Must put the SYMBOL_REF inside an UNSPEC here so that cse
             won't get confused into thinking that these two instructions
@@ -4787,6 +4790,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
              emit_insn (gen_movsi_high_pic (temp_reg, orig));
              emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
            }
+
          address = temp_reg;
          gotdata_op = true;
        }
@@ -4827,7 +4831,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
          && sparc_pic_register_p (XEXP (XEXP (orig, 0), 0)))
        return orig;
 
-      if (reg == 0)
+      if (!reg)
        {
          gcc_assert (can_create_pseudo_p ());
          reg = gen_reg_rtx (Pmode);
@@ -4935,7 +4939,11 @@ sparc_delegitimize_address (rtx x)
       && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL)
     {
       x = XVECEXP (XEXP (XEXP (x, 1), 1), 0, 0);
-      gcc_assert (GET_CODE (x) == LABEL_REF);
+      gcc_assert (GET_CODE (x) == LABEL_REF
+                 || (GET_CODE (x) == CONST
+                     && GET_CODE (XEXP (x, 0)) == PLUS
+                     && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
+                     && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT));
     }
 
   return x;
index 7988dece99d2079c25e44e34c83f73141c30b849..df769405190388ca4e684fff9e2dc5a3bee653e5 100644 (file)
 
 (define_expand "movsi_pic_label_ref"
   [(set (match_dup 3) (high:SI
-     (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
+     (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")
                 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
    (set (match_dup 4) (lo_sum:SI (match_dup 3)
      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
 (define_insn "*movsi_high_pic_label_ref"
   [(set (match_operand:SI 0 "register_operand" "=r")
       (high:SI
-        (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
+        (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")
                    (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "flag_pic"
   "sethi\t%%hi(%a2-(%a1-.)), %0")
 (define_insn "*movsi_lo_sum_pic_label_ref"
   [(set (match_operand:SI 0 "register_operand" "=r")
       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
-        (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
+        (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
                    (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "flag_pic"
   "or\t%1, %%lo(%a3-(%a2-.)), %0")
@@ -1896,7 +1896,7 @@ visl")
 
 (define_expand "movdi_pic_label_ref"
   [(set (match_dup 3) (high:DI
-     (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
+     (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")
                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
    (set (match_dup 4) (lo_sum:DI (match_dup 3)
      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
@@ -1922,7 +1922,7 @@ visl")
 (define_insn "*movdi_high_pic_label_ref"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI
-          (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
+          (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")
                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "TARGET_ARCH64 && flag_pic"
   "sethi\t%%hi(%a2-(%a1-.)), %0")
@@ -1930,7 +1930,7 @@ visl")
 (define_insn "*movdi_lo_sum_pic_label_ref"
   [(set (match_operand:DI 0 "register_operand" "=r")
       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
-        (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
+        (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "TARGET_ARCH64 && flag_pic"
   "or\t%1, %%lo(%a3-(%a2-.)), %0")
index e92ad3c241a679478c80a5eb6ba70b4427dfe817..dad3874ff95fb3bfbf80f8329705c85cd7cbfd74 100644 (file)
@@ -1,3 +1,7 @@
+2018-04-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * g++.dg/opt/pr85196.C: New test.
+
 2018-04-06  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/84269
diff --git a/gcc/testsuite/g++.dg/opt/pr85196.C b/gcc/testsuite/g++.dg/opt/pr85196.C
new file mode 100644 (file)
index 0000000..04d7abd
--- /dev/null
@@ -0,0 +1,89 @@
+// PR target/85196
+// Testcase by Rainer Orth <ro@gcc.gnu.org>
+
+// { dg-do compile }
+// { dg-options "-O -fpermissive -w" }
+// { dg-additional-options "-fPIC" { target fpic } }
+
+class a;
+template <typename> class b;
+template <typename k> class d : public b<k> {};
+class e {};
+void f(int);
+template <class> class g {
+public:
+  h();
+  a i();
+};
+template <> class b<e> : public g<e> {};
+typedef (*j)(d<e>);
+template <class k> class l {
+public:
+  k operator->() { return 0; }
+};
+enum m { n, aa, o, ab, q, p };
+inline s(m ac) {
+  switch (ac) {
+  case n:
+  case aa:
+  case p:
+    return 1;
+  case o:
+  case ab:
+    return 2;
+  }
+}
+class D {
+  int ad;
+
+public:
+  *ae() { return &ad; }
+};
+class a {
+  l<D *> af;
+
+public:
+  *r() { return af->ae(); }
+  t(int *c) {
+    int *w = af->ae();
+    return w == c;
+  }
+};
+class F : a {
+public:
+  static int ah[];
+  static e v(F *);
+  unsigned long ai() const;
+};
+inline unsigned long F::ai() const {
+  m aj = r() - &ah[0];
+  return s(aj);
+}
+inline e F::v(F *ak) {
+  long al = ak->ai();
+  f(al);
+}
+template <typename> am() { return q; }
+class an : F {
+public:
+  static ao(d<e> u) {
+    int *ap;
+    m aq = am<unsigned>();
+    ap = &ah[aq];
+    return u.h() && u.i().t(ap);
+  }
+  template <e ar(F *)> static as() {
+    F at;
+    ar(&at);
+  }
+  template <e ar(F *)> static au(int *, unsigned, e *) {
+    j av = ao;
+    d<e> aw;
+    if (av(aw))
+      as<ar>();
+  }
+};
+int *ax;
+int ay;
+e az;
+ba() { an::au<an::v>(ax, ay, &az); }