Hi James,

On 22/02/19 00:09, James Greenhalgh wrote:
> On Mon, Feb 18, 2019 at 08:40:12AM -0600, Matthew Malcomson wrote:
>>
>> Additionally, this patch contains two tidy-ups (happy to remove them or put 
>> in
>> a separate patch if people want):
> 
> Generally, yes I prefer that.
> 

I've removed the tidy ups and retested -- modified patch attached.

>>
>> OK for trunk?
> 
> This patch is fine for GCC 10, so not on trunk yet please unless there is
> a corectness reason for the change.
> 

The patch is a correctness change to fix the P1 regression that occurs 
when the stack pointer was passed to the define_insn from the 
define_peephole2.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89324

Ok for trunk?

Regards,
Matthew
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index b7f6fe0f1354f7aa19076a946ed2c633b9b9b8da..b7cd9fc787b8526cc7b11b9430fbfcd73103328a 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1985,7 +1985,7 @@ (define_expand "uaddvti4"
 (define_insn "add<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
+	 (plus:GPI (match_operand:GPI 1 "register_operand" "%rk,rk,rk")
 		   (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
 	 (const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
@@ -2002,7 +2002,7 @@ (define_insn "add<mode>3_compare0"
 (define_insn "*addsi3_compare0_uxtw"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
+	 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
 		  (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
 	 (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r,r,r")
@@ -2034,7 +2034,7 @@ (define_insn "add<mode>3_compareC"
   [(set (reg:CC_C CC_REGNUM)
 	(compare:CC_C
 	  (plus:GPI
-	    (match_operand:GPI 1 "register_operand" "r,r,r")
+	    (match_operand:GPI 1 "register_operand" "rk,rk,rk")
 	    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
 	  (match_dup 1)))
    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
@@ -2081,7 +2081,7 @@ (define_insn "add<mode>3_compareV_imm"
 	(compare:CC_V
 	  (plus:<DWI>
 	    (sign_extend:<DWI>
-	      (match_operand:GPI 1 "register_operand" "r,r"))
+	      (match_operand:GPI 1 "register_operand" "rk,rk"))
 	    (match_operand:GPI 2 "aarch64_plus_immediate" "I,J"))
 	  (sign_extend:<DWI>
 	    (plus:GPI (match_dup 1) (match_dup 2)))))
@@ -2098,7 +2098,7 @@ (define_insn "add<mode>3_compareV"
   [(set (reg:CC_V CC_REGNUM)
 	(compare:CC_V
 	  (plus:<DWI>
-	    (sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
+	    (sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "rk"))
 	    (sign_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
 	  (sign_extend:<DWI> (plus:GPI (match_dup 1) (match_dup 2)))))
    (set (match_operand:GPI 0 "register_operand" "=r")
@@ -2177,7 +2177,7 @@ (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
 	(compare:CC_NZ
 	 (plus:GPI
 	  (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
-	  (match_operand:GPI 2 "register_operand" "r"))
+	  (match_operand:GPI 2 "register_operand" "rk"))
 	(const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=r")
 	(plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
@@ -2189,7 +2189,7 @@ (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
+	 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
 		    (ANY_EXTEND:GPI
 		     (match_operand:ALLX 2 "register_operand" "r")))
 	(const_int 0)))
@@ -2207,7 +2207,7 @@ (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
 		    (ANY_EXTEND:GPI 
 		     (match_operand:ALLX 1 "register_operand" "r"))
 		    (match_operand 2 "aarch64_imm3" "Ui3"))
-		   (match_operand:GPI 3 "register_operand" "r"))
+		   (match_operand:GPI 3 "register_operand" "rk"))
 	 (const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=rk")
 	(plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
@@ -2221,7 +2221,7 @@ (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
+	 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
 		    (ashift:GPI 
 		     (ANY_EXTEND:GPI
 		      (match_operand:ALLX 2 "register_operand" "r"))
@@ -2244,7 +2244,7 @@ (define_insn "*adds_<optab><mode>_multp2"
 			      (match_operand 2 "aarch64_pwr_imm3" "Up3"))
 		    (match_operand 3 "const_int_operand" "n")
 		    (const_int 0))
-		   (match_operand:GPI 4 "register_operand" "r"))
+		   (match_operand:GPI 4 "register_operand" "rk"))
 	(const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=r")
 	(plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
@@ -2259,7 +2259,7 @@ (define_insn "*adds_<optab><mode>_multp2"
 (define_insn "*subs_<optab><mode>_multp2"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
-	 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
+	 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
 		    (ANY_EXTRACT:GPI
 		     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
 			       (match_operand 2 "aarch64_pwr_imm3" "Up3"))
@@ -2923,7 +2923,7 @@ (define_insn "negvdi_carryinV"
 
 (define_insn "*sub<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
-	(compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
+	(compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
 				  (match_operand:GPI 2 "register_operand" "r"))
 		       (const_int 0)))
    (set (match_operand:GPI 0 "register_operand" "=r")
@@ -2936,7 +2936,7 @@ (define_insn "*sub<mode>3_compare0"
 ;; zero_extend version of above
 (define_insn "*subsi3_compare0_uxtw"
   [(set (reg:CC_NZ CC_REGNUM)
-	(compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
+	(compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "rk")
 				 (match_operand:SI 2 "register_operand" "r"))
 		       (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
@@ -2949,7 +2949,7 @@ (define_insn "*subsi3_compare0_uxtw"
 (define_insn "sub<mode>3_compare1_imm"
   [(set (reg:CC CC_REGNUM)
 	(compare:CC
-	  (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ,rZ")
+	  (match_operand:GPI 1 "aarch64_reg_or_zero" "rkZ,rkZ")
 	  (match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))
    (set (match_operand:GPI 0 "register_operand" "=r,r")
 	(plus:GPI
@@ -2965,7 +2965,7 @@ (define_insn "sub<mode>3_compare1_imm"
 (define_insn "sub<mode>3_compare1"
   [(set (reg:CC CC_REGNUM)
 	(compare:CC
-	  (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+	  (match_operand:GPI 1 "aarch64_reg_or_zero" "rkZ")
 	  (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))
    (set (match_operand:GPI 0 "register_operand" "=r")
 	(minus:GPI (match_dup 1) (match_dup 2)))]
@@ -2975,7 +2975,7 @@ (define_insn "sub<mode>3_compare1"
 )
 
 (define_peephole2
-  [(set (match_operand:GPI 0 "register_operand")
+  [(set (match_operand:GPI 0 "aarch64_general_reg")
 	(minus:GPI (match_operand:GPI 1 "aarch64_reg_or_zero")
 		    (match_operand:GPI 2 "aarch64_reg_or_zero")))
    (set (reg:CC CC_REGNUM)
@@ -3000,7 +3000,7 @@ (define_peephole2
 	(compare:CC
 	  (match_operand:GPI 1 "aarch64_reg_or_zero")
 	  (match_operand:GPI 2 "aarch64_reg_or_zero")))
-   (set (match_operand:GPI 0 "register_operand")
+   (set (match_operand:GPI 0 "aarch64_general_reg")
 	(minus:GPI (match_dup 1)
 		   (match_dup 2)))]
   ""
@@ -3013,7 +3013,7 @@ (define_peephole2
 )
 
 (define_peephole2
-  [(set (match_operand:GPI 0 "register_operand")
+  [(set (match_operand:GPI 0 "aarch64_general_reg")
 	(plus:GPI (match_operand:GPI 1 "register_operand")
 		  (match_operand:GPI 2 "aarch64_plus_immediate")))
    (set (reg:CC CC_REGNUM)
@@ -3038,7 +3038,7 @@ (define_peephole2
 	(compare:CC
 	  (match_operand:GPI 1 "register_operand")
 	  (match_operand:GPI 3 "const_int_operand")))
-   (set (match_operand:GPI 0 "register_operand")
+   (set (match_operand:GPI 0 "aarch64_general_reg")
 	(plus:GPI (match_dup 1)
 		  (match_operand:GPI 2 "aarch64_plus_immediate")))]
   "INTVAL (operands[3]) == -INTVAL (operands[2])"
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index b8e6d232ff6237a58addda1ec0e953a1054dc616..8e1b784217b0367dc647a87024e14e36de781008 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -30,6 +30,10 @@ (define_predicate "aarch64_call_insn_operand"
   (ior (match_code "symbol_ref")
        (match_operand 0 "register_operand")))
 
+(define_predicate "aarch64_general_reg"
+  (and (match_operand 0 "register_operand")
+       (match_test "REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS")))
+
 ;; Return true if OP a (const_int 0) operand.
 (define_predicate "const0_operand"
   (and (match_code "const_int")
diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/subs_adds_sp.c b/gcc/testsuite/gcc.dg/rtl/aarch64/subs_adds_sp.c
new file mode 100644
index 0000000000000000000000000000000000000000..f537771a271e1d33df29561a4b687d621e090bab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/aarch64/subs_adds_sp.c
@@ -0,0 +1,153 @@
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-options "-O2" } */
+/*
+   Tests are:
+      Patterns allow subs/adds with a stack pointer source.
+      define_peephole2's don't generate patterns for subs/adds with a stack
+      pointer destination.
+ */
+
+/* These functions used to ICE due to using the stack pointer as a source
+   register.  */
+
+int __RTL (startwith ("final"))
+adds ()
+{
+(function "adds"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 101 (parallel [
+	    (set (reg:CC cc)
+		(compare:CC (reg/f:DI sp)
+		    (const_int -3)))
+	    (set (reg/f:DI x19)
+		(plus:DI (reg/f:DI sp)
+		    (const_int 3)))
+	]))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 10 (use (reg/i:SI x19)))
+      (cinsn 11 (use (reg/i:SI sp)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("final"))
+subs ()
+{
+(function "subs"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 101 (parallel [
+	    (set (reg:CC cc)
+		(compare:CC (reg/f:DI sp)
+		    (const_int 3)))
+	    (set (reg/f:DI x19)
+		(plus:DI (reg/f:DI sp)
+		    (const_int -3)))
+	]))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 10 (use (reg/i:SI x19)))
+      (cinsn 11 (use (reg/i:SI sp)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+/* These functions used to trigger peepholes generating invalid SUBS patterns
+   that used the stack pointer for the destination register.  */
+
+int __RTL (startwith ("peephole2")) sub3_compare1_peephole_1 ()
+{
+(function "sub3_compare1_peephole_1"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 89 (set (reg:DI sp)
+		 (minus:DI (reg:DI x2) (reg:DI x5))))
+      (cinsn 90 (set (reg:CC cc)
+		 (compare:CC (reg:DI x2) (reg:DI x5))))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 12 (use (reg/i:DI cc)))
+      (cinsn 11 (use (reg/i:DI sp)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) sub3_compare1_peephole_2 ()
+{
+(function "sub3_compare1_peephole_2"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 90 (set (reg:CC cc)
+		 (compare:CC (reg:DI x2) (reg:DI x5))))
+      (cinsn 89 (set (reg:DI sp)
+		 (minus:DI (reg:DI x2) (reg:DI x5))))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 12 (use (reg/i:DI cc)))
+      (cinsn 11 (use (reg/i:DI sp)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) sub3_compare1_imm_peephole_1 ()
+{
+(function "sub3_compare1_imm_peephole_1"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 90 (set (reg:CC cc)
+		 (compare:CC (reg:DI x2) (reg:DI x5))))
+      (cinsn 89 (set (reg:DI sp)
+		 (minus:DI (reg:DI x2) (reg:DI x5))))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 12 (use (reg/i:DI cc)))
+      (cinsn 11 (use (reg/i:DI sp)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) sub3_compare1_imm_peephole_2 ()
+{
+(function "sub3_compare1_imm_peephole_1"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 89 (set (reg:DI sp)
+		 (minus:DI (reg:DI x2) (reg:DI x5))))
+      (cinsn 90 (set (reg:CC cc)
+		 (compare:CC (reg:DI x2) (reg:DI x5))))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 12 (use (reg/i:DI cc)))
+      (cinsn 11 (use (reg/i:DI sp)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+/* Verify that the adds and subs functions generated their respective
+   instructions, and that none of the other functions generated either since
+   they are setting the stack pointer.  */
+/* { dg-final { scan-assembler-times {adds\tx[0-9]+, sp} 1 } }  */
+/* { dg-final { scan-assembler-not {adds\tsp} } }  */
+/* { dg-final { scan-assembler-times {subs\tx[0-9]+, sp} 1 } }  */
+/* { dg-final { scan-assembler-not {subs\tsp} } }  */
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr89324.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/pr89324.f90
new file mode 100644
index 0000000000000000000000000000000000000000..014b655d5edae26689ff57eda808e2a0f6146d5b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/pr89324.f90
@@ -0,0 +1,15 @@
+module a
+contains
+  pure function myotherlen()
+    myotherlen = 99
+  end  
+  subroutine b
+    characterx
+    block
+       character(myotherlen()) c
+       c = "abc"
+       x = c
+    end block
+  
+    end  
+end

Reply via email to