Avoid PR72749 by not using unspecs
authorAlan Modra <amodra@gcc.gnu.org>
Sat, 14 Jan 2017 13:24:46 +0000 (23:54 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Sat, 14 Jan 2017 13:24:46 +0000 (23:54 +1030)
Rather than using unspecs in doloop insns to stop combine creating
these insns, use legitimate_combined_insn.

PR target/72749
* combine.c (recog_for_combine_1): Set INSN_CODE before calling
target legitimate_combined_insn.
* config/rs6000/rs6000.c (TARGET_LEGITIMATE_COMBINED_INSN): Define.
(rs6000_legitimate_combined_insn): New function.
* config/rs6000/rs6000.md (UNSPEC_DOLOOP): Delete, and remove
all uses.
(ctr<mode>_internal3): Rename from *ctr<mode>_internal5.
(ctr<mode>_internal4): Rename from *ctr<mode>_internal6.
(ctr<mode>_internal1, ctr<mode>_internal2): Remove '*' from name.

From-SVN: r244465

gcc/ChangeLog
gcc/combine.c
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index e0f5d7a23600ca6f48e26c42672bbad7316bf76c..910605368d34862d6b482372290e3e26d4fbe8d4 100644 (file)
@@ -1,7 +1,20 @@
+2017-01-14  Alan Modra  <amodra@gmail.com>
+
+       PR target/72749
+       * combine.c (recog_for_combine_1): Set INSN_CODE before calling
+       target legitimate_combined_insn.
+       * config/rs6000/rs6000.c (TARGET_LEGITIMATE_COMBINED_INSN): Define.
+       (rs6000_legitimate_combined_insn): New function.
+       * config/rs6000/rs6000.md (UNSPEC_DOLOOP): Delete, and remove
+       all uses.
+       (ctr<mode>_internal3): Rename from *ctr<mode>_internal5.
+       (ctr<mode>_internal4): Rename from *ctr<mode>_internal6.
+       (ctr<mode>_internal1, ctr<mode>_internal2): Remove '*' from name.
+
 2017-01-14  Gerald Pfeifer  <gerald@pfeifer.com>
 
        * doc/frontends.texi (G++ and GCC): Remove references to Java.
-       
+
 2017-01-13  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/33562
        * config.gcc (*-*-fuchsia*): Set native_system_header_dir.
        (aarch64*-*-fuchsia*, arm*-*-fuchsia*, x86_64-*-fuchsia*): Add to
        targets.
-       * config.host: (aarch64*-*-fuchsia*, arm*-*-fuchsia*): Add to hosts. 
+       * config.host: (aarch64*-*-fuchsia*, arm*-*-fuchsia*): Add to hosts.
 
 2016-01-10  Richard Biener  <rguenther@suse.de>
 
index 3598045afdbba9afc33f7c90147d9e532568b910..28133ff3ba9cbd6e9ff9ab3e543876daa25c36d5 100644 (file)
@@ -11201,6 +11201,7 @@ recog_for_combine_1 (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
       old_icode = INSN_CODE (insn);
       PATTERN (insn) = pat;
       REG_NOTES (insn) = notes;
+      INSN_CODE (insn) = insn_code_number;
 
       /* Allow targets to reject combined insn.  */
       if (!targetm.legitimate_combined_insn (insn))
index 5909e27a6e294cf0a80f12fb635b96ae8df98f23..11394b2f70095c9c6becb6d1a37be469b1b23d00 100644 (file)
@@ -1558,6 +1558,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
 #define TARGET_CONST_NOT_OK_FOR_DEBUG_P rs6000_const_not_ok_for_debug_p
 
+#undef TARGET_LEGITIMATE_COMBINED_INSN
+#define TARGET_LEGITIMATE_COMBINED_INSN rs6000_legitimate_combined_insn
+
 #undef TARGET_ASM_FUNCTION_PROLOGUE
 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
 #undef TARGET_ASM_FUNCTION_EPILOGUE
@@ -9076,6 +9079,49 @@ rs6000_const_not_ok_for_debug_p (rtx x)
   return false;
 }
 
+
+/* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook.  */
+
+static bool
+rs6000_legitimate_combined_insn (rtx_insn *insn)
+{
+  switch (INSN_CODE (insn))
+    {
+      /* Reject creating doloop insns.  Combine should not be allowed
+        to create these for a number of reasons:
+        1) In a nested loop, if combine creates one of these in an
+        outer loop and the register allocator happens to allocate ctr
+        to the outer loop insn, then the inner loop can't use ctr.
+        Inner loops ought to be more highly optimized.
+        2) Combine often wants to create one of these from what was
+        originally a three insn sequence, first combining the three
+        insns to two, then to ctrsi/ctrdi.  When ctrsi/ctrdi is not
+        allocated ctr, the splitter takes use back to the three insn
+        sequence.  It's better to stop combine at the two insn
+        sequence.
+        3) Faced with not being able to allocate ctr for ctrsi/crtdi
+        insns, the register allocator sometimes uses floating point
+        or vector registers for the pseudo.  Since ctrsi/ctrdi is a
+        jump insn and output reloads are not implemented for jumps,
+        the ctrsi/ctrdi splitters need to handle all possible cases.
+        That's a pain, and it gets to be seriously difficult when a
+        splitter that runs after reload needs memory to transfer from
+        a gpr to fpr.  See PR70098 and PR71763 which are not fixed
+        for the difficult case.  It's better to not create problems
+        in the first place.  */
+    case CODE_FOR_ctrsi_internal1:
+    case CODE_FOR_ctrdi_internal1:
+    case CODE_FOR_ctrsi_internal2:
+    case CODE_FOR_ctrdi_internal2:
+    case CODE_FOR_ctrsi_internal3:
+    case CODE_FOR_ctrdi_internal3:
+    case CODE_FOR_ctrsi_internal4:
+    case CODE_FOR_ctrdi_internal4:
+      return false;
+    }
+  return true;
+}
+
 /* Construct the SYMBOL_REF for the tls_get_addr function.  */
 
 static GTY(()) rtx rs6000_tls_symbol;
index a094b92a96e81a27ce028f347bdbd1a4c7fc3704..b3334749860d92c2f9ba3519027e2468c926214e 100644 (file)
    UNSPEC_IEEE128_MOVE
    UNSPEC_IEEE128_CONVERT
    UNSPEC_SIGNBIT
-   UNSPEC_DOLOOP
    UNSPEC_SF_FROM_SI
    UNSPEC_SI_FROM_SF
   ])
              (set (match_dup 0)
                   (plus:P (match_dup 0)
                            (const_int -1)))
