]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Optimization for APX NDD is always zero-uppered for sub/adc/sbb
authorLingling Kong <lingling.kong@intel.com>
Wed, 14 Aug 2024 08:38:46 +0000 (16:38 +0800)
committerLingling Kong <lingling.kong@intel.com>
Wed, 14 Aug 2024 09:00:27 +0000 (17:00 +0800)
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.

gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr113729-adc-sbb.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr113729.c

index 5f237275bdc8eeb7ce36ad11a97fe987296de371..e267b330b2516cde4e2ebcc43e1a16c002862802 100644 (file)
    (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
    (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
    (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
    (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
    (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
    (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 (file)
index 0000000..8d446b3
--- /dev/null
@@ -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, -, >=)
index 34518a5cdc884ea60c1ab3aff534aa44ff9164fb..b24cb0e07fe8f2a99e60231e3b6d14012a9d7a1d 100644 (file)
@@ -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, -)