https://gcc.gnu.org/g:af4fb245e12f2dd8e2c32167c9acfaceb4b6af6a

commit r15-7036-gaf4fb245e12f2dd8e2c32167c9acfaceb4b6af6a
Author: Hongyu Wang <hongyu.w...@intel.com>
Date:   Fri Jan 17 09:04:17 2025 +0800

    i386: Fix wrong insn generated by shld/shrd ndd split [PR118510]
    
    For shld/shrd_ndd_2 insn, the spiltter outputs wrong pattern that
    mixed parallel for clobber and set. Use register_operand as dest
    and ajdust output template to fix.
    
    gcc/ChangeLog:
    
            PR target/118510
            * config/i386/i386.md (*x86_64_shld_ndd_2): Use register_operand
            for operand[0] and adjust the output template to directly
            generate ndd form shld pattern.
            (*x86_shld_ndd_2): Likewise.
            (*x86_64_shrd_ndd_2): Likewise.
            (*x86_shrd_ndd_2): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            PR target/118510
            * gcc.target/i386/pr118510.c: New test.

Diff:
---
 gcc/config/i386/i386.md                  | 44 +++++++++-----------------------
 gcc/testsuite/gcc.target/i386/pr118510.c | 14 ++++++++++
 2 files changed, 26 insertions(+), 32 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 5fbd0848df5b..c977e86b72e8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15596,7 +15596,7 @@
              (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn_and_split "*x86_64_shld_ndd_2"
-  [(set (match_operand:DI 0 "nonimmediate_operand")
+  [(set (match_operand:DI 0 "register_operand")
        (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
                           (match_operand:QI 3 "nonmemory_operand"))
                (lshiftrt:DI (match_operand:DI 2 "register_operand")
@@ -15606,7 +15606,7 @@
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
-  [(parallel [(set (match_dup 4)
+  [(parallel [(set (match_dup 0)
                   (ior:DI (ashift:DI (match_dup 1)
                                      (and:QI (match_dup 3) (const_int 63)))
                           (subreg:DI
@@ -15615,12 +15615,7 @@
                                 (minus:QI (const_int 64)
                                           (and:QI (match_dup 3)
                                                   (const_int 63)))) 0)))
-             (clobber (reg:CC FLAGS_REG))
-             (set (match_dup 0) (match_dup 4))])]
-{
-  operands[4] = gen_reg_rtx (DImode);
-  emit_move_insn (operands[4], operands[0]);
-})
+             (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn "x86_shld<nf_name>"
   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
@@ -15832,7 +15827,7 @@
              (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn_and_split "*x86_shld_ndd_2"
-  [(set (match_operand:SI 0 "nonimmediate_operand")
+  [(set (match_operand:SI 0 "register_operand")
        (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
                           (match_operand:QI 3 "nonmemory_operand"))
                (lshiftrt:SI (match_operand:SI 2 "register_operand")
@@ -15842,7 +15837,7 @@
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
-  [(parallel [(set (match_dup 4)
+  [(parallel [(set (match_dup 0)
                   (ior:SI (ashift:SI (match_dup 1)
                                      (and:QI (match_dup 3) (const_int 31)))
                           (subreg:SI
@@ -15851,12 +15846,7 @@
                                 (minus:QI (const_int 32)
                                           (and:QI (match_dup 3)
                                                   (const_int 31)))) 0)))
-             (clobber (reg:CC FLAGS_REG))
-             (set (match_dup 0) (match_dup 4))])]
-{
-  operands[4] = gen_reg_rtx (SImode);
-  emit_move_insn (operands[4], operands[0]);
-})
+             (clobber (reg:CC FLAGS_REG))])])
 
 (define_expand "@x86_shift<mode>_adj_1"
   [(set (reg:CCZ FLAGS_REG)
@@ -16991,7 +16981,7 @@
              (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn_and_split "*x86_64_shrd_ndd_2"
-  [(set (match_operand:DI 0 "nonimmediate_operand")
+  [(set (match_operand:DI 0 "register_operand")
        (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
                             (match_operand:QI 3 "nonmemory_operand"))
                (ashift:DI (match_operand:DI 2 "register_operand")
@@ -17001,7 +16991,7 @@
   && ix86_pre_reload_split ()"
   "#"
   "&& 1"
-  [(parallel [(set (match_dup 4)
+  [(parallel [(set (match_dup 0)
                   (ior:DI (lshiftrt:DI (match_dup 1)
                                        (and:QI (match_dup 3) (const_int 63)))
                           (subreg:DI
@@ -17010,12 +17000,7 @@
                                 (minus:QI (const_int 64)
                                           (and:QI (match_dup 3)
                                                   (const_int 63)))) 0)))
-             (clobber (reg:CC FLAGS_REG))
-             (set (match_dup 0) (match_dup 4))])]
-{
-  operands[4] = gen_reg_rtx (DImode);
-  emit_move_insn (operands[4], operands[0]);
-})
+             (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn "x86_shrd<nf_name>"
   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
@@ -17226,7 +17211,7 @@
              (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn_and_split "*x86_shrd_ndd_2"
-  [(set (match_operand:SI 0 "nonimmediate_operand")
+  [(set (match_operand:SI 0 "register_operand")
        (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
                           (match_operand:QI 3 "nonmemory_operand"))
                (ashift:SI (match_operand:SI 2 "register_operand")
@@ -17236,7 +17221,7 @@
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
-  [(parallel [(set (match_dup 4)
+  [(parallel [(set (match_dup 0)
                   (ior:SI (lshiftrt:SI (match_dup 1)
                                        (and:QI (match_dup 3) (const_int 31)))
                           (subreg:SI
@@ -17245,12 +17230,7 @@
                                 (minus:QI (const_int 32)
                                           (and:QI (match_dup 3)
                                                   (const_int 31)))) 0)))
-             (clobber (reg:CC FLAGS_REG))
-             (set (match_dup 0) (match_dup 4))])]
-{
-  operands[4] = gen_reg_rtx (SImode);
-  emit_move_insn (operands[4], operands[0]);
-})
+             (clobber (reg:CC FLAGS_REG))])])
 
 ;; Base name for insn mnemonic.
 (define_mode_attr cvt_mnemonic
diff --git a/gcc/testsuite/gcc.target/i386/pr118510.c 
b/gcc/testsuite/gcc.target/i386/pr118510.c
new file mode 100644
index 000000000000..6cfe8182b6f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr118510.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mapxf" } */
+
+typedef struct cpp_num cpp_num;
+struct cpp_num {
+    int high;
+    unsigned low;
+    int overflow;
+};
+int num_rshift_n;
+cpp_num num_lshift(cpp_num num) {
+    num.low = num.low >> num_rshift_n | num.high << (32 - num_rshift_n);
+    return num;
+}

Reply via email to