diff options
author | Philipp Tomsich <philipp.tomsich@vrull.eu> | 2022-11-21 12:44:23 +0100 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@vrull.eu> | 2022-11-21 12:53:45 +0100 |
commit | 4c7d336b673df2f3bf23bc5e7a69c445a2320c04 (patch) | |
tree | 1d87c2de420d758d05e8195ad5a0825c0749a69a | |
parent | 2473f28d79c480192aba783a08de8b0285c08213 (diff) | |
download | gcc-4c7d336b673df2f3bf23bc5e7a69c445a2320c04.zip gcc-4c7d336b673df2f3bf23bc5e7a69c445a2320c04.tar.gz gcc-4c7d336b673df2f3bf23bc5e7a69c445a2320c04.tar.bz2 |
RISC-V: Fix ICE in branch<ANYI:mode>_shiftedarith_equals_zero
With the recent improvements to the splitting of special cases of
branch patterns on RISC-V, a dependency on an unmerged/in-discussion
change for branch-equals-zero slipped in: this allowed a non-X mode to
be presented to branch-equals-zero (where only X mode is permissible).
This addresses the issue by wrapping the ANYI operand in a paradoxical
SUBREG:X (the high bits can be safely ignored, as we we perform an
and-immediate before the branch in the pattern).
Tested against the GCC testsuite and committed as obvious.
gcc/ChangeLog:
PR target/107786
* config/riscv/riscv.md
(*branch<ANYI:mode>_shiftedarith_equals_zero): Wrap ANYI
in a subreg, as our branch instructions only supports X.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/pr107786-2.c: New test.
* gcc.target/riscv/pr107786.c: New test.
-rw-r--r-- | gcc/config/riscv/riscv.md | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr107786-2.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr107786.c | 17 |
3 files changed, 38 insertions, 4 deletions
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index b7bb338..df57e2b 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2224,12 +2224,12 @@ (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc))) - (clobber (match_scratch:ANYI 4 "=&r"))] - "INTVAL (operands[3]) >= 0 || !partial_subreg_p (operands[2])" + (clobber (match_scratch:X 4 "=&r"))] + "!SMALL_OPERAND (INTVAL (operands[3]))" "#" "&& reload_completed" - [(set (match_dup 4) (lshiftrt:ANYI (match_dup 2) (match_dup 6))) - (set (match_dup 4) (and:ANYI (match_dup 4) (match_dup 7))) + [(set (match_dup 4) (lshiftrt:X (subreg:X (match_dup 2) 0) (match_dup 6))) + (set (match_dup 4) (and:X (match_dup 4) (match_dup 7))) (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)]) (label_ref (match_dup 0)) (pc)))] { diff --git a/gcc/testsuite/gcc.target/riscv/pr107786-2.c b/gcc/testsuite/gcc.target/riscv/pr107786-2.c new file mode 100644 index 0000000..ee316a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr107786-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */ + +int c; + +int main() { + for (;;) { + short h = c * 100; + if (h & 0x7ff0) + break; + } +} + +/* { dg-final { scan-assembler-times "andi\t" 1 } } */ +/* { dg-final { scan-assembler-times "srli\t" 1 } } */ + diff --git a/gcc/testsuite/gcc.target/riscv/pr107786.c b/gcc/testsuite/gcc.target/riscv/pr107786.c new file mode 100644 index 0000000..5246ec7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr107786.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */ + +int c; + +int main() { + for (;;) { + char h = c * 100; + if (h) + break; + } +} + +/* { dg-final { scan-assembler-times "andi\t" 1 } } */ +/* { dg-final { scan-assembler-not "srli\t" } } */ + |