Commit 666fdc46 by Jim Wilson Committed by Jim Wilson

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
parent 3330053e
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,
......
......@@ -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")
{
......
......@@ -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])));
})
;;
;; ....................
;;
......
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.
......
/* { 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 } } */
/* { 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 } } */
/* { 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 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment