From 4306fbeede0944d3b8a7a1b3d97cac8b693824ca Mon Sep 17 00:00:00 2001 From: Mary Bennett Date: Mon, 30 Oct 2023 12:28:36 +0000 Subject: [PATCH] Fix for Issue #77 Since the constraint `m` should assume non-xcvmem specific operands, we redefined TARGET_MEM_CONSTRAINT and defined 'm' to exclude XCVmem specific operands. Constraint `CVmp` defines addresses for post modify operands. Constraint `CVmr` defines addresses for reg + reg operands. Files Changed: * gcc/config/riscv/predicates.md (mem_post_inc): Prevent DI and DF mode mem. (mem_plus_reg): Likewise. * gcc/config/riscv/constraints.md: Add new constraints `m`, `CVmp` and `CVmr`. * gcc/config/riscv/riscv.md: Remove constraint `am`. * gcc/config/riscv/riscv.h: Redefine TARGET_MEM_CONSTRAINT to `w`. * gcc/testsuite/gcc.target/riscv/cv-mem-compile-1.c: New test. * gcc/testsuite/gcc.target/riscv/cv-mem-compile-2.c: Likewise. * gcc/testsuite/gcc.target/riscv/cv-mem-compile-3.c: Likewise. --- gcc/config/riscv/constraints.md | 30 ++++++++++--- gcc/config/riscv/corev.md | 44 +++++++++---------- gcc/config/riscv/predicates.md | 9 +++- gcc/config/riscv/riscv.h | 2 + gcc/config/riscv/riscv.md | 2 +- .../gcc.target/riscv/cv-mem-compile-1.c | 17 +++++++ .../gcc.target/riscv/cv-mem-compile-2.c | 18 ++++++++ .../gcc.target/riscv/cv-mem-compile-3.c | 26 +++++++++++ 8 files changed, 118 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mem-compile-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mem-compile-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mem-compile-3.c diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index c16505b79fd..8d954526738 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -35,6 +35,16 @@ ;; General constraints +(define_memory_constraint "m" + "An address that is not base reg + index reg or post modify." + (and (match_code "mem") + (and (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), + MEM_ADDR_SPACE (op))") + (not (match_test "(GET_CODE (XEXP (op, 0)) == PLUS + && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG + && GET_CODE (XEXP (XEXP (op, 0), 1)) == REG) + || GET_CODE (XEXP (op, 0)) == POST_MODIFY"))))) + (define_constraint "I" "An I-type 12-bit signed immediate." (and (match_code "const_int") @@ -128,11 +138,6 @@ (and (match_code "mem") (match_test "GET_CODE(XEXP(op,0)) == REG"))) -(define_memory_constraint "am" - "An address that is held in a general-purpose register." - (and (match_code "mem") - (match_test "!(GET_CODE(XEXP(op,0)) == PLUS && GET_CODE(XEXP(XEXP(op,0),0)) == REG && GET_CODE(XEXP(XEXP(op,0),1)) == REG)"))) - (define_constraint "S" "A constraint that matches an absolute symbolic address." (match_operand 0 "absolute_symbolic_operand")) @@ -168,6 +173,21 @@ (and (match_test "IN_RANGE (ival, 0, 1073741823)") (match_test "exact_log2 (ival + 1) != -1")))) +(define_constraint "CVmr" + "An address for reg+reg stores and loads" + (and (match_code "mem") + (match_test "GET_CODE (XEXP (op, 0)) == PLUS + && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG + && GET_CODE (XEXP (XEXP (op, 0), 1)) == REG"))) + +(define_constraint "CVmp" + "An address for post-modify or reg+reg stores and loads" + (and (match_code "mem") + (match_test "(GET_CODE (XEXP (op, 0)) == PLUS + && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG + && GET_CODE (XEXP (XEXP (op, 0), 1)) == REG) + || GET_CODE (XEXP (op, 0)) == POST_MODIFY"))) + (define_constraint "MVs10" "A 10-bit unsigned immediate for CORE-V bitmanip." (and (match_code "const_int") diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md index 39033be6924..a0f04d7cce4 100644 --- a/gcc/config/riscv/corev.md +++ b/gcc/config/riscv/corev.md @@ -2983,7 +2983,7 @@ ;; Post Increment Register-Immediate and Register-Register Load/Store (define_insn "cv_load_postinc" [(set (match_operand:ANYI 0 "register_operand" "=r") - (match_operand:ANYI 1 "mem_post_inc" "m"))] + (match_operand:ANYI 1 "mem_post_inc" "CVmp"))] "TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (mode, XEXP (operands[1], 0), (lra_in_progress || reload_completed))" "cv.\t%0,%1" [(set_attr "type" "load") @@ -2991,7 +2991,7 @@ (define_insn "cv_load__postinc" [(set (match_operand:SI 0 "register_operand" "=r") - (any_extend:SI (match_operand:SHORT 1 "mem_post_inc" "m")))] + (any_extend:SI (match_operand:SHORT 1 "mem_post_inc" "CVmp")))] "TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (mode, XEXP (operands[1], 0), (lra_in_progress || reload_completed))" "cv.\t%0,%1" [(set_attr "type" "load") @@ -2999,7 +2999,7 @@ (define_insn "cv_loadsf_postinc_hardfloat" [(set (match_operand:SF 0 "register_operand" "=r") - (match_operand:SF 1 "mem_post_inc" "m"))] + (match_operand:SF 1 "mem_post_inc" "CVmp"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], SFmode) @@ -3010,7 +3010,7 @@ (define_insn "cv_loadsf_postinc_softfloat" [(set (match_operand:SF 0 "register_operand" "=r") - (match_operand:SF 1 "mem_post_inc" "m"))] + (match_operand:SF 1 "mem_post_inc" "CVmp"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], SFmode) @@ -3021,7 +3021,7 @@ (define_insn "cv_loadhf_postinc_hardfloat" [(set (match_operand:HF 0 "register_operand" "=r") - (match_operand:HF 1 "mem_post_inc" "m"))] + (match_operand:HF 1 "mem_post_inc" "CVmp"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], HFmode) @@ -3032,7 +3032,7 @@ (define_insn "cv_loadhf_postinc_softfloat" [(set (match_operand:HF 0 "register_operand" "=r") - (match_operand:HF 1 "mem_post_inc" "m"))] + (match_operand:HF 1 "mem_post_inc" "CVmp"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], HFmode) @@ -3042,7 +3042,7 @@ (set_attr "mode" "HF")]) (define_insn "cv_store_postinc" - [(set (match_operand:ANYI 0 "mem_post_inc" "=m") + [(set (match_operand:ANYI 0 "mem_post_inc" "=CVmp") (match_operand:ANYI 1 "register_operand" "r"))] "TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (mode, XEXP (operands[0], 0), (lra_in_progress || reload_completed))" "cv.\t%1,%0" @@ -3050,7 +3050,7 @@ (set_attr "mode" "")]) (define_insn "cv_storesf_postinc_hardfloat" - [(set (match_operand:SF 0 "mem_post_inc" "=m") + [(set (match_operand:SF 0 "mem_post_inc" "=CVmp") (match_operand:SF 1 "register_operand" "r"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3061,7 +3061,7 @@ (set_attr "mode" "SF")]) (define_insn "cv_storesf_postinc_softfloat" - [(set (match_operand:SF 0 "mem_post_inc" "=m") + [(set (match_operand:SF 0 "mem_post_inc" "=CVmp") (match_operand:SF 1 "register_operand" "r"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3072,7 +3072,7 @@ (set_attr "mode" "SF")]) (define_insn "cv_storehf_postinc_hardfloat" - [(set (match_operand:HF 0 "mem_post_inc" "=m") + [(set (match_operand:HF 0 "mem_post_inc" "=CVmp") (match_operand:HF 1 "register_operand" "r"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3083,7 +3083,7 @@ (set_attr "mode" "HF")]) (define_insn "cv_storehf_postinc_softfloat" - [(set (match_operand:HF 0 "mem_post_inc" "=m") + [(set (match_operand:HF 0 "mem_post_inc" "=CVmp") (match_operand:HF 1 "register_operand" "r"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3096,7 +3096,7 @@ ;; Normal Register-Register Load/Store (define_insn "cv_load" [(set (match_operand:ANYI 0 "register_operand" "=r") - (match_operand:ANYI 1 "mem_plus_reg" "m"))] + (match_operand:ANYI 1 "mem_plus_reg" "CVmr"))] "TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (mode, XEXP (operands[1], 0), (lra_in_progress || reload_completed))" "cv.\t%0,%1" [(set_attr "type" "load") @@ -3104,7 +3104,7 @@ (define_insn "cv_load_" [(set (match_operand:SI 0 "register_operand" "=r") - (any_extend:SI (match_operand:SHORT 1 "mem_plus_reg" "m")))] + (any_extend:SI (match_operand:SHORT 1 "mem_plus_reg" "CVmr")))] "TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (mode, XEXP (operands[1], 0), (lra_in_progress || reload_completed))" "cv.\t%0,%1" [(set_attr "type" "load") @@ -3112,7 +3112,7 @@ (define_insn "cv_loadsf_hardfloat" [(set (match_operand:SF 0 "register_operand" "=r") - (match_operand:SF 1 "mem_plus_reg" "m"))] + (match_operand:SF 1 "mem_plus_reg" "CVmr"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], SFmode) @@ -3123,7 +3123,7 @@ (define_insn "cv_loadsf_softfloat" [(set (match_operand:SF 0 "register_operand" "=r") - (match_operand:SF 1 "mem_plus_reg" "m"))] + (match_operand:SF 1 "mem_plus_reg" "CVmr"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], SFmode) @@ -3134,7 +3134,7 @@ (define_insn "cv_loadhf_hardfloat" [(set (match_operand:HF 0 "register_operand" "=r") - (match_operand:HF 1 "mem_plus_reg" "m"))] + (match_operand:HF 1 "mem_plus_reg" "CVmr"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], HFmode) @@ -3145,7 +3145,7 @@ (define_insn "cv_loadhf_softfloat" [(set (match_operand:HF 0 "register_operand" "=r") - (match_operand:HF 1 "mem_plus_reg" "m"))] + (match_operand:HF 1 "mem_plus_reg" "CVmr"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[1], 0), (lra_in_progress || reload_completed)) && (register_operand (operands[0], HFmode) @@ -3155,7 +3155,7 @@ (set_attr "mode" "HF")]) (define_insn "cv_store" - [(set (match_operand:ANYI 0 "mem_plus_reg" "=m") + [(set (match_operand:ANYI 0 "mem_plus_reg" "=CVmr") (match_operand:ANYI 1 "register_operand" "r"))] "TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (mode, XEXP (operands[0], 0), (lra_in_progress || reload_completed))" "cv.\t%1,%0" @@ -3163,7 +3163,7 @@ (set_attr "mode" "")]) (define_insn "cv_storesf_hardfloat" - [(set (match_operand:SF 0 "mem_plus_reg" "=m") + [(set (match_operand:SF 0 "mem_plus_reg" "=CVmr") (match_operand:SF 1 "register_operand" " r"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3174,7 +3174,7 @@ (set_attr "mode" "SF")]) (define_insn "cv_storesf_softfloat" - [(set (match_operand:SF 0 "mem_plus_reg" "=m") + [(set (match_operand:SF 0 "mem_plus_reg" "=CVmr") (match_operand:SF 1 "register_operand" " r"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (SFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3185,7 +3185,7 @@ (set_attr "mode" "SF")]) (define_insn "cv_storehf_hardfloat" - [(set (match_operand:HF 0 "mem_plus_reg" "=m") + [(set (match_operand:HF 0 "mem_plus_reg" "=CVmr") (match_operand:HF 1 "register_operand" " r"))] "TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) @@ -3196,7 +3196,7 @@ (set_attr "mode" "HF")]) (define_insn "cv_storehf_softfloat" - [(set (match_operand:HF 0 "mem_plus_reg" "=m") + [(set (match_operand:HF 0 "mem_plus_reg" "=CVmr") (match_operand:HF 1 "register_operand" " r"))] "!TARGET_HARD_FLOAT && TARGET_XCVMEM && riscv_legitimate_xcvmem_address_p (HFmode, XEXP (operands[0], 0), (lra_in_progress || reload_completed)) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 18af5855d18..c5a225fa259 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -236,11 +236,16 @@ (define_predicate "mem_post_inc" (and (match_code "mem") - (match_test "TARGET_XCVMEM && GET_CODE (XEXP (op, 0)) == POST_MODIFY"))) + (match_test "TARGET_XCVMEM && GET_CODE (XEXP (op, 0)) == POST_MODIFY + && GET_MODE (op) != DImode + && GET_MODE (op) != DFmode + && GET_MODE (op) != TImode + && GET_MODE (op) != TFmode"))) (define_predicate "mem_plus_reg" (and (match_code "mem") - (match_test "GET_CODE (XEXP (op, 0)) == PLUS + (match_test "TARGET_XCVMEM && GET_CODE (XEXP (op, 0)) == PLUS + && GET_MODE_SIZE (GET_MODE (op)).to_constant () <= 4 && REG_P (XEXP (XEXP (op, 0), 1)) && REG_P (XEXP (XEXP (op, 0), 0))"))) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index e09a531b1bb..e2984e0df74 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -44,6 +44,8 @@ along with GCC; see the file COPYING3. If not see #define RISCV_TUNE_STRING_DEFAULT "rocket" #endif +#define TARGET_MEM_CONSTRAINT 'w' + extern const char *riscv_expand_arch (int argc, const char **argv); extern const char *riscv_expand_arch_from_cpu (int argc, const char **argv); extern const char *riscv_default_mtune (int argc, const char **argv); diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 804fcb611c6..996d7a98040 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2176,7 +2176,7 @@ (define_insn "*movsf_hardfloat" [(set (match_operand:SF 0 "nonimmediate_nonpostinc" "=f, f,f,f,m,m,*f,*r, *r,*r,*m") - (match_operand:SF 1 "move_operand" " f,zfli,G,am,f,G,*r,*f,*G*r,*m,*r"))] + (match_operand:SF 1 "move_operand" " f,zfli,G,m,f,G,*r,*f,*G*r,*m,*r"))] "TARGET_HARD_FLOAT && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" diff --git a/gcc/testsuite/gcc.target/riscv/cv-mem-compile-1.c b/gcc/testsuite/gcc.target/riscv/cv-mem-compile-1.c new file mode 100644 index 00000000000..4a9d733c5c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cv-mem-compile-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_xcvmem -mabi=ilp32 -g -O2" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +/* Test for illegal generation of pattern: `(mem:DF (plus:SI (reg reg)))`. + */ + +struct { + double a[3]; +} * b; +int c; + +int +foo (void) +{ + b[0].a[c] -= b[0].a[c]; +} diff --git a/gcc/testsuite/gcc.target/riscv/cv-mem-compile-2.c b/gcc/testsuite/gcc.target/riscv/cv-mem-compile-2.c new file mode 100644 index 00000000000..d15a2a51d67 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cv-mem-compile-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_xcvmem -mabi=ilp32 -g -O2" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +/* Test for illegal pattern: `(mem:DF (post_modify:SI (reg reg)))`. + */ + +int bar (double); + +int +foo (void) +{ + double *b; + int c = 0; + for (;; c++) + bar (b[c]); +} + diff --git a/gcc/testsuite/gcc.target/riscv/cv-mem-compile-3.c b/gcc/testsuite/gcc.target/riscv/cv-mem-compile-3.c new file mode 100644 index 00000000000..8ab1d35e1d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cv-mem-compile-3.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_xcvmem -mabi=ilp32 -g -O2 -Wno-int-conversion" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +/* Test for illegal assembly instruction `lbu reg,reg(reg)`. + */ + +int a; +int bar (char); + +int +foo (void) +{ + short *d; + char *e = (char *)foo; + for (;;) { + char c = d++; + bar (c); + short b = e[0] + b; + if (b) + a = 5; + e += 2; + } +} + +/* { dg-final { scan-assembler-not "lbu\t\[a-z\]\[0-99\],\[a-z\]\[0-99\]\\(\[a-z\]\[0-99\]\\)" } } */