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 ndd constraints, 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): Likewise. (*subv<mode>4_overflow_2): Likewise. (*addsi3_carry_zext_0r): Likewise. (@sub<mode>3_carry): Add NDD alternatives and adjust output templates. (*subsi3_carry_zext): Likewise. (subborrow<mode>): Likewise. (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 | 159 ++++++++++++-------- gcc/testsuite/gcc.target/i386/apx-ndd-sbb.c | 6 + 2 files changed, 106 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 1aa8469d666..c3dcfaf52e1 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -7641,12 +7641,13 @@ (define_expand "sub<mode>3" ix86_can_use_ndd_p (MINUS)); 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, + ix86_can_use_ndd_p (MINUS))" "#" "&& reload_completed" [(parallel [(set (reg:CC FLAGS_REG) @@ -7670,16 +7671,18 @@ (define_insn_and_split "*sub<dwi>3_doubleword" ix86_can_use_ndd_p (MINUS)); 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, + ix86_can_use_ndd_p (MINUS))" "#" "&& reload_completed" [(parallel [(set (reg:CC FLAGS_REG) @@ -7693,7 +7696,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>i,r,r") @@ -7929,14 +7933,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, + ix86_can_use_ndd_p (MINUS))" "#" "&& reload_completed" [(parallel [(set (reg:CC FLAGS_REG) @@ -7964,22 +7969,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, + ix86_can_use_ndd_p (MINUS)) && CONST_SCALAR_INT_P (operands[2]) && rtx_equal_p (operands[2], operands[3])" "#" @@ -8017,7 +8024,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) @@ -8025,11 +8033,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 @@ -8037,15 +8045,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, + ix86_can_use_ndd_p (MINUS))" + "@ + 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" @@ -8054,28 +8068,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, + ix86_can_use_ndd_p (MINUS)) && 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)") @@ -8360,15 +8378,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 "register_operand" "0,r")))) (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")]) @@ -8610,17 +8631,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, + ix86_can_use_ndd_p (MINUS))" + "@ + 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>")]) @@ -8707,18 +8734,22 @@ (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") (zero_extend:DI (minus:SI (minus:SI - (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 1 "register_operand" "0,r") (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")))) (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, + ix86_can_use_ndd_p (MINUS))" + "@ + sbb{l}\t{%2, %k0|%k0, %2} + sbb{l}\t{%2, %1, %k0|%k0, %1, %2}" + [(set_attr "isa" "*,apx_ndd") + (set_attr "type" "alu") (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) @@ -8803,21 +8834,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, + ix86_can_use_ndd_p (MINUS))" + "@ + 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>")]) @@ -8978,7 +9015,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, + ix86_can_use_ndd_p (MINUS))") (define_expand "uaddc<mode>5" [(match_operand:SWI48 0 "register_operand") @@ -9404,7 +9442,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, + ix86_can_use_ndd_p (MINUS)) && ix86_pre_reload_split ()" "#" "&& 1" @@ -9429,7 +9468,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, + ix86_can_use_ndd_p (MINUS)) && ix86_pre_reload_split ()" "#" "&& 1" @@ -9458,7 +9498,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, + ix86_can_use_ndd_p (MINUS)) && 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