From e2131cc73294a4a1bcbeed77a01d0dd9bb5f0862 Mon Sep 17 00:00:00 2001 From: Alexander Ivchenko Date: Thu, 14 Aug 2014 13:25:36 +0000 Subject: [PATCH] i386.md (define_attr "isa"): Add avx512bw,noavx512bw. gcc/ * config/i386/i386.md (define_attr "isa"): Add avx512bw,noavx512bw. (define_attr "enabled"): Ditto. (define_split): Add 32/64-bit mask logic. (define_insn "*kqi"): New. (define_insn "*khi"): New. (define_insn "*anddi_1"): Add mask version. (define_insn "*andsi_1"): Ditto. (define_insn "*_1"): Ditto. (define_insn "*hi_1"): Ditto. (define_insn "kxnor"): New. (define_insn "kunpcksi"): New. (define_insn "kunpckdi"): New. (define_insn "*one_cmpl2_1"): Add mask version. (define_insn "*one_cmplhi2_1"): Ditto. Co-Authored-By: Andrey Turetskiy Co-Authored-By: Anna Tikhonova Co-Authored-By: Ilya Tocar Co-Authored-By: Ilya Verbin Co-Authored-By: Kirill Yukhin Co-Authored-By: Maxim Kuznetsov Co-Authored-By: Michael Zolotukhin From-SVN: r213964 --- gcc/ChangeLog | 25 +++++ gcc/config/i386/i386.md | 211 +++++++++++++++++++++++++++++++--------- 2 files changed, 188 insertions(+), 48 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3a1d0846d4..ef7290705cb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2014-08-14 Alexander Ivchenko + Maxim Kuznetsov + Anna Tikhonova + Ilya Tocar + Andrey Turetskiy + Ilya Verbin + Kirill Yukhin + Michael Zolotukhin + + * config/i386/i386.md + (define_attr "isa"): Add avx512bw,noavx512bw. + (define_attr "enabled"): Ditto. + (define_split): Add 32/64-bit mask logic. + (define_insn "*kqi"): New. + (define_insn "*khi"): New. + (define_insn "*anddi_1"): Add mask version. + (define_insn "*andsi_1"): Ditto. + (define_insn "*_1"): Ditto. + (define_insn "*hi_1"): Ditto. + (define_insn "kxnor"): New. + (define_insn "kunpcksi"): New. + (define_insn "kunpckdi"): New. + (define_insn "*one_cmpl2_1"): Add mask version. + (define_insn "*one_cmplhi2_1"): Ditto. + 2014-08-14 Alexander Ivchenko Maxim Kuznetsov Anna Tikhonova diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4867e7e4ed0..a72c2065044 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -740,7 +740,8 @@ ;; Used to control the "enabled" attribute on a per-instruction basis. (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64, sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx, - avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f" + avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f, + fma_avx512f,avx512bw,noavx512bw" (const_string "base")) (define_attr "enabled" "" @@ -771,6 +772,8 @@ (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F") (eq_attr "isa" "fma_avx512f") (symbol_ref "TARGET_FMA || TARGET_AVX512F") + (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW") + (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW") ] (const_int 1))) @@ -7510,21 +7513,46 @@ }) (define_split - [(set (match_operand:SWI12 0 "mask_reg_operand") - (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand") - (match_operand:SWI12 2 "mask_reg_operand"))) + [(set (match_operand:SWI1248x 0 "mask_reg_operand") + (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand") + (match_operand:SWI1248x 2 "mask_reg_operand"))) (clobber (reg:CC FLAGS_REG))] "TARGET_AVX512F && reload_completed" [(set (match_dup 0) - (any_logic:SWI12 (match_dup 1) - (match_dup 2)))]) + (any_logic:SWI1248x (match_dup 1) + (match_dup 2)))]) -(define_insn "*k" - [(set (match_operand:SWI12 0 "mask_reg_operand" "=k") - (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "k") - (match_operand:SWI12 2 "mask_reg_operand" "k")))] +;; TODO: It seems to be possible to macroize following +;; 3 patterns. +(define_insn "*kqi" + [(set (match_operand:QI 0 "mask_reg_operand" "=k") + (any_logic:QI (match_operand:QI 1 "mask_reg_operand" "k") + (match_operand:QI 2 "mask_reg_operand" "k")))] + "TARGET_AVX512F" +{ + return TARGET_AVX512DQ ? "kb\t{%2, %1, %0|%0, %1, %2}" + : "kw\t{%2, %1, %0|%0, %1, %2}"; +} + [(set_attr "mode" "QI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "*khi" + [(set (match_operand:HI 0 "mask_reg_operand" "=k") + (any_logic:HI (match_operand:HI 1 "mask_reg_operand" "k") + (match_operand:HI 2 "mask_reg_operand" "k")))] "TARGET_AVX512F" "kw\t{%2, %1, %0|%0, %1, %2}"; + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "*k" + [(set (match_operand:SWI48x 0 "mask_reg_operand" "=k") + (any_logic:SWI48x (match_operand:SWI48x 1 "mask_reg_operand" "k") + (match_operand:SWI48x 2 "mask_reg_operand" "k")))] + "TARGET_AVX512BW" + "k\t{%2, %1, %0|%0, %1, %2}"; [(set_attr "mode" "") (set_attr "type" "msklog") (set_attr "prefix" "vex")]) @@ -7580,10 +7608,10 @@ }) (define_insn "*anddi_1" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k") (and:DI - (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") - (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) + (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k") + (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" { @@ -7592,6 +7620,9 @@ case TYPE_IMOVX: return "#"; + case TYPE_MSKLOG: + return "kandq\t{%2, %1, %0|%0, %1, %2}"; + default: gcc_assert (rtx_equal_p (operands[0], operands[1])); if (get_attr_mode (insn) == MODE_SI) @@ -7600,8 +7631,8 @@ return "and{q}\t{%2, %0|%0, %2}"; } } - [(set_attr "type" "alu,alu,alu,imovx") - (set_attr "length_immediate" "*,*,*,0") + [(set_attr "type" "alu,alu,alu,imovx,msklog") + (set_attr "length_immediate" "*,*,*,0,0") (set (attr "prefix_rex") (if_then_else (and (eq_attr "type" "imovx") @@ -7609,12 +7640,12 @@ (match_operand 1 "ext_QIreg_operand"))) (const_string "1") (const_string "*"))) - (set_attr "mode" "SI,DI,DI,SI")]) + (set_attr "mode" "SI,DI,DI,SI,DI")]) (define_insn "*andsi_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya") - (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") - (match_operand:SI 2 "x86_64_general_operand" "re,rm,L"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k") + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k") + (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, SImode, operands)" { @@ -7623,12 +7654,15 @@ case TYPE_IMOVX: return "#"; + case TYPE_MSKLOG: + return "kandd\t{%2, %1, %0|%0, %1, %2}"; + default: gcc_assert (rtx_equal_p (operands[0], operands[1])); return "and{l}\t{%2, %0|%0, %2}"; } } - [(set_attr "type" "alu,alu,imovx") + [(set_attr "type" "alu,alu,imovx,msklog") (set (attr "prefix_rex") (if_then_else (and (eq_attr "type" "imovx") @@ -7636,7 +7670,7 @@ (match_operand 1 "ext_QIreg_operand"))) (const_string "1") (const_string "*"))) - (set_attr "length_immediate" "*,*,0") + (set_attr "length_immediate" "*,*,0,0") (set_attr "mode" "SI")]) ;; See comment for addsi_1_zext why we do use nonimmediate_operand @@ -7688,11 +7722,21 @@ (match_operand:QI 2 "general_operand" "qn,qmn,rn,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, QImode, operands)" - "@ - and{b}\t{%2, %0|%0, %2} - and{b}\t{%2, %0|%0, %2} - and{l}\t{%k2, %k0|%k0, %k2} - kandw\t{%2, %1, %0|%0, %1, %2}" +{ + switch (which_alternative) + { + case 0: + case 1: + return "and{b}\t{%2, %0|%0, %2}"; + case 2: + return "and{l}\t{%k2, %k0|%k0, %k2}"; + case 3: + return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}" + : "kandw\t{%2, %1, %0|%0, %1, %2}"; + default: + gcc_unreachable (); + } +} [(set_attr "type" "alu,alu,alu,msklog") (set_attr "mode" "QI,QI,SI,HI")]) @@ -7715,10 +7759,22 @@ (match_operand:SWI12 2 "register_operand" "r,r,k"))) (clobber (reg:CC FLAGS_REG))] "TARGET_AVX512F" - "@ - andn\t{%k2, %k1, %k0|%k0, %k1, %k2} - # - kandnw\t{%2, %1, %0|%0, %1, %2}" +{ + switch (which_alternative) + { + case 0: + return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"; + case 1: + return "#"; + case 2: + if (TARGET_AVX512DQ && mode == QImode) + return "kandnb\t{%2, %1, %0|%0, %1, %2}"; + else + return "kandnw\t{%2, %1, %0|%0, %1, %2}"; + default: + gcc_unreachable (); + } +} [(set_attr "isa" "bmi,*,avx512f") (set_attr "type" "bitmanip,*,msklog") (set_attr "prefix" "*,*,vex") @@ -8082,14 +8138,17 @@ "ix86_expand_binary_operator (, mode, operands); DONE;") (define_insn "*_1" - [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm") + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k") (any_or:SWI48 - (match_operand:SWI48 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI48 2 "" ",r"))) + (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k") + (match_operand:SWI48 2 "" ",r,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (, mode, operands)" - "{}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "@ + {}\t{%2, %0|%0, %2} + {}\t{%2, %0|%0, %2} + k\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "alu,alu,msklog") (set_attr "mode" "")]) (define_insn "*hi_1" @@ -8177,19 +8236,36 @@ (match_operand:SWI12 2 "register_operand" "r,k")))) (clobber (reg:CC FLAGS_REG))] "TARGET_AVX512F" +{ + if (which_alternative == 1 && mode == QImode && TARGET_AVX512DQ) + return "kxnorb\t{%2, %1, %0|%0, %1, %2}"; + return "kxnorw\t{%2, %1, %0|%0, %1, %2}"; +} + [(set_attr "type" "*,msklog") + (set_attr "prefix" "*,vex") + (set_attr "mode" "")]) + +(define_insn "kxnor" + [(set (match_operand:SWI48x 0 "register_operand" "=r,!k") + (not:SWI48x + (xor:SWI48x + (match_operand:SWI48x 1 "register_operand" "0,k") + (match_operand:SWI48x 2 "register_operand" "r,k")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_AVX512BW" "@ # - kxnorw\t{%2, %1, %0|%0, %1, %2}" + kxnor\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "*,msklog") (set_attr "prefix" "*,vex") (set_attr "mode" "")]) (define_split - [(set (match_operand:SWI12 0 "general_reg_operand") - (not:SWI12 - (xor:SWI12 + [(set (match_operand:SWI1248x 0 "general_reg_operand") + (not:SWI1248x + (xor:SWI1248x (match_dup 0) - (match_operand:SWI12 1 "general_reg_operand")))) + (match_operand:SWI1248x 1 "general_reg_operand")))) (clobber (reg:CC FLAGS_REG))] "TARGET_AVX512F && reload_completed" [(parallel [(set (match_dup 0) @@ -8199,6 +8275,8 @@ (set (match_dup 0) (not:HI (match_dup 0)))]) +;;There are kortrest[bdq] but no intrinsics for them. +;;We probably don't need to implement them. (define_insn "kortestzhi" [(set (reg:CCZ FLAGS_REG) (compare:CCZ @@ -8238,6 +8316,28 @@ (set_attr "type" "msklog") (set_attr "prefix" "vex")]) +(define_insn "kunpcksi" + [(set (match_operand:SI 0 "register_operand" "=k") + (ior:SI + (ashift:SI + (match_operand:SI 1 "register_operand" "k") + (const_int 16)) + (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))] + "TARGET_AVX512BW" + "kunpckwd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "mode" "SI")]) + +(define_insn "kunpckdi" + [(set (match_operand:DI 0 "register_operand" "=k") + (ior:DI + (ashift:DI + (match_operand:DI 1 "register_operand" "k") + (const_int 32)) + (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))] + "TARGET_AVX512BW" + "kunpckdq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "mode" "DI")]) + ;; See comment for addsi_1_zext why we do use nonimmediate_operand ;; ??? Special case for immediate operand is missing - it is tricky. (define_insn "*si_2_zext" @@ -8837,11 +8937,15 @@ "ix86_expand_unary_operator (NOT, mode, operands); DONE;") (define_insn "*one_cmpl2_1" - [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") - (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))] + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k") + (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))] "ix86_unary_operator_ok (NOT, mode, operands)" - "not{}\t%0" - [(set_attr "type" "negnot") + "@ + not{}\t%0 + knot\t{%1, %0|%0, %1}" + [(set_attr "isa" "*,avx512bw") + (set_attr "type" "negnot,msklog") + (set_attr "prefix" "*,vex") (set_attr "mode" "")]) (define_insn "*one_cmplhi2_1" @@ -8861,10 +8965,21 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k") (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))] "ix86_unary_operator_ok (NOT, QImode, operands)" - "@ - not{b}\t%0 - not{l}\t%k0 - knotw\t{%1, %0|%0, %1}" +{ + switch (which_alternative) + { + case 0: + return "not{b}\t%0"; + case 1: + return "not{l}\t%k0"; + case 2: + if (TARGET_AVX512DQ) + return "knotb\t{%1, %0|%0, %1}"; + return "knotw\t{%1, %0|%0, %1}"; + default: + gcc_unreachable (); + } +} [(set_attr "isa" "*,*,avx512f") (set_attr "type" "negnot,negnot,msklog") (set_attr "prefix" "*,*,vex")