diff options
author | Jeff Law <jlaw@ventanamicro.com> | 2024-11-19 19:24:41 -0700 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2024-11-19 19:26:08 -0700 |
commit | 065433b4ce8d9676ba3be4871c520b8257f21c14 (patch) | |
tree | e3fc4a6f0bad2b1ad4fea0257bfd351959e0043c /gcc | |
parent | 5afc98fec97d84baa0c580809fb3e220444fa20d (diff) | |
download | gcc-065433b4ce8d9676ba3be4871c520b8257f21c14.zip gcc-065433b4ce8d9676ba3be4871c520b8257f21c14.tar.gz gcc-065433b4ce8d9676ba3be4871c520b8257f21c14.tar.bz2 |
[RISC-V][PR target/117649] Fix branch on masked values splitter
Andreas reported GCC mis-compiled GAS for risc-v Thankfully he also reduced it
to a nice little testcase.
So the whole point of the pattern in question is to "reduce" the constants by
right shifting away common unnecessary bits in RTL expressions like this:
> [(set (pc)
> (if_then_else (any_eq
> (and:ANYI (match_operand:ANYI 1 "register_operand" "r")
> (match_operand 2 "shifted_const_arith_operand" "i"))
> (match_operand 3 "shifted_const_arith_operand" "i"))
> (label_ref (match_operand 0 "" ""))
> (pc)))
When applicable, the reduced constants in operands 2/3 fit into a simm12 and
thus do not need multi-instruction synthesis. Note that we have to also shift
operand 1.
That shift should have been an arithmetic shift, but was incorrectly coded as a
logical shift.
Fixed with the obvious change on the right shift opcode.
Expecting to push to the trunk once the pre-commit tester renders its verdict.
I've already tested in this my tester for rv32 and rv64.
PR target/117649
gcc/
* config/riscv/riscv.md (branch on masked/shifted operands): Use
arithmetic rather than logical shift for operand 1.
gcc/testsuite
* gcc.target/riscv/branch-1.c: Update expected output.
* gcc.target/riscv/pr117649.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/riscv/riscv.md | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/branch-1.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr117649.c | 16 |
3 files changed, 19 insertions, 2 deletions
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 5b7b735..eb5cd6f 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3153,7 +3153,7 @@ INTVAL (operands[3]))" "#" "&& reload_completed" - [(set (match_dup 4) (lshiftrt:X (match_dup 1) (match_dup 7))) + [(set (match_dup 4) (ashiftrt:X (match_dup 1) (match_dup 7))) (set (match_dup 4) (and:X (match_dup 4) (match_dup 8))) (set (match_dup 5) (match_dup 9)) (set (pc) (if_then_else (any_eq (match_dup 4) (match_dup 5)) diff --git a/gcc/testsuite/gcc.target/riscv/branch-1.c b/gcc/testsuite/gcc.target/riscv/branch-1.c index 7fa8783..52fc127 100644 --- a/gcc/testsuite/gcc.target/riscv/branch-1.c +++ b/gcc/testsuite/gcc.target/riscv/branch-1.c @@ -41,7 +41,8 @@ void f6(long long a) } /* { dg-final { scan-assembler-times "slli\t" 2 } } */ -/* { dg-final { scan-assembler-times "srli\t" 5 } } */ +/* { dg-final { scan-assembler-times "srai\t" 2 } } */ +/* { dg-final { scan-assembler-times "srli\t" 3 } } */ /* { dg-final { scan-assembler-times "andi\t" 3 } } */ /* { dg-final { scan-assembler-times "\tli\t" 3 } } */ /* { dg-final { scan-assembler-not "addi\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr117649.c b/gcc/testsuite/gcc.target/riscv/pr117649.c new file mode 100644 index 0000000..d0e7414 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr117649.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ + +void exit (int); + +void __attribute__ ((noinline)) +f (unsigned int i) +{ + if ((i & 0xf0000000) != 0xc0000000) __builtin_abort (); +} + +int +main () +{ + f (0xc0000022); + exit (0); +} |