On Mon, May 21, 2018 at 4:53 PM, Uros Bizjak <ubiz...@gmail.com> wrote: > Hello! > > Attached patch implements scalar float->unsigned int truncations with AVX512F. > > 2018-05-21 Uros Bizjak <ubiz...@gmail.com> > > * config/i386/i386.md (fixuns_trunc<mode>di2): New insn pattern. > (fixuns_trunc<mode>si2_avx512f): Ditto. > (*fixuns_trunc<mode>si2_avx512f_zext): Ditto. > (fixuns_trunc<mode>si2): Also enable for AVX512F and TARGET_SSE_MATH. > Emit fixuns_trunc<mode>si2_avx512f for AVX512F targets. > > testsuite/ChangeLog: > > 2018-05-21 Uros Bizjak <ubiz...@gmail.com> > > * gcc.target/i386/cvt-2.c: New test. > > Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. > > Unfortunately, I have to means to test the patch on AVX512 target, so > to avoid some hidden issue, I'd like to ask someone to test it on live > target.
Ops, ssemodesuffix handling was missing in the insn mnemonic. Fixed in the attached v-2 patch. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 260441) +++ config/i386/i386.md (working copy) @@ -5017,6 +5017,18 @@ } }) +;; Unsigned conversion to DImode + +(define_insn "fixuns_trunc<mode>di2" + [(set (match_operand:DI 0 "register_operand" "=r") + (unsigned_fix:DI + (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] + "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH" + "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "evex") + (set_attr "mode" "DI")]) + ;; Unsigned conversion to SImode. (define_expand "fixuns_trunc<mode>si2" @@ -5027,7 +5039,7 @@ (use (match_dup 2)) (clobber (match_scratch:<ssevecmode> 3)) (clobber (match_scratch:<ssevecmode> 4))])] - "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" + "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH" { machine_mode mode = <MODE>mode; machine_mode vecmode = <ssevecmode>mode; @@ -5034,6 +5046,12 @@ REAL_VALUE_TYPE TWO31r; rtx two31; + if (TARGET_AVX512F) + { + emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1])); + DONE; + } + if (optimize_insn_for_size_p ()) FAIL; @@ -5043,6 +5061,27 @@ operands[2] = force_reg (vecmode, two31); }) +(define_insn "fixuns_trunc<mode>si2_avx512f" + [(set (match_operand:SI 0 "register_operand" "=r") + (unsigned_fix:SI + (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] + "TARGET_AVX512F && TARGET_SSE_MATH" + "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "evex") + (set_attr "mode" "SI")]) + +(define_insn "*fixuns_trunc<mode>si2_avx512f_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (unsigned_fix:SI + (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))] + "TARGET_64BIT && TARGET_AVX512F" + "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "evex") + (set_attr "mode" "SI")]) + (define_insn_and_split "*fixuns_trunc<mode>_1" [(set (match_operand:SI 0 "register_operand" "=&x,&x") (unsigned_fix:SI Index: testsuite/gcc.target/i386/cvt-2.c =================================================================== --- testsuite/gcc.target/i386/cvt-2.c (nonexistent) +++ testsuite/gcc.target/i386/cvt-2.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512f -mfpmath=sse" } */ + +unsigned int f2ui (float x) { return x; } +unsigned int d2ui (double x) { return x; } + +#ifdef __x86_64__ +unsigned long f2ul (float x) { return x; } +unsigned long d2ul (double x) { return x; } +#endif + +/* { dg-final { scan-assembler-times "vcvttss2usi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "vcvttsd2usi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "vcvttss2usi" 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "vcvttsd2usi" 2 { target { ! ia32 } } } } */