This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Avoid PR72749 by not using unspecs


Rather than using unspecs in doloop insns to stop combine creating
these insns, use legitimate_combined_insn.

I'm not sure why the original patch implementing
legitimate_combined_insn did not store the result of recog to the insn
but it seems good to me, and would allow the recog call in
ix86_legitimate_combined_insn to be omitted.  (I tested that too, not
shown here.)

Bootstrapped and regression tested powerpc64le-linux, powerpc64-linux,
x86_64-linux.  OK for mainline?

	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.

diff --git a/gcc/combine.c b/gcc/combine.c
index 3043f2a..73a74ac 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -11199,6 +11199,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))
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 02b521c..76ba81b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f7c1ab2..9442b07 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -149,7 +149,6 @@ (define_c_enum "unspec"
    UNSPEC_IEEE128_MOVE
    UNSPEC_IEEE128_CONVERT
    UNSPEC_SIGNBIT
-   UNSPEC_DOLOOP
    UNSPEC_SF_FROM_SI
    UNSPEC_SI_FROM_SF
   ])
@@ -12740,7 +12739,6 @@ (define_expand "ctr<mode>"
 	      (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 ""))])]
   ""
@@ -12751,9 +12749,8 @@ (define_expand "ctr<mode>"
 ;; 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.
 
-(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))
@@ -12762,7 +12759,6 @@ (define_insn "*ctr<mode>_internal1"
    (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"))]
   ""
@@ -12778,7 +12774,7 @@ (define_insn "*ctr<mode>_internal1"
   [(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))
@@ -12787,7 +12783,6 @@ (define_insn "*ctr<mode>_internal2"
    (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"))]
   ""
@@ -12805,7 +12800,7 @@ (define_insn "*ctr<mode>_internal2"
 
 ;; 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))
@@ -12814,7 +12809,6 @@ (define_insn "*ctr<mode>_internal5"
    (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"))]
   ""
@@ -12830,7 +12824,7 @@ (define_insn "*ctr<mode>_internal5"
   [(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))
@@ -12839,7 +12833,6 @@ (define_insn "*ctr<mode>_internal6"
    (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"))]
   ""
@@ -12866,7 +12859,6 @@ (define_split
 		      (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"
@@ -12892,7 +12884,6 @@ (define_split
 		      (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)"
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr72749.c b/gcc/testsuite/gcc.c-torture/compile/pr72749.c
new file mode 100644
index 0000000..2ef4d9a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr72749.c
@@ -0,0 +1,21 @@
+/* { dg-options "-O2 -fsched2-use-superblocks" } */
+
+int as;
+
+void
+ji (int *x4)
+{
+  if (0)
+    {
+      unsigned int pv;
+
+      while (as < 0)
+        {
+          for (*x4 = 0; *x4 < 1; ++(*x4))
+yj:
+            x4 = (int *)&pv;
+          ++as;
+        }
+    }
+  goto yj;
+}

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]