aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-06-30 21:52:01 +0000
committerJim Wilson <wilson@gcc.gnu.org>2018-06-30 14:52:01 -0700
commit666fdc46bc848984ee7d2906f2dfe10e1ee5d535 (patch)
treedfcba939f1bcd8dc96d335edf960ac2bf2c767a9 /gcc
parent3330053ecaafe8bca82cc3845be9b2d01a614eb1 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/riscv/predicates.md20
-rw-r--r--gcc/config/riscv/riscv.md32
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/riscv/shift-shift-1.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/shift-shift-2.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/shift-shift-3.c18
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 } } */