From: Jakub Jelinek Date: Thu, 23 Jan 2020 11:39:13 +0000 (+0100) Subject: i386: Use bzhi for x & ((1 << y) - 1) or x & ((1U << y) - 1) [PR93346] X-Git-Tag: basepoints/gcc-11~1907 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9592f639ff4655203f1cffb7c6752696e2721fb0;p=thirdparty%2Fgcc.git 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 PR target/93346 * config/i386/i386.md (*bmi2_bzhi_3_2, *bmi2_bzhi_3_3): New define_insn patterns. * gcc.target/i386/pr93346.c: New test. --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d634b378afc4..e62d3c023311 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-01-23 Jakub Jelinek + + PR target/93346 + * config/i386/i386.md (*bmi2_bzhi_3_2, *bmi2_bzhi_3_3): + New define_insn patterns. + 2020-01-23 Richard Sandiford * doc/sourcebuild.texi (check-function-bodies): Add an diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 6c674aaea5bf..b5b53bbcfaa7 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14304,6 +14304,35 @@ (set_attr "prefix" "vex") (set_attr "mode" "")]) +(define_insn "*bmi2_bzhi_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{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "bitmanip") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "*bmi2_bzhi_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{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "bitmanip") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "bmi2_pdep_3" [(set (match_operand:SWI48 0 "register_operand" "=r") (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 22c172f299bb..dbcd8dd83902 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-01-23 Jakub Jelinek + + PR target/93346 + * gcc.target/i386/pr93346.c: New test. + 2020-01-23 Martin Sebor PR c/84919 diff --git a/gcc/testsuite/gcc.target/i386/pr93346.c b/gcc/testsuite/gcc.target/i386/pr93346.c new file mode 100644 index 000000000000..bad5c48f9452 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93346.c @@ -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); +}