... and fix gcc.target/i386/avx512f-kmovw-1.c scan-asm failure. 2016-11-29 Uros Bizjak <ubiz...@gmail.com>
* config/i386/sse.md (UNSPEC_MASKOP): Move from i386.md. (mshift): Ditto. (SWI1248_AVX512BWDQ): Ditto. (SWI1248_AVX512BW): Ditto. (k<any_logic:code><mode>): Ditto. (kandn<mode>): Ditto. (kxnor<mode>): Ditto. (knot<mode>): Ditto. (*k<any_lshift:code><mode>): Ditto. (kortestzhi, kortestchi): Ditto. (kunpckhi, kunpcksi, kunpckdi): Ditto. testsuite/ChangeLog: 2016-11-29 Uros Bizjak <ubiz...@gmail.com> * gcc.target/i386/avx512f-kmovw-1.c (avx512f_test): Force value through k register. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 242963) +++ config/i386/i386.md (working copy) @@ -186,9 +186,6 @@ UNSPEC_PDEP UNSPEC_PEXT - ;; For AVX512F support - UNSPEC_KMASKOP - UNSPEC_BNDMK UNSPEC_BNDMK_ADDR UNSPEC_BNDSTX @@ -921,9 +918,6 @@ (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) -;; Mask variant left right mnemonics -(define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")]) - ;; Mapping of rotate operators (define_code_iterator any_rotate [rotate rotatert]) @@ -966,15 +960,6 @@ ;; All integer modes. (define_mode_iterator SWI1248x [QI HI SI DI]) -;; All integer modes with AVX512BW/DQ. -(define_mode_iterator SWI1248_AVX512BWDQ - [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")]) - -;; All integer modes with AVX512BW, where HImode operation -;; can be used instead of QImode. -(define_mode_iterator SWI1248_AVX512BW - [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")]) - ;; All integer modes without QImode. (define_mode_iterator SWI248x [HI SI DI]) @@ -2489,11 +2474,6 @@ ] (const_string "SI")))]) -(define_expand "kmovw" - [(set (match_operand:HI 0 "nonimmediate_operand") - (match_operand:HI 1 "nonimmediate_operand"))] - "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))") - (define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m") (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))] @@ -8061,28 +8041,6 @@ operands[3] = gen_lowpart (QImode, operands[3]); }) -(define_insn "k<code><mode>" - [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") - (any_logic:SWI1248_AVX512BW - (match_operand:SWI1248_AVX512BW 1 "register_operand" "k") - (match_operand:SWI1248_AVX512BW 2 "register_operand" "k"))) - (unspec [(const_int 0)] UNSPEC_KMASKOP)] - "TARGET_AVX512F" -{ - if (get_attr_mode (insn) == MODE_HI) - return "k<logic>w\t{%2, %1, %0|%0, %1, %2}"; - else - return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; -} - [(set_attr "type" "msklog") - (set_attr "prefix" "vex") - (set (attr "mode") - (cond [(and (match_test "<MODE>mode == QImode") - (not (match_test "TARGET_AVX512DQ"))) - (const_string "HI") - ] - (const_string "<MODE>")))]) - ;; %%% This used to optimize known byte-wide and operations to memory, ;; and sometimes to QImode registers. If this is considered useful, ;; it should be done with splitters. @@ -8576,29 +8534,6 @@ operands[2] = gen_lowpart (QImode, operands[2]); }) -(define_insn "kandn<mode>" - [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") - (and:SWI1248_AVX512BW - (not:SWI1248_AVX512BW - (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")) - (match_operand:SWI1248_AVX512BW 2 "register_operand" "k"))) - (unspec [(const_int 0)] UNSPEC_KMASKOP)] - "TARGET_AVX512F" -{ - if (get_attr_mode (insn) == MODE_HI) - return "kandnw\t{%2, %1, %0|%0, %1, %2}"; - else - return "kandn<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; -} - [(set_attr "type" "msklog") - (set_attr "prefix" "vex") - (set (attr "mode") - (cond [(and (match_test "<MODE>mode == QImode") - (not (match_test "TARGET_AVX512DQ"))) - (const_string "HI") - ] - (const_string "<MODE>")))]) - (define_insn_and_split "*andndi3_doubleword" [(set (match_operand:DI 0 "register_operand" "=r") (and:DI @@ -8987,92 +8922,6 @@ (set_attr "type" "alu") (set_attr "modrm" "1") (set_attr "mode" "QI")]) - -(define_insn "kxnor<mode>" - [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") - (not:SWI1248_AVX512BW - (xor:SWI1248_AVX512BW - (match_operand:SWI1248_AVX512BW 1 "register_operand" "k") - (match_operand:SWI1248_AVX512BW 2 "register_operand" "k")))) - (unspec [(const_int 0)] UNSPEC_KMASKOP)] - "TARGET_AVX512F" -{ - if (get_attr_mode (insn) == MODE_HI) - return "kxnorw\t{%2, %1, %0|%0, %1, %2}"; - else - return "kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; -} - [(set_attr "type" "msklog") - (set_attr "prefix" "vex") - (set (attr "mode") - (cond [(and (match_test "<MODE>mode == QImode") - (not (match_test "TARGET_AVX512DQ"))) - (const_string "HI") - ] - (const_string "<MODE>")))]) - -;;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 - (ior:HI - (match_operand:HI 0 "register_operand" "k") - (match_operand:HI 1 "register_operand" "k")) - (const_int 0)))] - "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)" - "kortestw\t{%1, %0|%0, %1}" - [(set_attr "mode" "HI") - (set_attr "type" "msklog") - (set_attr "prefix" "vex")]) - -(define_insn "kortestchi" - [(set (reg:CCC FLAGS_REG) - (compare:CCC - (ior:HI - (match_operand:HI 0 "register_operand" "k") - (match_operand:HI 1 "register_operand" "k")) - (const_int -1)))] - "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)" - "kortestw\t{%1, %0|%0, %1}" - [(set_attr "mode" "HI") - (set_attr "type" "msklog") - (set_attr "prefix" "vex")]) - -(define_insn "kunpckhi" - [(set (match_operand:HI 0 "register_operand" "=k") - (ior:HI - (ashift:HI - (zero_extend:HI (match_operand:QI 1 "register_operand" "k")) - (const_int 8)) - (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))] - "TARGET_AVX512F" - "kunpckbw\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "mode" "HI") - (set_attr "type" "msklog") - (set_attr "prefix" "vex")]) - -(define_insn "kunpcksi" - [(set (match_operand:SI 0 "register_operand" "=k") - (ior:SI - (ashift:SI - (zero_extend:SI (match_operand:HI 1 "register_operand" "k")) - (const_int 16)) - (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))] - "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 - (zero_extend:DI (match_operand:SI 1 "register_operand" "k")) - (const_int 32)) - (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))] - "TARGET_AVX512BW" - "kunpckdq\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "mode" "DI")]) ;; Negation instructions @@ -9463,27 +9312,6 @@ ;; One complement instructions -(define_insn "knot<mode>" - [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") - (not:SWI1248_AVX512BW - (match_operand:SWI1248_AVX512BW 1 "register_operand" "k"))) - (unspec [(const_int 0)] UNSPEC_KMASKOP)] - "TARGET_AVX512F" -{ - if (get_attr_mode (insn) == MODE_HI) - return "knotw\t{%1, %0|%0, %1}"; - else - return "knot<mskmodesuffix>\t{%1, %0|%0, %1}"; -} - [(set_attr "type" "msklog") - (set_attr "prefix" "vex") - (set (attr "mode") - (cond [(and (match_test "<MODE>mode == QImode") - (not (match_test "TARGET_AVX512DQ"))) - (const_string "HI") - ] - (const_string "<MODE>")))]) - (define_expand "one_cmpl<mode>2" [(set (match_operand:SWIM 0 "nonimmediate_operand") (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))] @@ -9600,18 +9428,6 @@ ;; shift pair, instead using moves and sign extension for counts greater ;; than 31. -(define_insn "*k<code><mode>" - [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k") - (any_lshift:SWI1248_AVX512BWDQ - (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k") - (match_operand:QI 2 "immediate_operand" "n"))) - (unspec [(const_int 0)] UNSPEC_KMASKOP)] - "TARGET_AVX512F" - "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "type" "msklog") - (set_attr "prefix" "vex") - (set_attr "mode" "<MODE>")]) - (define_expand "ashl<mode>3" [(set (match_operand:SDWIM 0 "<shift_operand>") (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>") Index: config/i386/sse.md =================================================================== --- config/i386/sse.md (revision 242963) +++ config/i386/sse.md (working copy) @@ -106,6 +106,9 @@ UNSPEC_MASKED_EQ UNSPEC_MASKED_GT + ;; Mask operations + UNSPEC_MASKOP + ;; For embed. rounding feature UNSPEC_EMBEDDED_ROUNDING @@ -1290,6 +1293,195 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; +;; Mask operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; All integer modes with AVX512BW/DQ. +(define_mode_iterator SWI1248_AVX512BWDQ + [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")]) + +;; All integer modes with AVX512BW, where HImode operation +;; can be used instead of QImode. +(define_mode_iterator SWI1248_AVX512BW + [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")]) + +;; Mask variant shift mnemonics +(define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")]) + +(define_expand "kmovw" + [(set (match_operand:HI 0 "nonimmediate_operand") + (match_operand:HI 1 "nonimmediate_operand"))] + "TARGET_AVX512F + && !(MEM_P (operands[0]) && MEM_P (operands[1]))") + +(define_insn "k<code><mode>" + [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") + (any_logic:SWI1248_AVX512BW + (match_operand:SWI1248_AVX512BW 1 "register_operand" "k") + (match_operand:SWI1248_AVX512BW 2 "register_operand" "k"))) + (unspec [(const_int 0)] UNSPEC_MASKOP)] + "TARGET_AVX512F" +{ + if (get_attr_mode (insn) == MODE_HI) + return "k<logic>w\t{%2, %1, %0|%0, %1, %2}"; + else + return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; +} + [(set_attr "type" "msklog") + (set_attr "prefix" "vex") + (set (attr "mode") + (cond [(and (match_test "<MODE>mode == QImode") + (not (match_test "TARGET_AVX512DQ"))) + (const_string "HI") + ] + (const_string "<MODE>")))]) + +(define_insn "kandn<mode>" + [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") + (and:SWI1248_AVX512BW + (not:SWI1248_AVX512BW + (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")) + (match_operand:SWI1248_AVX512BW 2 "register_operand" "k"))) + (unspec [(const_int 0)] UNSPEC_MASKOP)] + "TARGET_AVX512F" +{ + if (get_attr_mode (insn) == MODE_HI) + return "kandnw\t{%2, %1, %0|%0, %1, %2}"; + else + return "kandn<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; +} + [(set_attr "type" "msklog") + (set_attr "prefix" "vex") + (set (attr "mode") + (cond [(and (match_test "<MODE>mode == QImode") + (not (match_test "TARGET_AVX512DQ"))) + (const_string "HI") + ] + (const_string "<MODE>")))]) + +(define_insn "kxnor<mode>" + [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") + (not:SWI1248_AVX512BW + (xor:SWI1248_AVX512BW + (match_operand:SWI1248_AVX512BW 1 "register_operand" "k") + (match_operand:SWI1248_AVX512BW 2 "register_operand" "k")))) + (unspec [(const_int 0)] UNSPEC_MASKOP)] + "TARGET_AVX512F" +{ + if (get_attr_mode (insn) == MODE_HI) + return "kxnorw\t{%2, %1, %0|%0, %1, %2}"; + else + return "kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; +} + [(set_attr "type" "msklog") + (set_attr "prefix" "vex") + (set (attr "mode") + (cond [(and (match_test "<MODE>mode == QImode") + (not (match_test "TARGET_AVX512DQ"))) + (const_string "HI") + ] + (const_string "<MODE>")))]) + +(define_insn "knot<mode>" + [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k") + (not:SWI1248_AVX512BW + (match_operand:SWI1248_AVX512BW 1 "register_operand" "k"))) + (unspec [(const_int 0)] UNSPEC_MASKOP)] + "TARGET_AVX512F" +{ + if (get_attr_mode (insn) == MODE_HI) + return "knotw\t{%1, %0|%0, %1}"; + else + return "knot<mskmodesuffix>\t{%1, %0|%0, %1}"; +} + [(set_attr "type" "msklog") + (set_attr "prefix" "vex") + (set (attr "mode") + (cond [(and (match_test "<MODE>mode == QImode") + (not (match_test "TARGET_AVX512DQ"))) + (const_string "HI") + ] + (const_string "<MODE>")))]) + +(define_insn "*k<code><mode>" + [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k") + (any_lshift:SWI1248_AVX512BWDQ + (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k") + (match_operand:QI 2 "immediate_operand" "n"))) + (unspec [(const_int 0)] UNSPEC_MASKOP)] + "TARGET_AVX512F" + "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "msklog") + (set_attr "prefix" "vex") + (set_attr "mode" "<MODE>")]) + +;;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 + (ior:HI + (match_operand:HI 0 "register_operand" "k") + (match_operand:HI 1 "register_operand" "k")) + (const_int 0)))] + "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)" + "kortestw\t{%1, %0|%0, %1}" + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "kortestchi" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (ior:HI + (match_operand:HI 0 "register_operand" "k") + (match_operand:HI 1 "register_operand" "k")) + (const_int -1)))] + "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)" + "kortestw\t{%1, %0|%0, %1}" + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "kunpckhi" + [(set (match_operand:HI 0 "register_operand" "=k") + (ior:HI + (ashift:HI + (zero_extend:HI (match_operand:QI 1 "register_operand" "k")) + (const_int 8)) + (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))] + "TARGET_AVX512F" + "kunpckbw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "kunpcksi" + [(set (match_operand:SI 0 "register_operand" "=k") + (ior:SI + (ashift:SI + (zero_extend:SI (match_operand:HI 1 "register_operand" "k")) + (const_int 16)) + (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))] + "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 + (zero_extend:DI (match_operand:SI 1 "register_operand" "k")) + (const_int 32)) + (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))] + "TARGET_AVX512BW" + "kunpckdq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "mode" "DI")]) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; Parallel floating point arithmetic ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Index: testsuite/gcc.target/i386/avx512f-kmovw-1.c =================================================================== --- testsuite/gcc.target/i386/avx512f-kmovw-1.c (revision 242963) +++ testsuite/gcc.target/i386/avx512f-kmovw-1.c (working copy) @@ -8,5 +8,8 @@ void avx512f_test () { - k1 = _mm512_kmov (11); + __mmask16 k = _mm512_kmov (11); + + asm volatile ("" : "+k" (k)); + k1 = k; }