From 23902d70375e9ca12883343197c5d35587013fe7 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 19 Sep 2017 23:14:11 +0200 Subject: [PATCH] i386.md (*scc_bt): New insn_and_split pattern. * config/i386/i386.md (*scc_bt): New insn_and_split pattern. (*scc_bt_1): Ditto. (*scc_bt_mask): Ditto. testsuite/ChangeLog: * gcc.target/i386/bt-5.c: New test. * gcc.target/i386/bt-6.c: Ditto. * gcc.target/i386/bt-mask-3.c: Ditto. * gcc.target/i386/bt-mask-4.c: Ditto. From-SVN: r252986 --- gcc/ChangeLog | 6 ++ gcc/config/i386/i386.md | 92 +++++++++++++++++++++++ gcc/testsuite/ChangeLog | 7 ++ gcc/testsuite/gcc.target/i386/bt-5.c | 11 +++ gcc/testsuite/gcc.target/i386/bt-6.c | 12 +++ gcc/testsuite/gcc.target/i386/bt-mask-3.c | 12 +++ gcc/testsuite/gcc.target/i386/bt-mask-4.c | 12 +++ 7 files changed, 152 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/bt-5.c create mode 100644 gcc/testsuite/gcc.target/i386/bt-6.c create mode 100644 gcc/testsuite/gcc.target/i386/bt-mask-3.c create mode 100644 gcc/testsuite/gcc.target/i386/bt-mask-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 35a36024ec2..9576c8c4f47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-09-19 Uros Bizjak + + * config/i386/i386.md (*scc_bt): New insn_and_split pattern. + (*scc_bt_1): Ditto. + (*scc_bt_mask): Ditto. + 2017-09-19 Uros Bizjak * config/i386/i386.c (ix86_split_long_move): Do not handle diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 43227dc77ee..b1bde14ad5e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11246,6 +11246,98 @@ (const_string "SI") (const_string "")))]) +(define_insn_and_split "*scc_bt" + [(set (match_operand:QI 0 "nonimmediate_operand") + (match_operator 1 "bt_comparison_operator" + [(zero_extract:SWI48 + (match_operand:SWI48 2 "nonimmediate_operand") + (const_int 1) + (match_operand:SI 3 "nonmemory_operand")) + (const_int 0)])) + (clobber (reg:CC FLAGS_REG))] + "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) + && (CONST_INT_P (operands[3]) + ? (INTVAL (operands[3]) < GET_MODE_BITSIZE (mode) + && INTVAL (operands[3]) + >= (optimize_function_for_size_p (cfun) ? 8 : 32)) + : !memory_operand (operands[2], mode)) + && can_create_pseudo_p ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 + (match_dup 2) + (const_int 1) + (match_dup 3)) + (const_int 0))) + (set (match_dup 0) + (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))] +{ + operands[1] = shallow_copy_rtx (operands[1]); + PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); +}) + +(define_insn_and_split "*scc_bt_1" + [(set (match_operand:QI 0 "nonimmediate_operand") + (match_operator 1 "bt_comparison_operator" + [(zero_extract:SWI48 + (match_operand:SWI48 2 "register_operand") + (const_int 1) + (zero_extend:SI + (match_operand:QI 3 "register_operand"))) + (const_int 0)])) + (clobber (reg:CC FLAGS_REG))] + "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) + && can_create_pseudo_p ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 + (match_dup 2) + (const_int 1) + (match_dup 3)) + (const_int 0))) + (set (match_dup 0) + (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))] +{ + operands[3] = lowpart_subreg (SImode, operands[3], QImode); + operands[1] = shallow_copy_rtx (operands[1]); + PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); +}) + +;; Avoid useless masking of bit offset operand. +(define_insn_and_split "*scc_bt_mask" + [(set (match_operand:QI 0 "nonimmediate_operand") + (match_operator 1 "bt_comparison_operator" + [(zero_extract:SWI48 + (match_operand:SWI48 2 "register_operand") + (const_int 1) + (and:SI + (match_operand:SI 3 "register_operand") + (match_operand 4 "const_int_operand")))])) + (clobber (reg:CC FLAGS_REG))] + "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) + && (INTVAL (operands[4]) & (GET_MODE_BITSIZE (mode)-1)) + == GET_MODE_BITSIZE (mode)-1 + && can_create_pseudo_p ()" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SWI48 + (match_dup 2) + (const_int 1) + (match_dup 3)) + (const_int 0))) + (set (match_dup 0) + (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))] +{ + operands[1] = shallow_copy_rtx (operands[1]); + PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); +}) + (define_insn_and_split "*jcc_bt" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4362138d2ca..011420575b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-09-19 Uros Bizjak + + * gcc.target/i386/bt-5.c: New test. + * gcc.target/i386/bt-6.c: Ditto. + * gcc.target/i386/bt-mask-3.c: Ditto. + * gcc.target/i386/bt-mask-4.c: Ditto. + 2017-09-19 Jakub Jelinek * g++.dg/tree-ssa/pr31146-2.C: Only do scan-tree-dump for c++14_down. diff --git a/gcc/testsuite/gcc.target/i386/bt-5.c b/gcc/testsuite/gcc.target/i386/bt-5.c new file mode 100644 index 00000000000..309adfe291e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bt-5.c @@ -0,0 +1,11 @@ +/* PR target/36473 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=core2" } */ +/* { dg-additional-options "-mregparm=2" { target ia32 } } */ + +int test(unsigned x, unsigned n) +{ + return !(x & ( 0x01 << n )); +} + +/* { dg-final { scan-assembler "btl\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/i386/bt-6.c b/gcc/testsuite/gcc.target/i386/bt-6.c new file mode 100644 index 00000000000..994ec432e0e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bt-6.c @@ -0,0 +1,12 @@ +/* PR target/36473 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=core2" } */ +/* { dg-additional-options "-mregparm=2" { target ia32 } } */ + +int test(unsigned long x, unsigned long n) +{ + return !(x & ( (long)0x01 << n )); +} + +/* { dg-final { scan-assembler "btl\[ \t\]" { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler "btq\[ \t\]" { target lp64 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/bt-mask-3.c b/gcc/testsuite/gcc.target/i386/bt-mask-3.c new file mode 100644 index 00000000000..bf3a404b0d5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bt-mask-3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=core2" } */ +/* { dg-additional-options "-mregparm=2" { target ia32 } } */ + +int test (unsigned x, unsigned n) +{ + n &= 0x1f; + + return !(x & (0x01 << n)); +} + +/* { dg-final { scan-assembler-not "and\[lq\]\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/i386/bt-mask-4.c b/gcc/testsuite/gcc.target/i386/bt-mask-4.c new file mode 100644 index 00000000000..819864686f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bt-mask-4.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=core2" } */ +/* { dg-additional-options "-mregparm=2" { target ia32 } } */ + +int test (unsigned long x, unsigned long n) +{ + n &= 0x3f; + + return !(x & ((long)0x01 << n)); +} + +/* { dg-final { scan-assembler-not "and\[lq\]\[ \t\]" } } */ -- 2.30.2