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 test for sub. * gcc.target/i386/pr113729-adc-sbb.c: New test. --- 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(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr113729-adc-sbb.c diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b1cf0868efe..bb90a67b16d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -8052,6 +8052,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 @@ -8771,6 +8799,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 @@ -8792,6 +8858,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 @@ -8809,6 +8903,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 @@ -9161,6 +9283,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 @@ -9183,32 +9345,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 00000000000..e8d4d25f5cb --- /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 74f65506ad4..755b3981536 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, -) -- 2.31.1