diff options
author | Jim Wilson <jimw@sifive.com> | 2018-06-30 21:52:01 +0000 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 2018-06-30 14:52:01 -0700 |
commit | 666fdc46bc848984ee7d2906f2dfe10e1ee5d535 (patch) | |
tree | dfcba939f1bcd8dc96d335edf960ac2bf2c767a9 /gcc | |
parent | 3330053ecaafe8bca82cc3845be9b2d01a614eb1 (diff) | |
download | gcc-666fdc46bc848984ee7d2906f2dfe10e1ee5d535.zip gcc-666fdc46bc848984ee7d2906f2dfe10e1ee5d535.tar.gz gcc-666fdc46bc848984ee7d2906f2dfe10e1ee5d535.tar.bz2 |
RISC-V: Add patterns to convert AND mask to two shifts.
gcc/
* config/riscv/predicates.md (p2m1_shift_operand): New.
(high_mask_shift_operand): New.
* config/riscv/riscv.md (lshrsi3_zero_extend_3+1): New combiner
pattern using p2m1_shift_operand.
(lshsi3_zero_extend_3+2): New combiner pattern using
high_mask_shift_operand.
gcc/testsuite/
* gcc.target/riscv/shift-shift-1.c: New.
* gcc.target/riscv/shift-shift-2.c: New.
* gcc.target/riscv/shift-shift-3.c: New.
From-SVN: r262278
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/riscv/predicates.md | 20 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.md | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/shift-shift-1.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/shift-shift-2.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/shift-shift-3.c | 18 |
7 files changed, 131 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d63e3ba..509af92 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-06-30 Jim Wilson <jimw@sifive.com> + + * config/riscv/predicates.md (p2m1_shift_operand): New. + (high_mask_shift_operand): New. + * config/riscv/riscv.md (lshrsi3_zero_extend_3+1): New combiner + pattern using p2m1_shift_operand. + (lshsi3_zero_extend_3+2): New combiner pattern using + high_mask_shift_operand. + 2018-06-30 Richard Sandiford <richard.sandiford@arm.com> * tree-vect-patterns.c (vect_get_external_def_edge): New function, diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index a2799d4..cffc831 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -71,6 +71,26 @@ return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); }) +(define_predicate "p2m1_shift_operand" + (match_code "const_int") +{ + int val = exact_log2 (INTVAL (op) + 1); + if (val < 12) + return false; + return true; + }) + +(define_predicate "high_mask_shift_operand" + (match_code "const_int") +{ + int val1 = clz_hwi (~ INTVAL (op)); + int val0 = ctz_hwi (INTVAL (op)); + if ((val0 + val1 == BITS_PER_WORD) + && val0 > 31 && val0 < 64) + return true; + return false; +}) + (define_predicate "move_operand" (match_operand 0 "general_operand") { diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index a5940dc..7b411f0 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1711,6 +1711,38 @@ [(set_attr "type" "shift") (set_attr "mode" "SI")]) +;; Handle AND with 2^N-1 for N from 12 to XLEN. This can be split into +;; two logical shifts. Otherwise it requires 3 instructions: lui, +;; xor/addi/srli, and. +(define_split + [(set (match_operand:GPR 0 "register_operand") + (and:GPR (match_operand:GPR 1 "register_operand") + (match_operand:GPR 2 "p2m1_shift_operand")))] + "" + [(set (match_dup 0) + (ashift:GPR (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (lshiftrt:GPR (match_dup 0) (match_dup 2)))] +{ + operands[2] = GEN_INT (BITS_PER_WORD + - exact_log2 (INTVAL (operands[2]) + 1)); +}) + +;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros. This can be +;; split into two shifts. Otherwise it requires 3 instructions: li, sll, and. +(define_split + [(set (match_operand:DI 0 "register_operand") + (and:DI (match_operand:DI 1 "register_operand") + (match_operand:DI 2 "high_mask_shift_operand")))] + "TARGET_64BIT" + [(set (match_dup 0) + (lshiftrt:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (ashift:DI (match_dup 0) (match_dup 2)))] +{ + operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2]))); +}) + ;; ;; .................... ;; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 88fd3c8..7992353 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-06-30 Jim Wilson <jimw@sifive.com> + + * gcc.target/riscv/shift-shift-1.c: New. + * gcc.target/riscv/shift-shift-2.c: New. + * gcc.target/riscv/shift-shift-3.c: New. + 2018-06-30 Richard Sandiford <richard.sandiford@arm.com> * gcc.dg/vect/vect-widen-mult-extern-1.c: New test. diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-1.c b/gcc/testsuite/gcc.target/riscv/shift-shift-1.c new file mode 100644 index 0000000..a5343a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/shift-shift-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc -mabi=ilp32 -O" } */ + +/* Test for lshrsi3_zero_extend_3+1 pattern that uses p2m1_shift_operand. */ +unsigned int +sub1 (unsigned int i) +{ + return (i << 1) >> 1; +} + +unsigned int +sub2 (unsigned int i) +{ + return (i << 20) >> 20; +} +/* { dg-final { scan-assembler-times "slli" 2 } } */ +/* { dg-final { scan-assembler-times "srli" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c new file mode 100644 index 0000000..3f07e77 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64 -O" } */ + +/* Test for lshrsi3_zero_extend_3+1 pattern that uses p2m1_shift_operand. */ +unsigned int +sub1 (unsigned int i) +{ + return (i << 1) >> 1; +} + +unsigned int +sub2 (unsigned int i) +{ + return (i << 20) >> 20; +} + +unsigned long +sub3 (unsigned long i) +{ + return (i << 1) >> 1; +} + +unsigned long +sub4 (unsigned long i) +{ + return (i << 52) >> 52; +} +/* { dg-final { scan-assembler-times "slli" 4 } } */ +/* { dg-final { scan-assembler-times "srli" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-3.c b/gcc/testsuite/gcc.target/riscv/shift-shift-3.c new file mode 100644 index 0000000..c974e75 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/shift-shift-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64 -O" } */ + +/* Test for lshrsi3_zero_extend_3+2 pattern that uses + high_mask_shift_operand. */ +unsigned long +sub1 (unsigned long i) +{ + return (i >> 32) << 32; +} + +unsigned long +sub2 (unsigned long i) +{ + return (i >> 63) << 63; +} +/* { dg-final { scan-assembler-times "slli" 2 } } */ +/* { dg-final { scan-assembler-times "srli" 2 } } */ |