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