gcc: xtensa: fix PR target/98285

2020-12-14  Max Filippov  <jcmvbkbc@gmail.com>
gcc/
	* config/xtensa/predicates.md (addsubx_operand): Change accepted
	values from 2/4/8 to 1..3.
	* config/xtensa/xtensa.md (*addx, *subx): Change RTL pattern
	to use 'ashift' instead of 'mult'. Update operands[3] value.

gcc/testsuite/
	* gcc.target/xtensa/pr98285.c: New test.
This commit is contained in:
Max Filippov 2020-12-12 12:14:40 -08:00
parent 773a4106bb
commit 06ff8708f0
3 changed files with 68 additions and 9 deletions

View file

@ -25,9 +25,8 @@
(define_predicate "addsubx_operand"
(and (match_code "const_int")
(match_test "INTVAL (op) == 2
|| INTVAL (op) == 4
|| INTVAL (op) == 8")))
(match_test "INTVAL (op) >= 1
&& INTVAL (op) <= 3")))
(define_predicate "arith_operand"
(ior (and (match_code "const_int")

View file

@ -162,11 +162,14 @@
(define_insn "*addx"
[(set (match_operand:SI 0 "register_operand" "=a")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 3 "addsubx_operand" "i"))
(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 3 "addsubx_operand" "i"))
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_ADDX"
"addx%3\t%0, %1, %2"
{
operands[3] = GEN_INT (1 << INTVAL (operands[3]));
return "addx%3\t%0, %1, %2";
}
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "3")])
@ -196,11 +199,14 @@
(define_insn "*subx"
[(set (match_operand:SI 0 "register_operand" "=a")
(minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 3 "addsubx_operand" "i"))
(minus:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 3 "addsubx_operand" "i"))
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_ADDX"
"subx%3\t%0, %1, %2"
{
operands[3] = GEN_INT (1 << INTVAL (operands[3]));
return "subx%3\t%0, %1, %2";
}
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "3")])

View file

@ -0,0 +1,54 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
int mul3(int v)
{
return v * 3;
}
int mul5(int v)
{
return v * 5;
}
int mul7(int v)
{
return v * 7;
}
int mul9(int v)
{
return v * 9;
}
int mul2sub(int a, int b)
{
return a * 2 - b;
}
int mul4sub(int a, int b)
{
return a * 4 - b;
}
short index2(short *p, int i)
{
return p[i];
}
int index4(int *p, int i)
{
return p[i];
}
long long index8(long long *p, int i)
{
return p[i];
}
/* { dg-final { scan-assembler-times "addx2" 2 } } */
/* { dg-final { scan-assembler-times "addx4" 2 } } */
/* { dg-final { scan-assembler-times "addx8" 2 } } */
/* { dg-final { scan-assembler-times "subx2" 1 } } */
/* { dg-final { scan-assembler-times "subx4" 1 } } */
/* { dg-final { scan-assembler-times "subx8" 1 } } */