From 26b57b93b389a08b1328b577526e886f43a76476 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 13 Dec 2018 09:08:22 +0100 Subject: [PATCH] re PR target/88465 (AVX512: optimize loading of constant values to kN registers) PR target/88465 * config/i386/i386.md (*movdi_internal, *movsi_internal, *movhi_internal, *movqi_internal): Add alternative(s) to load 0 or -1 into k registers using kxor or kxnoq instructions. * gcc.target/i386/avx512f-pr88465.c: New test. * gcc.target/i386/avx512dq-pr88465.c: New test. From-SVN: r267078 --- gcc/ChangeLog | 5 ++ gcc/config/i386/i386.md | 68 +++++++++++++++---- gcc/testsuite/ChangeLog | 4 ++ .../gcc.target/i386/avx512dq-pr88465.c | 14 ++++ .../gcc.target/i386/avx512f-pr88465.c | 21 ++++++ 5 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512dq-pr88465.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-pr88465.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 55c291b8e59..a88ec326953 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-12-13 Jakub Jelinek + PR target/88465 + * config/i386/i386.md (*movdi_internal, *movsi_internal, + *movhi_internal, *movqi_internal): Add alternative(s) to load + 0 or -1 into k registers using kxor or kxnoq instructions. + PR target/88461 * config/i386/sse.md (VI1248_AVX512VLBW, AVX512ZEXTMASK): New mode iterators. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a220346a068..5e46bdcdd37 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2056,9 +2056,9 @@ (define_insn "*movdi_internal" [(set (match_operand:DI 0 "nonimmediate_operand" - "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m") + "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k") (match_operand:DI 1 "general_operand" - "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k"))] + "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2066,6 +2066,13 @@ case TYPE_MSKMOV: return "kmovq\t{%1, %0|%0, %1}"; + case TYPE_MSKLOG: + if (operands[1] == const0_rtx) + return "kxorq\t%0, %0, %0"; + else if (operands[1] == constm1_rtx) + return "kxnorq\t%0, %0, %0"; + gcc_unreachable (); + case TYPE_MULTI: return "#"; @@ -2159,6 +2166,8 @@ (const_string "ssecvt") (eq_attr "alternative" "23,24,25,26") (const_string "mskmov") + (eq_attr "alternative" "27") + (const_string "msklog") (and (match_operand 0 "register_operand") (match_operand 1 "pic_32bit_operand")) (const_string "lea") @@ -2296,9 +2305,9 @@ (define_insn "*movsi_internal" [(set (match_operand:SI 0 "nonimmediate_operand" - "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm") + "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k") (match_operand:SI 1 "general_operand" - "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k"))] + "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2309,6 +2318,13 @@ case TYPE_MSKMOV: return "kmovd\t{%1, %0|%0, %1}"; + case TYPE_MSKLOG: + if (operands[1] == const0_rtx) + return "kxord\t%0, %0, %0"; + else if (operands[1] == constm1_rtx) + return "kxnord\t%0, %0, %0"; + gcc_unreachable (); + case TYPE_SSEMOV: switch (get_attr_mode (insn)) { @@ -2375,6 +2391,8 @@ (const_string "ssemov") (eq_attr "alternative" "14,15,16") (const_string "mskmov") + (eq_attr "alternative" "17") + (const_string "msklog") (and (match_operand 0 "register_operand") (match_operand 1 "pic_32bit_operand")) (const_string "lea") @@ -2419,8 +2437,8 @@ (symbol_ref "true")))]) (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"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k") + (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2444,6 +2462,13 @@ gcc_unreachable (); } + case TYPE_MSKLOG: + if (operands[1] == const0_rtx) + return "kxorw\t%0, %0, %0"; + else if (operands[1] == constm1_rtx) + return "kxnorw\t%0, %0, %0"; + gcc_unreachable (); + default: if (get_attr_mode (insn) == MODE_SI) return "mov{l}\t{%k1, %k0|%k0, %k1}"; @@ -2454,6 +2479,8 @@ [(set (attr "type") (cond [(eq_attr "alternative" "4,5,6,7") (const_string "mskmov") + (eq_attr "alternative" "8") + (const_string "msklog") (match_test "optimize_function_for_size_p (cfun)") (const_string "imov") (and (eq_attr "alternative" "0") @@ -2469,7 +2496,7 @@ ] (const_string "imov"))) (set (attr "prefix") - (if_then_else (eq_attr "alternative" "4,5,6,7") + (if_then_else (eq_attr "alternative" "4,5,6,7,8") (const_string "vex") (const_string "orig"))) (set (attr "mode") @@ -2498,9 +2525,9 @@ (define_insn "*movqi_internal" [(set (match_operand:QI 0 "nonimmediate_operand" - "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k") + "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k") (match_operand:QI 1 "general_operand" - "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))] + "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { static char buf[128]; @@ -2538,6 +2565,21 @@ snprintf (buf, sizeof (buf), ops, suffix); return buf; + case TYPE_MSKLOG: + if (operands[1] == const0_rtx) + { + if (get_attr_mode (insn) == MODE_HI) + return "kxorw\t%0, %0, %0"; + else + return "kxorb\t%0, %0, %0"; + } + else if (operands[1] == constm1_rtx) + { + gcc_assert (TARGET_AVX512DQ); + return "kxnorb\t%0, %0, %0"; + } + gcc_unreachable (); + default: if (get_attr_mode (insn) == MODE_SI) return "mov{l}\t{%k1, %k0|%k0, %k1}"; @@ -2548,13 +2590,15 @@ [(set (attr "isa") (cond [(eq_attr "alternative" "1,2") (const_string "x64") - (eq_attr "alternative" "12,13") + (eq_attr "alternative" "12,13,15") (const_string "avx512dq") ] (const_string "*"))) (set (attr "type") (cond [(eq_attr "alternative" "9,10,11,12,13") (const_string "mskmov") + (eq_attr "alternative" "14,15") + (const_string "msklog") (and (eq_attr "alternative" "7") (not (match_operand:QI 1 "aligned_operand"))) (const_string "imovx") @@ -2572,7 +2616,7 @@ ] (const_string "imov"))) (set (attr "prefix") - (if_then_else (eq_attr "alternative" "9,10,11") + (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15") (const_string "vex") (const_string "orig"))) (set (attr "mode") @@ -2580,7 +2624,7 @@ (const_string "SI") (eq_attr "alternative" "8") (const_string "QI") - (and (eq_attr "alternative" "9,10,11") + (and (eq_attr "alternative" "9,10,11,14") (not (match_test "TARGET_AVX512DQ"))) (const_string "HI") (eq_attr "type" "imovx") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 295b160ee54..d6901c4db36 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2018-12-13 Jakub Jelinek + PR target/88465 + * gcc.target/i386/avx512f-pr88465.c: New test. + * gcc.target/i386/avx512dq-pr88465.c: New test. + PR target/88461 * gcc.target/i386/pr88461.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-pr88465.c b/gcc/testsuite/gcc.target/i386/avx512dq-pr88465.c new file mode 100644 index 00000000000..a11fd26a44e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512dq-pr88465.c @@ -0,0 +1,14 @@ +/* PR target/88465 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512dq -mno-avx512bw" } */ +/* { dg-final { scan-assembler-times "kxorb\[ \t]" 1 } } */ +/* { dg-final { scan-assembler-times "kxnorb\[ \t]" 1 } } */ + +void +foo (void) +{ + unsigned char k = 0; + __asm volatile ("" : : "k" (k)); + k = -1; + __asm volatile ("" : : "k" (k)); +} diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr88465.c b/gcc/testsuite/gcc.target/i386/avx512f-pr88465.c new file mode 100644 index 00000000000..e66ea64db02 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-pr88465.c @@ -0,0 +1,21 @@ +/* PR target/88465 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512f -mno-avx512dq -mno-avx512bw" } */ +/* { dg-final { scan-assembler-times "kxorw\[ \t]" 2 } } */ +/* { dg-final { scan-assembler-times "kxnorw\[ \t]" 1 } } */ + +void +foo (void) +{ + unsigned short int k = 0; + __asm volatile ("" : : "k" (k)); + k = -1; + __asm volatile ("" : : "k" (k)); +} + +void +bar (void) +{ + unsigned char k = 0; + __asm volatile ("" : : "k" (k)); +} -- 2.30.2