From f359611b363490b48a7ce0fd021f7e47d8816eb0 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 10 Jun 2019 21:17:57 +0200 Subject: [PATCH] i386-protos.h (ix86_split_fp_absneg_operator): New prototype. * config/i386/i386-protos.h (ix86_split_fp_absneg_operator): New prototype. * config/i386/i386-expand.c (ix86_expand_fp_absneg_operator): Emit clobber also for non-sse operations. (ix86_split_fp_absneg_operator): New function. * config/i386/i386.md (SSEMODEF): New mode iterator. (ssevecmodef): New mode attribute. (tf2): Use absneg code iterator. (*tf2_1): Rename from *absnegtf3_sse. Use absneg code iterator. Add three-operand AVX alternatives. (*2_i387_1): Rename from *absnegxf2_i387. Use absneg code iterator and X87MODEF mode iterator. (absneg fp_reg non-sse splitter): Call absneg code iterator and X87MODEF mode iterator. (absneg general_reg non-sse splitter): Use absneg code iterator and X87MODEF mode iterator. Use ix86_split_fp_absneg_operator. (*2_1): Rename from *absneg2. Use absneg code iterator. Add three-operand AVX alternative. (absneg sse_reg splitter): Use absneg code iterator and SSEMODEF mode iterator. Handle AVX operands. (absneg fp_reg splitter): Use absneg code iterator and MODEF mode iterator. (absneg general_reg splitter): Merge splitters using MODEF mode iterator. Use absneg code iterator. Call ix86_split_fp_absneg_operator. (*2_i387): Rename from *2_1. Do not enable for non-sse modes before reload. (CSGNMODE): Remove. (CSGNVMODE): Ditto. (copysing3): Use SSEMODEF instead of CSGNMODE and ssevecmodef mode attribute instaed of CSGNVMODE. (copysign3_const): Ditto. (copysign3_var): Ditto. * config/i386/i386.md (*2): Rename from *absneg2. Use absneg code iterator. Simplify code using std::swap. * config/i386/predicates.md (absneg_operator): Remove. From-SVN: r272123 --- gcc/ChangeLog | 39 ++++++ gcc/config/i386/i386-expand.c | 116 ++++++++++++++++-- gcc/config/i386/i386-protos.h | 2 + gcc/config/i386/i386.md | 269 +++++++++++++++++------------------------- gcc/config/i386/predicates.md | 3 - gcc/config/i386/sse.md | 34 ++---- 6 files changed, 262 insertions(+), 201 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9327d97..a479644 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,42 @@ +2019-06-10 Uroš Bizjak + + * config/i386/i386-protos.h (ix86_split_fp_absneg_operator): + New prototype. + * config/i386/i386-expand.c (ix86_expand_fp_absneg_operator): + Emit clobber also for non-sse operations. + (ix86_split_fp_absneg_operator): New function. + * config/i386/i386.md (SSEMODEF): New mode iterator. + (ssevecmodef): New mode attribute. + (tf2): Use absneg code iterator. + (*tf2_1): Rename from *absnegtf3_sse. Use absneg code iterator. + Add three-operand AVX alternatives. + (*2_i387_1): Rename from *absnegxf2_i387. + Use absneg code iterator and X87MODEF mode iterator. + (absneg fp_reg non-sse splitter): Call absneg code iterator + and X87MODEF mode iterator. + (absneg general_reg non-sse splitter): Use absneg code iterator + and X87MODEF mode iterator. Use ix86_split_fp_absneg_operator. + (*2_1): Rename from *absneg2. Use absneg + code iterator. Add three-operand AVX alternative. + (absneg sse_reg splitter): Use absneg code iterator + and SSEMODEF mode iterator. Handle AVX operands. + (absneg fp_reg splitter): Use absneg code iterator + and MODEF mode iterator. + (absneg general_reg splitter): Merge splitters using MODEF mode + iterator. Use absneg code iterator. Call + ix86_split_fp_absneg_operator. + (*2_i387): Rename from *2_1. + Do not enable for non-sse modes before reload. + (CSGNMODE): Remove. + (CSGNVMODE): Ditto. + (copysing3): Use SSEMODEF instead of CSGNMODE and + ssevecmodef mode attribute instaed of CSGNVMODE. + (copysign3_const): Ditto. + (copysign3_var): Ditto. + * config/i386/i386.md (*2): Rename from *absneg2. + Use absneg code iterator. Simplify code using std::swap. + * config/i386/predicates.md (absneg_operator): Remove. + 2019-06-10 Martin Sebor * gimple-fold.c (get_range_strlen): Update comment that didn't diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 97914536..0585c7d 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -1704,10 +1704,11 @@ void ix86_expand_fp_absneg_operator (enum rtx_code code, machine_mode mode, rtx operands[]) { - rtx mask, set, dst, src; + rtx set, dst, src; bool use_sse = false; bool vector_mode = VECTOR_MODE_P (mode); machine_mode vmode = mode; + rtvec par; if (vector_mode) use_sse = true; @@ -1722,24 +1723,19 @@ ix86_expand_fp_absneg_operator (enum rtx_code code, machine_mode mode, vmode = V2DFmode; } - /* NEG and ABS performed with SSE use bitwise mask operations. - Create the appropriate mask now. */ - if (use_sse) - mask = ix86_build_signbit_mask (vmode, vector_mode, code == ABS); - else - mask = NULL_RTX; - dst = operands[0]; src = operands[1]; set = gen_rtx_fmt_e (code, mode, src); set = gen_rtx_SET (dst, set); - if (mask) + if (use_sse) { - rtx use, clob; - rtvec par; + rtx mask, use, clob; + /* NEG and ABS performed with SSE use bitwise mask operations. + Create the appropriate mask now. */ + mask = ix86_build_signbit_mask (vmode, vector_mode, code == ABS); use = gen_rtx_USE (VOIDmode, mask); if (vector_mode) par = gen_rtvec (2, set, use); @@ -1748,10 +1744,104 @@ ix86_expand_fp_absneg_operator (enum rtx_code code, machine_mode mode, clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); par = gen_rtvec (3, set, use, clob); } - emit_insn (gen_rtx_PARALLEL (VOIDmode, par)); } else - emit_insn (set); + { + rtx clob; + + /* Changing of sign for FP values is doable using integer unit too. */ + clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); + par = gen_rtvec (2, set, clob); + } + + emit_insn (gen_rtx_PARALLEL (VOIDmode, par)); +} + +/* Deconstruct a floating point ABS or NEG operation + with integer registers into integer operations. */ + +void +ix86_split_fp_absneg_operator (enum rtx_code code, machine_mode mode, + rtx operands[]) +{ + enum rtx_code absneg_op; + rtx dst, set; + + gcc_assert (operands_match_p (operands[0], operands[1])); + + switch (mode) + { + case E_SFmode: + dst = gen_lowpart (SImode, operands[0]); + + if (code == ABS) + { + set = gen_int_mode (0x7fffffff, SImode); + absneg_op = AND; + } + else + { + set = gen_int_mode (0x80000000, SImode); + absneg_op = XOR; + } + set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set); + break; + + case E_DFmode: + if (TARGET_64BIT) + { + dst = gen_lowpart (DImode, operands[0]); + dst = gen_rtx_ZERO_EXTRACT (DImode, dst, const1_rtx, GEN_INT (63)); + + if (code == ABS) + set = const0_rtx; + else + set = gen_rtx_NOT (DImode, dst); + } + else + { + dst = gen_highpart (SImode, operands[0]); + + if (code == ABS) + { + set = gen_int_mode (0x7fffffff, SImode); + absneg_op = AND; + } + else + { + set = gen_int_mode (0x80000000, SImode); + absneg_op = XOR; + } + set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set); + } + break; + + case E_XFmode: + dst = gen_rtx_REG (SImode, + REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2)); + if (code == ABS) + { + set = GEN_INT (0x7fff); + absneg_op = AND; + } + else + { + set = GEN_INT (0x8000); + absneg_op = XOR; + } + set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set); + break; + + default: + gcc_unreachable (); + } + + set = gen_rtx_SET (dst, set); + + rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); + rtvec par = gen_rtvec (2, set, clob); + + emit_insn (gen_rtx_PARALLEL (VOIDmode, par)); } /* Expand a copysign operation. Special case operand 0 being a constant. */ diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index b9de1e7..80b6ee7 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -121,6 +121,8 @@ extern rtx ix86_expand_adjust_ufix_to_sfix_si (rtx, rtx *); extern enum ix86_fpcmp_strategy ix86_fp_comparison_strategy (enum rtx_code); extern void ix86_expand_fp_absneg_operator (enum rtx_code, machine_mode, rtx[]); +extern void ix86_split_fp_absneg_operator (enum rtx_code, machine_mode, + rtx[]); extern void ix86_expand_copysign (rtx []); extern void ix86_split_copysign_const (rtx []); extern void ix86_split_copysign_var (rtx []); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 977fbc6..9f8194b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1162,6 +1162,10 @@ ;; All x87 floating point modes (define_mode_iterator X87MODEF [SF DF XF]) +;; All SSE floating point modes +(define_mode_iterator SSEMODEF [SF DF TF]) +(define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")]) + ;; SSE instruction suffix for various modes (define_mode_attr ssemodesuffix [(SF "ss") (DF "sd") @@ -9488,7 +9492,21 @@ [(set_attr "type" "negnot") (set_attr "mode" "")]) -;; Changing of sign for FP values is doable using integer unit too. +(define_expand "tf2" + [(set (match_operand:TF 0 "register_operand") + (absneg:TF (match_operand:TF 1 "register_operand")))] + "TARGET_SSE" + "ix86_expand_fp_absneg_operator (, TFmode, operands); DONE;") + +(define_insn "*tf2_1" + [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv") + (absneg:TF + (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))) + (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv")) + (clobber (reg:CC FLAGS_REG))] + "TARGET_SSE" + "#" + [(set_attr "isa" "noavx,noavx,avx,avx")]) (define_expand "2" [(set (match_operand:X87MODEF 0 "register_operand") @@ -9496,203 +9514,128 @@ "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" "ix86_expand_fp_absneg_operator (, mode, operands); DONE;") -(define_insn "*absneg2" - [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r") - (match_operator:MODEF 3 "absneg_operator" - [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")])) - (use (match_operand: 2 "nonimmediate_operand" "Yvm,0,X,X")) +;; Changing of sign for FP values is doable using integer unit too. +(define_insn "*2_i387_1" + [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") + (absneg:X87MODEF + (match_operand:X87MODEF 1 "register_operand" "0,0"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:X87MODEF 0 "fp_register_operand") + (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))]) + +(define_split + [(set (match_operand:X87MODEF 0 "general_reg_operand") + (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_80387 && reload_completed" + [(const_int 0)] + "ix86_split_fp_absneg_operator (, mode, operands); DONE;") + +(define_insn "*2_1" + [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r") + (absneg:MODEF + (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0"))) + (use (match_operand: 2 "vector_operand" "xBm,0,Yvm,X,X")) (clobber (reg:CC FLAGS_REG))] "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" "#" - [(set (attr "enabled") + [(set_attr "isa" "noavx,noavx,avx,*,*") + (set (attr "enabled") (if_then_else (match_test ("SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")) (if_then_else - (eq_attr "alternative" "2") + (eq_attr "alternative" "3,4") (symbol_ref "TARGET_MIX_SSE_I387") - (symbol_ref "true")) + (const_string "*")) (if_then_else - (eq_attr "alternative" "2,3") + (eq_attr "alternative" "3,4") (symbol_ref "true") (symbol_ref "false"))))]) -(define_insn "*absnegxf2_i387" - [(set (match_operand:XF 0 "register_operand" "=f,!r") - (match_operator:XF 3 "absneg_operator" - [(match_operand:XF 1 "register_operand" "0,0")])) - (use (match_operand 2)) - (clobber (reg:CC FLAGS_REG))] - "TARGET_80387" - "#") - -(define_expand "tf2" - [(set (match_operand:TF 0 "register_operand") - (absneg:TF (match_operand:TF 1 "register_operand")))] - "TARGET_SSE" - "ix86_expand_fp_absneg_operator (, TFmode, operands); DONE;") - -(define_insn "*absnegtf2_sse" - [(set (match_operand:TF 0 "register_operand" "=Yv,Yv") - (match_operator:TF 3 "absneg_operator" - [(match_operand:TF 1 "register_operand" "0,Yv")])) - (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_SSE" - "#") - -;; Splitters for fp abs and neg. - (define_split - [(set (match_operand 0 "fp_register_operand") - (match_operator 1 "absneg_operator" [(match_dup 0)])) - (use (match_operand 2)) + [(set (match_operand:SSEMODEF 0 "sse_reg_operand") + (absneg:SSEMODEF + (match_operand:SSEMODEF 1 "vector_operand"))) + (use (match_operand: 2 "vector_operand")) (clobber (reg:CC FLAGS_REG))] - "reload_completed" - [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) - -(define_split - [(set (match_operand 0 "sse_reg_operand") - (match_operator 3 "absneg_operator" - [(match_operand 1 "register_operand")])) - (use (match_operand 2 "nonimmediate_operand")) - (clobber (reg:CC FLAGS_REG))] - "reload_completed" + "((SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) + || (TARGET_SSE && (mode == TFmode))) + && reload_completed" [(set (match_dup 0) (match_dup 3))] { - machine_mode mode = GET_MODE (operands[0]); - machine_mode vmode = GET_MODE (operands[2]); - rtx tmp; + machine_mode mode = mode; + machine_mode vmode = mode; + enum rtx_code absneg_op = == ABS ? AND : XOR; operands[0] = lowpart_subreg (vmode, operands[0], mode); operands[1] = lowpart_subreg (vmode, operands[1], mode); - if (operands_match_p (operands[0], operands[2])) - std::swap (operands[1], operands[2]); - if (GET_CODE (operands[3]) == ABS) - tmp = gen_rtx_AND (vmode, operands[1], operands[2]); - else - tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); - operands[3] = tmp; -}) -(define_split - [(set (match_operand:SF 0 "general_reg_operand") - (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) - (use (match_operand:V4SF 2)) - (clobber (reg:CC FLAGS_REG))] - "reload_completed" - [(parallel [(set (match_dup 0) (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] -{ - rtx tmp; - operands[0] = gen_lowpart (SImode, operands[0]); - if (GET_CODE (operands[1]) == ABS) + if (TARGET_AVX) { - tmp = gen_int_mode (0x7fffffff, SImode); - tmp = gen_rtx_AND (SImode, operands[0], tmp); + if (MEM_P (operands[1])) + std::swap (operands[1], operands[2]); } else - { - tmp = gen_int_mode (0x80000000, SImode); - tmp = gen_rtx_XOR (SImode, operands[0], tmp); - } - operands[1] = tmp; + { + if (operands_match_p (operands[0], operands[2])) + std::swap (operands[1], operands[2]); + } + + operands[3] + = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]); }) (define_split - [(set (match_operand:DF 0 "general_reg_operand") - (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) + [(set (match_operand:MODEF 0 "fp_register_operand") + (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand"))) (use (match_operand 2)) (clobber (reg:CC FLAGS_REG))] - "reload_completed" - [(parallel [(set (match_dup 0) (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] -{ - rtx tmp; - if (TARGET_64BIT) - { - tmp = gen_lowpart (DImode, operands[0]); - tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); - operands[0] = tmp; - - if (GET_CODE (operands[1]) == ABS) - tmp = const0_rtx; - else - tmp = gen_rtx_NOT (DImode, tmp); - } - else - { - operands[0] = gen_highpart (SImode, operands[0]); - if (GET_CODE (operands[1]) == ABS) - { - tmp = gen_int_mode (0x7fffffff, SImode); - tmp = gen_rtx_AND (SImode, operands[0], tmp); - } - else - { - tmp = gen_int_mode (0x80000000, SImode); - tmp = gen_rtx_XOR (SImode, operands[0], tmp); - } - } - operands[1] = tmp; -}) + "TARGET_80387 && reload_completed" + [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))]) (define_split - [(set (match_operand:XF 0 "general_reg_operand") - (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) + [(set (match_operand:MODEF 0 "general_reg_operand") + (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand"))) (use (match_operand 2)) (clobber (reg:CC FLAGS_REG))] - "reload_completed" - [(parallel [(set (match_dup 0) (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] -{ - rtx tmp; - operands[0] = gen_rtx_REG (SImode, - REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2)); - if (GET_CODE (operands[1]) == ABS) - { - tmp = GEN_INT (0x7fff); - tmp = gen_rtx_AND (SImode, operands[0], tmp); - } - else - { - tmp = GEN_INT (0x8000); - tmp = gen_rtx_XOR (SImode, operands[0], tmp); - } - operands[1] = tmp; -}) + "TARGET_80387 && reload_completed" + [(const_int 0)] + "ix86_split_fp_absneg_operator (, mode, operands); DONE;") ;; Conditionalize these after reload. If they match before reload, we ;; lose the clobber and ability to use integer instructions. -(define_insn "*2_1" +(define_insn "*2_i387" [(set (match_operand:X87MODEF 0 "register_operand" "=f") (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] - "TARGET_80387 - && (reload_completed - || !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))" + "TARGET_80387 && reload_completed" "" [(set_attr "type" "fsgn") (set_attr "mode" "")]) ;; Copysign instructions -(define_mode_iterator CSGNMODE [SF DF TF]) -(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) - (define_expand "copysign3" - [(match_operand:CSGNMODE 0 "register_operand") - (match_operand:CSGNMODE 1 "nonmemory_operand") - (match_operand:CSGNMODE 2 "register_operand")] + [(match_operand:SSEMODEF 0 "register_operand") + (match_operand:SSEMODEF 1 "nonmemory_operand") + (match_operand:SSEMODEF 2 "register_operand")] "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) || (TARGET_SSE && (mode == TFmode))" "ix86_expand_copysign (operands); DONE;") (define_insn_and_split "copysign3_const" - [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv") - (unspec:CSGNMODE - [(match_operand: 1 "nonimm_or_0_operand" "YvmC") - (match_operand:CSGNMODE 2 "register_operand" "0") - (match_operand: 3 "nonimmediate_operand" "Yvm")] + [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv") + (unspec:SSEMODEF + [(match_operand: 1 "nonimm_or_0_operand" "YvmC") + (match_operand:SSEMODEF 2 "register_operand" "0") + (match_operand: 3 "nonimmediate_operand" "Yvm")] UNSPEC_COPYSIGN))] "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) || (TARGET_SSE && (mode == TFmode))" @@ -9702,29 +9645,29 @@ "ix86_split_copysign_const (operands); DONE;") (define_insn "copysign3_var" - [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") - (unspec:CSGNMODE - [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv") - (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv") - (match_operand: 4 + [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") + (unspec:SSEMODEF + [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv") + (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv") + (match_operand: 4 "nonimmediate_operand" "X,Yvm,Yvm,0,0") - (match_operand: 5 + (match_operand: 5 "nonimmediate_operand" "0,Yvm,1,Yvm,1")] UNSPEC_COPYSIGN)) - (clobber (match_scratch: 1 "=Yv,Yv,Yv,Yv,Yv"))] + (clobber (match_scratch: 1 "=Yv,Yv,Yv,Yv,Yv"))] "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) || (TARGET_SSE && (mode == TFmode))" "#") (define_split - [(set (match_operand:CSGNMODE 0 "register_operand") - (unspec:CSGNMODE - [(match_operand:CSGNMODE 2 "register_operand") - (match_operand:CSGNMODE 3 "register_operand") - (match_operand: 4) - (match_operand: 5)] + [(set (match_operand:SSEMODEF 0 "register_operand") + (unspec:SSEMODEF + [(match_operand:SSEMODEF 2 "register_operand") + (match_operand:SSEMODEF 3 "register_operand") + (match_operand: 4) + (match_operand: 5)] UNSPEC_COPYSIGN)) - (clobber (match_scratch: 1))] + (clobber (match_scratch: 1))] "((SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) || (TARGET_SSE && (mode == TFmode))) && reload_completed" diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 29867fb..5e8f671 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1404,9 +1404,6 @@ (define_predicate "compare_operator" (match_code "compare")) -(define_predicate "absneg_operator" - (match_code "abs,neg")) - ;; Return true if OP is a memory operand, aligned to ;; less than its natural alignment. (define_predicate "misaligned_operand" diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 0997f43..d7d5425 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1720,41 +1720,31 @@ "TARGET_SSE" "ix86_expand_fp_absneg_operator (, mode, operands); DONE;") -(define_insn_and_split "*absneg2" +(define_insn_and_split "*2" [(set (match_operand:VF 0 "register_operand" "=x,x,v,v") - (match_operator:VF 3 "absneg_operator" - [(match_operand:VF 1 "vector_operand" "0, xBm,v, m")])) + (absneg:VF + (match_operand:VF 1 "vector_operand" "0, xBm,v, m"))) (use (match_operand:VF 2 "vector_operand" "xBm,0, vm,v"))] "TARGET_SSE" "#" "&& reload_completed" - [(const_int 0)] + [(set (match_dup 0) (match_dup 3))] { - enum rtx_code absneg_op; - rtx op1, op2; - rtx t; + enum rtx_code absneg_op = == ABS ? AND : XOR; if (TARGET_AVX) { if (MEM_P (operands[1])) - op1 = operands[2], op2 = operands[1]; - else - op1 = operands[1], op2 = operands[2]; + std::swap (operands[1], operands[2]); } else - { - op1 = operands[0]; - if (rtx_equal_p (operands[0], operands[1])) - op2 = operands[2]; - else - op2 = operands[1]; - } + { + if (operands_match_p (operands[0], operands[2])) + std::swap (operands[1], operands[2]); + } - absneg_op = GET_CODE (operands[3]) == NEG ? XOR : AND; - t = gen_rtx_fmt_ee (absneg_op, mode, op1, op2); - t = gen_rtx_SET (operands[0], t); - emit_insn (t); - DONE; + operands[3] + = gen_rtx_fmt_ee (absneg_op, mode, operands[1], operands[2]); } [(set_attr "isa" "noavx,noavx,avx,avx")]) -- 2.7.4