From: Kong Lingling <lingling.k...@intel.com> Similar to *add<dwi>3_doubleword, operands[1] may not equal to operands[0] so extra move is required.
gcc/ChangeLog: * config/i386/i386.md (*sub<dwi>3_doubleword): Add new alternative for NDD, and emit move when operands[0] not equal to operands[1]. (*sub<dwi>3_doubleword_zext): Likewise. (*subv<dwi>4_doubleword): Likewise. (*subv<dwi>4_doubleword_1): Likewise. (*subv<mode>4_overflow_1): Add NDD alternatives and adjust output templates. (*subv<mode>4_overflow_2): Likewise. (@sub<mode>3_carry): Likewise. (*addsi3_carry_zext_0r): Likewise, and use nonimmediate_operand for operands[1] to accept memory input for NDD alternative. (*subsi3_carry_zext): Likewise. (subborrow<mode>): Parse TARGET_APX_NDD to ix86_binary_operator_ok. (subborrow<mode>_0): Likewise. (*sub<mode>3_eq): Likewise. (*sub<mode>3_ne): Likewise. (*sub<mode>3_eq_1): Likewise. gcc/testsuite/ChangeLog: * gcc.target/i386/apx-ndd-sbb.c: New test. --- gcc/config/i386/i386.md | 160 ++++++++++++-------- gcc/testsuite/gcc.target/i386/apx-ndd-sbb.c | 6 + 2 files changed, 107 insertions(+), 59 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-sbb.c diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ea5377a0b38..e2705ada31a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -7776,12 +7776,13 @@ (define_expand "sub<mode>3" TARGET_APX_NDD); DONE;") (define_insn_and_split "*sub<dwi>3_doubleword" - [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") + [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,r") (minus:<DWI> - (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") - (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))) + (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r") + (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD)" "#" "&& reload_completed" [(parallel [(set (reg:CC FLAGS_REG) @@ -7805,16 +7806,18 @@ (define_insn_and_split "*sub<dwi>3_doubleword" TARGET_APX_NDD); DONE; } -}) +} +[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) (define_insn_and_split "*sub<dwi>3_doubleword_zext" - [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") + [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,r,r") (minus:<DWI> - (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") + (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o") (zero_extend:<DWI> - (match_operand:DWIH 2 "nonimmediate_operand" "rm,r")))) + (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r")))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)" + "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, + TARGET_APX_NDD)" "#" "&& reload_completed" [(parallel [(set (reg:CC FLAGS_REG) @@ -7828,7 +7831,8 @@ (define_insn_and_split "*sub<dwi>3_doubleword_zext" (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) (const_int 0))) (clobber (reg:CC FLAGS_REG))])] - "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);") + "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);" +[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) (define_insn "*sub<mode>_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r") @@ -8162,14 +8166,15 @@ (define_insn_and_split "*subv<dwi>4_doubleword" (eq:CCO (minus:<QPWI> (sign_extend:<QPWI> - (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")) + (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r")) (sign_extend:<QPWI> - (match_operand:<DWI> 2 "nonimmediate_operand" "r,o"))) + (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o"))) (sign_extend:<QPWI> (minus:<DWI> (match_dup 1) (match_dup 2))))) - (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") + (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,r") (minus:<DWI> (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD)" "#" "&& reload_completed" [(parallel [(set (reg:CC FLAGS_REG) @@ -8197,22 +8202,24 @@ (define_insn_and_split "*subv<dwi>4_doubleword" (match_dup 5)))])] { split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); -}) +} +[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) (define_insn_and_split "*subv<dwi>4_doubleword_1" [(set (reg:CCO FLAGS_REG) (eq:CCO (minus:<QPWI> (sign_extend:<QPWI> - (match_operand:<DWI> 1 "nonimmediate_operand" "0")) + (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")) (match_operand:<QPWI> 3 "const_scalar_int_operand")) (sign_extend:<QPWI> (minus:<DWI> (match_dup 1) - (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>"))))) - (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") + (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>"))))) + (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") (minus:<DWI> (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD) && CONST_SCALAR_INT_P (operands[2]) && rtx_equal_p (operands[2], operands[3])" "#" @@ -8250,7 +8257,8 @@ (define_insn_and_split "*subv<dwi>4_doubleword_1" operands[5])); DONE; } -}) +} +[(set_attr "isa" "*,apx_ndd")]) (define_insn "*subv<mode>4_overflow_1" [(set (reg:CCO FLAGS_REG) @@ -8258,11 +8266,11 @@ (define_insn "*subv<mode>4_overflow_1" (minus:<DWI> (minus:<DWI> (sign_extend:<DWI> - (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")) (match_operator:<DWI> 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)])) (sign_extend:<DWI> - (match_operand:SWI 2 "<general_sext_operand>" "rWe,m"))) + (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m"))) (sign_extend:<DWI> (minus:SWI (minus:SWI @@ -8270,15 +8278,21 @@ (define_insn "*subv<mode>4_overflow_1" (match_operator:SWI 5 "ix86_carry_flag_operator" [(match_dup 3) (const_int 0)])) (match_dup 2))))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r") + (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r") (minus:SWI (minus:SWI (match_dup 1) (match_op_dup 5 [(match_dup 3) (const_int 0)])) (match_dup 2)))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" - "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD)" + "@ + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>")]) (define_insn "*subv<mode>4_overflow_2" @@ -8287,28 +8301,32 @@ (define_insn "*subv<mode>4_overflow_2" (minus:<DWI> (minus:<DWI> (sign_extend:<DWI> - (match_operand:SWI 1 "nonimmediate_operand" "%0")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,rm")) (match_operator:<DWI> 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)])) - (match_operand:<DWI> 6 "const_int_operand" "n")) + (match_operand:<DWI> 6 "const_int_operand" "n,n")) (sign_extend:<DWI> (minus:SWI (minus:SWI (match_dup 1) (match_operator:SWI 5 "ix86_carry_flag_operator" [(match_dup 3) (const_int 0)])) - (match_operand:SWI 2 "x86_64_immediate_operand" "e"))))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=rm") + (match_operand:SWI 2 "x86_64_immediate_operand" "e,e"))))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r") (minus:SWI (minus:SWI (match_dup 1) (match_op_dup 5 [(match_dup 3) (const_int 0)])) (match_dup 2)))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD) && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == INTVAL (operands[6])" - "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "@ + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>") (set (attr "length_immediate") (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") @@ -8593,15 +8611,18 @@ (define_insn "*addsi3_carry_zext_0" (set_attr "mode" "SI")]) (define_insn "*addsi3_carry_zext_0r" - [(set (match_operand:DI 0 "register_operand" "=r") + [(set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator" [(reg FLAGS_REG) (const_int 0)]) - (match_operand:SI 1 "register_operand" "0")))) + (match_operand:SI 1 "nonimmediate_operand" "0,rm")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "sbb{l}\t{$-1, %k0|%k0, -1}" - [(set_attr "type" "alu") + "@ + sbb{l}\t{$-1, %k0|%k0, -1} + sbb{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")]) @@ -8841,17 +8862,23 @@ (define_insn "*addcarry<mode>_1" (const_string "4")))]) (define_insn "@sub<mode>3_carry" - [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r") (minus:SWI (minus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "0,0") + (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r") (match_operator:SWI 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)])) - (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))) + (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" - "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD)" + "@ + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) @@ -8938,18 +8965,23 @@ (define_insn "*sub<mode>3_carry_0r" (set_attr "mode" "<MODE>")]) (define_insn "*subsi3_carry_zext" - [(set (match_operand:DI 0 "register_operand" "=r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (minus:SI (minus:SI - (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 1 "nonimmediate_operand" "0,r,rm") (match_operator:SI 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)])) - (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" - "sbb{l}\t{%2, %k0|%k0, %2}" - [(set_attr "type" "alu") + "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands, + TARGET_APX_NDD)" + "@ + sbb{l}\t{%2, %k0|%k0, %2} + sbb{l}\t{%2, %1, %k0|%k0, %1, %2} + sbb{l}\t{%2, %1, %k0|%k0, %1, %2}" + [(set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) @@ -9034,21 +9066,27 @@ (define_insn "subborrow<mode>" [(set (reg:CCC FLAGS_REG) (compare:CCC (zero_extend:<DWI> - (match_operand:SWI48 1 "nonimmediate_operand" "0,0")) + (match_operand:SWI48 1 "nonimmediate_operand" "0,0,r,rm")) (plus:<DWI> (match_operator:<DWI> 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)]) (zero_extend:<DWI> - (match_operand:SWI48 2 "nonimmediate_operand" "r,rm"))))) - (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") + (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,rm,r"))))) + (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") (minus:SWI48 (minus:SWI48 (match_dup 1) (match_operator:SWI48 5 "ix86_carry_flag_operator" [(match_dup 3) (const_int 0)])) (match_dup 2)))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" - "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD)" + "@ + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %0|%0, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) @@ -9209,7 +9247,8 @@ (define_expand "subborrow<mode>_0" (match_operand:SWI48 2 "<general_operand>"))) (set (match_operand:SWI48 0 "register_operand") (minus:SWI48 (match_dup 1) (match_dup 2)))])] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)") + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD)") (define_expand "uaddc<mode>5" [(match_operand:SWI48 0 "register_operand") @@ -9634,7 +9673,8 @@ (define_insn_and_split "*sub<mode>3_eq" (const_int 0))) (match_operand:SWI 2 "<general_operand>"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) + "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD) && ix86_pre_reload_split ()" "#" "&& 1" @@ -9659,7 +9699,8 @@ (define_insn_and_split "*sub<mode>3_ne" "CONST_INT_P (operands[2]) && (<MODE>mode != DImode || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000)) - && ix86_binary_operator_ok (MINUS, <MODE>mode, operands) + && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD) && ix86_pre_reload_split ()" "#" "&& 1" @@ -9688,7 +9729,8 @@ (define_insn_and_split "*sub<mode>3_eq_1" "CONST_INT_P (operands[2]) && (<MODE>mode != DImode || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000)) - && ix86_binary_operator_ok (MINUS, <MODE>mode, operands) + && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, + TARGET_APX_NDD) && ix86_pre_reload_split ()" "#" "&& 1" diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-sbb.c b/gcc/testsuite/gcc.target/i386/apx-ndd-sbb.c new file mode 100644 index 00000000000..662e3c607d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-sbb.c @@ -0,0 +1,6 @@ +/* { dg-do compile { target { int128 && { ! ia32 } } } } */ +/* { dg-options "-mapxf -O2" } */ + +#include "pr91681-2.c" + +/* { dg-final { scan-assembler-times "sbbq\[^\n\r]*0, %rdi, %rdx" 1 } } */ -- 2.31.1