i386: Use bzhi for x & ((1 << y) - 1) or x & ((1U << y) - 1) [PR93346]
The bzhi patterns are quite complicated because they need to accurately describe the behavior of the instruction for all input values. The following patterns are simple and make bzhi recognizable even for cases where not all input values are valid, because the user used a shift, in which case the low 8 bit of the last operand need to be in between 0 and precision-1. 2020-01-23 Jakub Jelinek <jakub@redhat.com> PR target/93346 * config/i386/i386.md (*bmi2_bzhi_<mode>3_2, *bmi2_bzhi_<mode>3_3): New define_insn patterns. * gcc.target/i386/pr93346.c: New test.
This commit is contained in:
parent
8a990ffafa
commit
9592f639ff
4 changed files with 116 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
|||
2020-01-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/93346
|
||||
* config/i386/i386.md (*bmi2_bzhi_<mode>3_2, *bmi2_bzhi_<mode>3_3):
|
||||
New define_insn patterns.
|
||||
|
||||
2020-01-23 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* doc/sourcebuild.texi (check-function-bodies): Add an
|
||||
|
|
|
@ -14304,6 +14304,35 @@
|
|||
(set_attr "prefix" "vex")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "*bmi2_bzhi_<mode>3_2"
|
||||
[(set (match_operand:SWI48 0 "register_operand" "=r")
|
||||
(and:SWI48
|
||||
(plus:SWI48
|
||||
(ashift:SWI48 (const_int 1)
|
||||
(match_operand:QI 2 "register_operand" "r"))
|
||||
(const_int -1))
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "rm")))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"TARGET_BMI2"
|
||||
"bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
|
||||
[(set_attr "type" "bitmanip")
|
||||
(set_attr "prefix" "vex")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "*bmi2_bzhi_<mode>3_3"
|
||||
[(set (match_operand:SWI48 0 "register_operand" "=r")
|
||||
(and:SWI48
|
||||
(not:SWI48
|
||||
(ashift:SWI48 (const_int -1)
|
||||
(match_operand:QI 2 "register_operand" "r")))
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "rm")))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"TARGET_BMI2"
|
||||
"bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
|
||||
[(set_attr "type" "bitmanip")
|
||||
(set_attr "prefix" "vex")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "bmi2_pdep_<mode>3"
|
||||
[(set (match_operand:SWI48 0 "register_operand" "=r")
|
||||
(unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2020-01-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/93346
|
||||
* gcc.target/i386/pr93346.c: New test.
|
||||
|
||||
2020-01-23 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/84919
|
||||
|
|
76
gcc/testsuite/gcc.target/i386/pr93346.c
Normal file
76
gcc/testsuite/gcc.target/i386/pr93346.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* PR target/93346 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -mbmi2" } */
|
||||
/* { dg-final { scan-assembler-times "\tbzhi\t" 12 } } */
|
||||
|
||||
unsigned int
|
||||
f1 (unsigned int x, unsigned int y)
|
||||
{
|
||||
return x & ((1 << y) - 1);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
f2 (unsigned int x, unsigned int y)
|
||||
{
|
||||
return x & ((1U << y) - 1);
|
||||
}
|
||||
|
||||
int
|
||||
f3 (int x, unsigned int y)
|
||||
{
|
||||
return x & ((1 << y) - 1);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
f4 (unsigned long x, unsigned int y)
|
||||
{
|
||||
return x & ((1L << y) - 1);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
f5 (unsigned long x, unsigned int y)
|
||||
{
|
||||
return x & ((1UL << y) - 1);
|
||||
}
|
||||
|
||||
long
|
||||
f6 (long x, unsigned int y)
|
||||
{
|
||||
return x & ((1L << y) - 1);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
f7 (unsigned int x, int y)
|
||||
{
|
||||
return x & ((1 << y) - 1);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
f8 (unsigned int x, int y)
|
||||
{
|
||||
return x & ((1U << y) - 1);
|
||||
}
|
||||
|
||||
int
|
||||
f9 (int x, int y)
|
||||
{
|
||||
return x & ((1 << y) - 1);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
f10 (unsigned long x, int y)
|
||||
{
|
||||
return x & ((1L << y) - 1);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
f11 (unsigned long x, int y)
|
||||
{
|
||||
return x & ((1UL << y) - 1);
|
||||
}
|
||||
|
||||
long
|
||||
f12 (long x, int y)
|
||||
{
|
||||
return x & ((1L << y) - 1);
|
||||
}
|
Loading…
Add table
Reference in a new issue