Hi,

For spiltter after <rotate_insn><mode>3_mask it now splits the pattern
to *<rotate_insn><mode>3_mask, causing the splitter doesn't generate
nf variant. Add corresponding nf counterpart for define_insn_and_split
to make the splitter also works for nf insn.

Bootstrapped & regtested on x86-64-pc-linux-gnu.

Ok for trunk?

gcc/ChangeLog:

        PR target/119539
        * config/i386/i386.md (*<insn><mode>3_mask_nf): New
        define_insn_and_split.
        (*<insn><mode>3_mask_1_nf): Likewise.
        (*<insn><mode>3_mask): Use force_lowpart_subreg.

gcc/testsuite/ChangeLog:

        PR target/119539
        * gcc.target/i386/apx-nf-pr119539.c: New test.
---
 gcc/config/i386/i386.md                       | 46 ++++++++++++++++++-
 .../gcc.target/i386/apx-nf-pr119539.c         |  6 +++
 2 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f7f790d2aeb..42312f0c330 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -18131,6 +18131,30 @@ (define_expand "<insn><mode>3"
   DONE;
 })
 
+;; Avoid useless masking of count operand.
+(define_insn_and_split "*<insn><mode>3_mask_nf"
+  [(set (match_operand:SWI 0 "nonimmediate_operand")
+       (any_rotate:SWI
+         (match_operand:SWI 1 "nonimmediate_operand")
+         (subreg:QI
+           (and
+             (match_operand 2 "int248_register_operand" "c")
+             (match_operand 3 "const_int_operand")) 0)))]
+  "TARGET_APX_NF
+   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+      == GET_MODE_BITSIZE (<MODE>mode)-1
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (match_dup 0)
+       (any_rotate:SWI (match_dup 1)
+                       (match_dup 2)))]
+{
+  operands[2] = force_lowpart_subreg (QImode, operands[2],
+                                     GET_MODE (operands[2]));
+})
+
 ;; Avoid useless masking of count operand.
 (define_insn_and_split "*<insn><mode>3_mask"
   [(set (match_operand:SWI 0 "nonimmediate_operand")
@@ -18153,8 +18177,8 @@ (define_insn_and_split "*<insn><mode>3_mask"
                           (match_dup 2)))
       (clobber (reg:CC FLAGS_REG))])]
 {
-  operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
-  operands[2] = gen_lowpart (QImode, operands[2]);
+  operands[2] = force_lowpart_subreg (QImode, operands[2],
+                                     GET_MODE (operands[2]));
 })
 
 (define_split
@@ -18174,6 +18198,24 @@ (define_split
                         (and:SI (match_dup 2) (match_dup 3)) 0)))]
  "operands[4] = gen_reg_rtx (<MODE>mode);")
 
+(define_insn_and_split "*<insn><mode>3_mask_1_nf"
+  [(set (match_operand:SWI 0 "nonimmediate_operand")
+       (any_rotate:SWI
+         (match_operand:SWI 1 "nonimmediate_operand")
+         (and:QI
+           (match_operand:QI 2 "register_operand" "c")
+           (match_operand:QI 3 "const_int_operand"))))]
+  "TARGET_APX_NF
+   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+      == GET_MODE_BITSIZE (<MODE>mode)-1
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (match_dup 0)
+       (any_rotate:SWI (match_dup 1)
+                       (match_dup 2)))])
+
 (define_insn_and_split "*<insn><mode>3_mask_1"
   [(set (match_operand:SWI 0 "nonimmediate_operand")
        (any_rotate:SWI
diff --git a/gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c 
b/gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c
new file mode 100644
index 00000000000..5dfec55ed76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapx-features=nf -march=x86-64 -O2" } */
+/* { dg-final { scan-assembler-times "\{nf\} rol" 2 } } */
+
+long int f1 (int x) { return ~(1ULL << (x & 0x3f)); }
+long int f2 (char x) { return ~(1ULL << (x & 0x3f)); }
-- 
2.31.1

Reply via email to