-             (unspec [(const_int 0)] UNSPEC_DOLOOP)
              (clobber (match_scratch:CC 2 ""))
              (clobber (match_scratch:P 3 ""))])]
   ""
 ;; JUMP_INSNs.
 ;; For the length attribute to be calculated correctly, the
 ;; label MUST be operand 0.
-;; The UNSPEC is present to prevent combine creating this pattern.
+;; rs6000_legitimate_combined_insn prevents combine creating any of
+;; the ctr<mode> insns.
 
-(define_insn "*ctr<mode>_internal1"
+(define_insn "ctr<mode>_internal1"
   [(set (pc)
        (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
                          (const_int 1))
    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
        (plus:P (match_dup 1)
                 (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_DOLOOP)
    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
   ""
   [(set_attr "type" "branch")
    (set_attr "length" "*,16,20,20")])
 
-(define_insn "*ctr<mode>_internal2"
+(define_insn "ctr<mode>_internal2"
   [(set (pc)
        (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
                          (const_int 1))
    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
        (plus:P (match_dup 1)
                 (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_DOLOOP)
    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
   ""
 
 ;; Similar but use EQ
 
-(define_insn "*ctr<mode>_internal5"
+(define_insn "ctr<mode>_internal3"
   [(set (pc)
        (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
                          (const_int 1))
    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
        (plus:P (match_dup 1)
                 (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_DOLOOP)
    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
   ""
   [(set_attr "type" "branch")
    (set_attr "length" "*,16,20,20")])
 
-(define_insn "*ctr<mode>_internal6"
+(define_insn "ctr<mode>_internal4"
   [(set (pc)
        (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
                          (const_int 1))
    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
        (plus:P (match_dup 1)
                 (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_DOLOOP)
    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
   ""
                      (match_operand 6 "" "")))
    (set (match_operand:P 0 "int_reg_operand" "")
        (plus:P (match_dup 1) (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_DOLOOP)
    (clobber (match_scratch:CC 3 ""))
    (clobber (match_scratch:P 4 ""))]
   "reload_completed"
                      (match_operand 6 "" "")))
    (set (match_operand:P 0 "nonimmediate_operand" "")
        (plus:P (match_dup 1) (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_DOLOOP)
    (clobber (match_scratch:CC 3 ""))
    (clobber (match_scratch:P 4 ""))]
   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"