https://gcc.gnu.org/g:1b761744dc3ea6f3d66a9c48f16719ad1c92d5ad

commit r15-2914-g1b761744dc3ea6f3d66a9c48f16719ad1c92d5ad
Author: Lingling Kong <lingling.k...@intel.com>
Date:   Wed Aug 14 16:38:46 2024 +0800

    i386: Optimization for APX NDD is always zero-uppered for sub/adc/sbb
    
    gcc/ChangeLog:
    
            PR target/113729
            * config/i386/i386.md (*subqi_1_zext<mode><nf_name>): New
            define_insn.
            (*subhi_1_zext<mode><nf_name>): Ditto.
            (*addqi3_carry_zext<mode>): Ditto.
            (*addhi3_carry_zext<mode>): Ditto.
            (*addqi3_carry_zext<mode>_0): Ditto.
            (*addhi3_carry_zext<mode>_0): Ditto.
            (*addqi3_carry_zext<mode>_0r): Ditto.
            (*addhi3_carry_zext<mode>_0r): Ditto.
            (*subqi3_carry_zext<mode>): Ditto.
            (*subhi3_carry_zext<mode>): Ditto.
            (*subqi3_carry_zext<mode>_0): Ditto.
            (*subhi3_carry_zext<mode>_0): Ditto.
            (*subqi3_carry_zext<mode>_0r): Ditto.
            (*subhi3_carry_zext<mode>_0r): Ditto.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/pr113729.c: Add more test.
            * gcc.target/i386/pr113729-adc-sbb.c: New test.

Diff:
---
 gcc/config/i386/i386.md                          | 244 ++++++++++++++++++++++-
 gcc/testsuite/gcc.target/i386/pr113729-adc-sbb.c |  63 ++++++
 gcc/testsuite/gcc.target/i386/pr113729.c         |   6 +
 3 files changed, 305 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 5f237275bdc8..e267b330b251 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -8043,6 +8043,34 @@
    (set_attr "has_nf" "1")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*subqi_1_zext<mode><nf_name>"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
