From: Roger Sayle Date: Fri, 14 Jul 2023 17:21:56 +0000 (+0100) Subject: PR target/110588: Add *bt_setncqi_2 to generate btl on x86. X-Git-Tag: basepoints/gcc-15~7611 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43a0a5cd57eefd5a5bbead606ec4f6959af31802;p=thirdparty%2Fgcc.git PR target/110588: Add *bt_setncqi_2 to generate btl on x86. This patch resolves PR target/110588 to catch another case in combine where the i386 backend should be generating a btl instruction. This adds another define_insn_and_split to recognize the RTL representation for this case. I also noticed that two related define_insn_and_split weren't using the preferred string style for single statement preparation-statements, so I've reformatted these to be consistent in style with the new one. 2023-07-14 Roger Sayle gcc/ChangeLog PR target/110588 * config/i386/i386.md (*bt_setcqi): Prefer string form preparation statement over braces for a single statement. (*bt_setncqi): Likewise. (*bt_setncqi_2): New define_insn_and_split. gcc/testsuite/ChangeLog PR target/110588 * gcc.target/i386/pr110588.c: New test case. --- diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 89a7fb0de260..47ea050253a5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -16287,9 +16287,7 @@ (const_int 0))) (set (match_dup 0) (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] -{ - operands[2] = lowpart_subreg (SImode, operands[2], QImode); -}) + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") ;; Help combine recognize bt followed by setnc (define_insn_and_split "*bt_setncqi" @@ -16310,9 +16308,7 @@ (const_int 0))) (set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] -{ - operands[2] = lowpart_subreg (SImode, operands[2], QImode); -}) + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") (define_insn_and_split "*bt_setnc" [(set (match_operand:SWI48 0 "register_operand") @@ -16336,6 +16332,27 @@ operands[2] = lowpart_subreg (SImode, operands[2], QImode); operands[3] = gen_reg_rtx (QImode); }) + +;; Help combine recognize bt followed by setnc (PR target/110588) +(define_insn_and_split "*bt_setncqi_2" + [(set (match_operand:QI 0 "register_operand") + (eq:QI + (zero_extract:SWI48 + (match_operand:SWI48 1 "register_operand") + (const_int 1) + (zero_extend:SI (match_operand:QI 2 "register_operand"))) + (const_int 0))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_USE_BT && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) + (const_int 0))) + (set (match_dup 0) + (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))] + "operands[2] = lowpart_subreg (SImode, operands[2], QImode);") ;; Store-flag instructions. diff --git a/gcc/testsuite/gcc.target/i386/pr110588.c b/gcc/testsuite/gcc.target/i386/pr110588.c new file mode 100644 index 000000000000..4505c87a5946 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110588.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=core2" } */ + +unsigned char foo (unsigned char x, int y) +{ + int _1 = (int) x; + int _2 = _1 >> y; + int _3 = _2 & 1; + unsigned char _8 = (unsigned char) _3; + unsigned char _6 = _8 ^ 1; + return _6; +} + +/* { dg-final { scan-assembler "btl" } } */ +/* { dg-final { scan-assembler "setnc" } } */ +/* { dg-final { scan-assembler-not "sarl" } } */ +/* { dg-final { scan-assembler-not "andl" } } */ +/* { dg-final { scan-assembler-not "xorl" } } */