[PATCH v3] RISC-V: Add split pattern to generate SFB instructions. [PR113095]
Since the match.pd transforms (zero_one == 0) ? y : z <op> y, into ((typeof(y))zero_one * z) <op> y. Add splitters to recongize this expression to generate SFB instructions. gcc/ChangeLog: PR target/113095 * config/riscv/sfb.md: New splitters to rewrite single bit sign extension as the condition to SFB instructions. gcc/testsuite/ChangeLog: * gcc.target/riscv/sfb.c: New test. * gcc.target/riscv/pr113095.c: New test.
This commit is contained in:
parent
0f5a9a00e3
commit
fb54b97728
3 changed files with 77 additions and 0 deletions
|
@ -35,3 +35,35 @@
|
|||
[(set_attr "length" "8")
|
||||
(set_attr "type" "sfb_alu")
|
||||
(set_attr "mode" "<GPR:MODE>")])
|
||||
|
||||
;; Combine creates this form ((typeof(y))zero_one * z) <op> y
|
||||
;; for SiFive short forward branches.
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:X 0 "register_operand")
|
||||
(and:X (sign_extract:X (match_operand:X 1 "register_operand")
|
||||
(const_int 1)
|
||||
(match_operand 2 "immediate_operand"))
|
||||
(match_operand:X 3 "register_operand")))
|
||||
(clobber (match_operand:X 4 "register_operand"))]
|
||||
"TARGET_SFB_ALU"
|
||||
[(set (match_dup 4) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 2)))
|
||||
(set (match_dup 0) (if_then_else:X (ne (match_dup 4) (const_int 0))
|
||||
(match_dup 3)
|
||||
(const_int 0)))])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:X 0 "register_operand")
|
||||
(and:X (sign_extract:X (match_operand:X 1 "register_operand")
|
||||
(const_int 1)
|
||||
(match_operand 2 "immediate_operand"))
|
||||
(match_operand:X 3 "register_operand")))
|
||||
(clobber (match_operand:X 4 "register_operand"))]
|
||||
"TARGET_SFB_ALU && (UINTVAL (operands[2]) < 11)"
|
||||
[(set (match_dup 4) (and:X (match_dup 1) (match_dup 2)))
|
||||
(set (match_dup 0) (if_then_else:X (ne (match_dup 4) (const_int 0))
|
||||
(match_dup 3)
|
||||
(const_int 0)))]
|
||||
{
|
||||
operands[2] = GEN_INT (1 << UINTVAL(operands[2]));
|
||||
})
|
||||
|
|
21
gcc/testsuite/gcc.target/riscv/pr113095.c
Normal file
21
gcc/testsuite/gcc.target/riscv/pr113095.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O2 -march=rv32gc -mabi=ilp32d -mtune=sifive-7-series" { target { rv32 } } } */
|
||||
/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -mtune=sifive-7-series" {target { rv64 } } } */
|
||||
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
unsigned short __attribute__ ((noinline, noclone))
|
||||
foo (unsigned short x) {
|
||||
if (x == 1)
|
||||
x ^= 0x4002;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int main () {
|
||||
if (foo(1) != 0x4003)
|
||||
abort ();
|
||||
|
||||
exit(0);
|
||||
}
|
24
gcc/testsuite/gcc.target/riscv/sfb.c
Normal file
24
gcc/testsuite/gcc.target/riscv/sfb.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
//* { dg-do compile } */
|
||||
/* { dg-options "-O2 -march=rv32gc -mabi=ilp32d -mtune=sifive-7-series" } */
|
||||
|
||||
int f1(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return ((x & 1) == 0) ? y : z ^ y;
|
||||
}
|
||||
|
||||
int f2(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return ((x & 1) != 0) ? z ^ y : y;
|
||||
}
|
||||
|
||||
int f3(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return ((x & 1) == 0) ? y : z | y;
|
||||
}
|
||||
|
||||
int f4(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return ((x & 1) != 0) ? z | y : y;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "bne" 4 } } */
|
||||
/* { dg-final { scan-assembler-times "movcc" 4 } } */
|
Loading…
Add table
Reference in a new issue