+       (zero_extend:SWI248x
+         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "rm,r")
+                   (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
+  "TARGET_APX_NDD && <nf_condition>
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "@
+  <nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}
+  <nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "has_nf" "1")
+   (set_attr "mode" "QI")])
+
+(define_insn "*subhi_1_zext<mode><nf_name>"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
+       (zero_extend:SWI48x
+         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "rm,r")
+                   (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
+  "TARGET_APX_NDD && <nf_condition>
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "@
+  <nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}
+  <nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "has_nf" "1")
+   (set_attr "mode" "HI")])
+
 (define_insn "*subsi_1_zext"
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
@@ -8762,6 +8790,44 @@
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*addqi3_carry_zext<mode>"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
+       (zero_extend:SWI248x
+         (plus:QI
+           (plus:QI (match_operator:QI 3 "ix86_carry_flag_operator"
+                     [(reg FLAGS_REG) (const_int 0)])
+                    (match_operand:QI 1 "nonimmediate_operand" "%rm,r"))
+           (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "@
+  adc{b}\t{%2, %1, %b0|%b0, %1, %2}
+  adc{b}\t{%2, %1, %b0|%b0, %1, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*addhi3_carry_zext<mode>"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
+       (zero_extend:SWI48x
+         (plus:HI
+           (plus:HI (match_operator:HI 3 "ix86_carry_flag_operator"
+                     [(reg FLAGS_REG) (const_int 0)])
+                    (match_operand:HI 1 "nonimmediate_operand" "%rm,r"))
+           (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "@
+  adc{w}\t{%2, %1, %w0|%w0, %1, %2}
+  adc{w}\t{%2, %1, %w0|%w0, %1, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "HI")])
+
 (define_insn "*addsi3_carry_zext"
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
@@ -8783,6 +8849,34 @@
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
+(define_insn "*addqi3_carry_zext<mode>_0"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r")
+       (zero_extend:SWI248x
+         (plus:QI (match_operator:QI 2 "ix86_carry_flag_operator"
+                   [(reg FLAGS_REG) (const_int 0)])
+                  (match_operand:QI 1 "nonimmediate_operand" "rm"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "adc{b}\t{$0, %1, %b0|%b0, %1, 0}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*addhi3_carry_zext<mode>_0"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r")
+       (zero_extend:SWI48x
+         (plus:HI (match_operator:HI 2 "ix86_carry_flag_operator"
+                   [(reg FLAGS_REG) (const_int 0)])
+                  (match_operand:HI 1 "nonimmediate_operand" "rm"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "adc{w}\t{$0, %1, %w0|%w0, %1, 0}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "HI")])
+
 (define_insn "*addsi3_carry_zext_0"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
@@ -8800,6 +8894,34 @@
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
+(define_insn "*addqi3_carry_zext<mode>_0r"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r")
+       (zero_extend:SWI248x
+         (plus:QI (match_operator:QI 2 "ix86_carry_flag_unset_operator"
+                   [(reg FLAGS_REG) (const_int 0)])
+                  (match_operand:QI 1 "nonimmediate_operand" "rm"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "sbb{b}\t{$-1, %1, %b0|%b0, %1, -1}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*addhi3_carry_zext<mode>_0r"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r")
+       (zero_extend:SWI48x
+         (plus:HI (match_operator:HI 2 "ix86_carry_flag_unset_operator"
+                   [(reg FLAGS_REG) (const_int 0)])
+                  (match_operand:HI 1 "nonimmediate_operand" "rm"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "sbb{w}\t{$-1, %1, %w0|%w0, %1, -1}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "HI")])
+
 (define_insn "*addsi3_carry_zext_0r"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
@@ -9152,6 +9274,46 @@
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*subqi3_carry_zext<mode>"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
+       (zero_extend:SWI248x
+         (minus:QI
+           (minus:QI
+             (match_operand:QI 1 "nonimmediate_operand" "r,rm")
+             (match_operator:QI 3 "ix86_carry_flag_operator"
+              [(reg FLAGS_REG) (const_int 0)]))
+           (match_operand:QI 2 "x86_64_general_operand" "rBMe,re"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "@
+  sbb{b}\t{%2, %1, %b0|%b0, %1, %2}
+  sbb{b}\t{%2, %1, %b0|%b0, %1, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*subhi3_carry_zext<mode>"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
+       (zero_extend:SWI48x
+         (minus:HI
+           (minus:HI
+             (match_operand:HI 1 "nonimmediate_operand" "r,rm")
+             (match_operator:HI 3 "ix86_carry_flag_operator"
+              [(reg FLAGS_REG) (const_int 0)]))
+           (match_operand:HI 2 "x86_64_general_operand" "rBMe,re"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "@
+  sbb{w}\t{%2, %1, %w0|%w0, %1, %2}
+  sbb{w}\t{%2, %1, %w0|%w0, %1, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "HI")])
+
 (define_insn "*subsi3_carry_zext"
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
@@ -9174,32 +9336,98 @@
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
+(define_insn "*subqi3_carry_zext<mode>_0"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r")
+       (zero_extend:SWI248x
+         (minus:QI
+           (match_operand:QI 1 "nonimmediate_operand" "rm")
+           (match_operator:QI 2 "ix86_carry_flag_operator"
+             [(reg FLAGS_REG) (const_int 0)]))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "sbb{b}\t{$0, %1, %b0|%b0, %1, 0}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*subhi3_carry_zext<mode>_0"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r")
+       (zero_extend:SWI48x
+         (minus:HI
+           (match_operand:HI 1 "nonimmediate_operand" "rm")
+           (match_operator:HI 2 "ix86_carry_flag_operator"
+             [(reg FLAGS_REG) (const_int 0)]))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "sbb{w}\t{$0, %1, %w0|%w0, %1, 0}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "HI")])
+
 (define_insn "*subsi3_carry_zext_0"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
          (minus:SI
-           (match_operand:SI 1 "register_operand" "0")
+           (match_operand:SI 1 "nonimmediate_operand" "0,rm")
            (match_operator:SI 2 "ix86_carry_flag_operator"
              [(reg FLAGS_REG) (const_int 0)]))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
-  "sbb{l}\t{$0, %k0|%k0, 0}"
-  [(set_attr "type" "alu")
+  "@
+  sbb{l}\t{$0, %k0|%k0, 0}
+  sbb{l}\t{$0, %1, %k0|%k0, %1, 0}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
+(define_insn "*subqi3_carry_zext<mode>_0r"
+  [(set (match_operand:SWI248x 0 "register_operand" "=r")
+       (zero_extend:SWI248x
+         (minus:QI
+           (match_operand:QI 1 "nonimmediate_operand" "rm")
+           (match_operator:QI 2 "ix86_carry_flag_unset_operator"
+             [(reg FLAGS_REG) (const_int 0)]))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "adc{b}\t{$-1, %1, %b0|%b0, %1, -1}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*subhi3_carry_zext<mode>_0r"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r")
+       (zero_extend:SWI48x
+         (minus:HI
+           (match_operand:HI 1 "nonimmediate_operand" "rm")
+           (match_operator:HI 2 "ix86_carry_flag_unset_operator"
+             [(reg FLAGS_REG) (const_int 0)]))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "adc{w}\t{$-1, %1, %w0|%w0, %1, -1}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "pent_pair" "pu")
+   (set_attr "mode" "HI")])
+
 (define_insn "*subsi3_carry_zext_0r"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
          (minus:SI
-           (match_operand:SI 1 "register_operand" "0")
+           (match_operand:SI 1 "nonimmediate_operand" "0,rm")
            (match_operator:SI 2 "ix86_carry_flag_unset_operator"
              [(reg FLAGS_REG) (const_int 0)]))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
-  "adc{l}\t{$-1, %k0|%k0, -1}"
-  [(set_attr "type" "alu")
+  "@
+  adc{l}\t{$-1, %k0|%k0, -1}
+  adc{l}\t{$-1, %1, %k0|%k0, %1, -1}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
diff --git a/gcc/testsuite/gcc.target/i386/pr113729-adc-sbb.c 
b/gcc/testsuite/gcc.target/i386/pr113729-adc-sbb.c
new file mode 100644
index 000000000000..8d446b3fb03a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr113729-adc-sbb.c
@@ -0,0 +1,63 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapx-features=ndd -march=x86-64 -O2" } */
+/* { dg-final { scan-assembler-not "movz"} } */
+
+#define FC(TYPE1, TYPE2, OP_NAME, OP)               \
+TYPE1                                               \
+__attribute__ ((noipa))                             \
+fc_##OP_NAME##_##TYPE2##_##TYPE1 (TYPE2 *a, TYPE2 b)\
+{                                                   \
+  unsigned TYPE2 c = (*a OP b OP (a > b)); /* { dg-warning "comparison between 
pointer and integer" } */ \
+  return c;                                         \
+}                      
+
+/* addqi3_carry_zext<mode> */
+FC (char, short, adc, +)
+FC (char, int, adc, +)
+FC (char, long, adc, +)
+FC (short, int, adc, +)
+FC (short, long, adc, +)
+/* subqi3_carry_zext<mode> */
+FC (char, short, sbb, -)
+FC (char, int, sbb, -)
+FC (char, long, sbb, -)
+FC (short, int, sbb, -)
+FC (short, long, sbb, -)
+
+#define FC0(TYPE1, TYPE2, OP_NAME, OP1, OP2)        \
+unsigned TYPE2                                      \
+__attribute__ ((noipa))                             \
+fc0_##OP_NAME##_##TYPE2##_##TYPE1                   \
+(unsigned TYPE1 a, unsigned TYPE1 b, TYPE1 c)       \
+{                                                   \
+  unsigned TYPE1 d = (c OP1 (a OP2 b));             \
+  return d;                                         \
+}                      
+
+/* addqi3_carry_zext<mode>_0 */
+FC0 (char, short, adc, +, <)
+FC0 (char, int, adc, +, <)
+FC0 (char, long, adc, +, <)
+FC0 (short, int, adc, +, <)
+FC0 (short, long, adc, +, <)
+/* subqi3_carry_zext<mode>_0 */
+FC0 (char, short, sbb, -, <)
+FC0 (char, int, sbb, -, <)
+FC0 (char, long, sbb, -, <)
+FC0 (short, int, sbb, -, <)
+FC0 (short, long, sbb, -, <)
+/* subsi3_carry_zext<mode>_0 */
+FC0 (int, long, sbb, -, <)
+/* addqi3_carry_zext<mode>_0r */
+FC0 (char, short, adcr, +, >=)
+FC0 (char, int, adcr, +, >=)
+FC0 (char, long, adcr, +, >=)
+FC0 (short, int, adcr, +, >=)
+FC0 (short, long, adcr, +, >=)
+/* subqi3_carry_zext<mode>_0r */
+FC0 (char, short, sbbr, -, >=)
+FC0 (char, int, sbbr, -, >=)
+FC0 (char, long, sbbr, -, >=)
+FC0 (short, int, sbbr, -, >=)
+FC0 (short, long, sbbr, -, >=)
+FC0 (int, long, sbbr, -, >=)
diff --git a/gcc/testsuite/gcc.target/i386/pr113729.c 
b/gcc/testsuite/gcc.target/i386/pr113729.c
index 34518a5cdc88..b24cb0e07fe8 100644
--- a/gcc/testsuite/gcc.target/i386/pr113729.c
+++ b/gcc/testsuite/gcc.target/i386/pr113729.c
@@ -25,3 +25,9 @@ F (int, char, add, +)
 F (int64_t, char, add, +)
 F (int, short, add, +)
 F (int64_t, short, add, +)
+/* subqi_1_zext<mode> */
+F (short, char, sub, -)
+F (int, char, sub, -)
+F (int64_t, char, sub, -)
+F (int, short, sub, -)
+F (int64_t, short, sub, -)

Reply via email to