Commit 4b3f4964 by Uros Bizjak Committed by Uros Bizjak

i386.md (*floatuns<SWI48:mode><MODEF:mode>2_avx512): New insn pattern.

	* config/i386/i386.md (*floatuns<SWI48:mode><MODEF:mode>2_avx512):
	New insn pattern.
	(floatunssi<mode>2): Also enable for AVX512F and TARGET_SSE_MATH.
	Rewrite expander pattern.  Emit gen_floatunssi<mode>2_i387_with_xmm
	for non-SSE modes.
	(floatunsdisf2): Rewrite expander pattern.  Hanlde TARGET_AVX512F.
	(floatunsdidf2): Ditto.

	* 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:

	* gcc.target/i386/cvt-2.c: New test.

	* gcc.target/i386/cvt-3.c: New test.

From-SVN: r260614
parent 3f131545
2018-05-23 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*floatuns<SWI48:mode><MODEF:mode>2_avx512):
New insn pattern.
(floatunssi<mode>2): Also enable for AVX512F and TARGET_SSE_MATH.
Rewrite expander pattern. Emit gen_floatunssi<mode>2_i387_with_xmm
for non-SSE modes.
(floatunsdisf2): Rewrite expander pattern. Hanlde TARGET_AVX512F.
(floatunsdidf2): Ditto.
2018-05-23 Uros Bizjak <ubizjak@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.
2018-05-23 Alexander Monakov <amonakov@ispras.ru> 2018-05-23 Alexander Monakov <amonakov@ispras.ru>
PR rtl-optimization/79985 PR rtl-optimization/79985
......
...@@ -5017,6 +5017,18 @@ ...@@ -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. ;; Unsigned conversion to SImode.
(define_expand "fixuns_trunc<mode>si2" (define_expand "fixuns_trunc<mode>si2"
...@@ -5027,13 +5039,19 @@ ...@@ -5027,13 +5039,19 @@
(use (match_dup 2)) (use (match_dup 2))
(clobber (match_scratch:<ssevecmode> 3)) (clobber (match_scratch:<ssevecmode> 3))
(clobber (match_scratch:<ssevecmode> 4))])] (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 mode = <MODE>mode;
machine_mode vecmode = <ssevecmode>mode; machine_mode vecmode = <ssevecmode>mode;
REAL_VALUE_TYPE TWO31r; REAL_VALUE_TYPE TWO31r;
rtx two31; rtx two31;
if (TARGET_AVX512F)
{
emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
DONE;
}
if (optimize_insn_for_size_p ()) if (optimize_insn_for_size_p ())
FAIL; FAIL;
...@@ -5043,6 +5061,27 @@ ...@@ -5043,6 +5061,27 @@
operands[2] = force_reg (vecmode, two31); 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" (define_insn_and_split "*fixuns_trunc<mode>_1"
[(set (match_operand:SI 0 "register_operand" "=&x,&x") [(set (match_operand:SI 0 "register_operand" "=&x,&x")
(unsigned_fix:SI (unsigned_fix:SI
...@@ -5615,16 +5654,26 @@ ...@@ -5615,16 +5654,26 @@
DONE; DONE;
}) })
(define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
[(set (match_operand:MODEF 0 "register_operand" "=v")
(unsigned_float:MODEF
(match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
"TARGET_AVX512F && TARGET_SSE_MATH"
"vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "prefix" "evex")
(set_attr "mode" "<MODEF:MODE>")])
;; Avoid store forwarding (partial memory) stall penalty by extending ;; Avoid store forwarding (partial memory) stall penalty by extending
;; SImode value to DImode through XMM register instead of pushing two ;; SImode value to DImode through XMM register instead of pushing two
;; SImode values to stack. Also note that fild loads from memory only. ;; SImode values to stack. Also note that fild loads from memory only.
(define_insn_and_split "*floatunssi<mode>2_i387_with_xmm" (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
[(set (match_operand:X87MODEF 0 "register_operand" "=f") [(set (match_operand:X87MODEF 0 "register_operand" "=f")
(unsigned_float:X87MODEF (unsigned_float:X87MODEF
(match_operand:SI 1 "nonimmediate_operand" "rm"))) (match_operand:SI 1 "nonimmediate_operand" "rm")))
(clobber (match_scratch:DI 3 "=x")) (clobber (match_operand:DI 2 "memory_operand" "=m"))
(clobber (match_operand:DI 2 "memory_operand" "=m"))] (clobber (match_scratch:DI 3 "=x"))]
"!TARGET_64BIT "!TARGET_64BIT
&& TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
&& TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC" && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
...@@ -5639,43 +5688,59 @@ ...@@ -5639,43 +5688,59 @@
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_expand "floatunssi<mode>2" (define_expand "floatunssi<mode>2"
[(parallel [(set (match_operand:X87MODEF 0 "register_operand")
[(set (match_operand:X87MODEF 0 "register_operand") (unsigned_float:X87MODEF
(unsigned_float:X87MODEF (match_operand:SI 1 "nonimmediate_operand")))]
(match_operand:SI 1 "nonimmediate_operand"))) "(!TARGET_64BIT
(clobber (match_scratch:DI 3)) && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
(clobber (match_dup 2))])] && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
"!TARGET_64BIT || ((!TARGET_64BIT || TARGET_AVX512F)
&& ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
&& TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
|| (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
{ {
if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
{
emit_insn (gen_floatunssi<mode>2_i387_with_xmm
(operands[0], operands[1],
assign_386_stack_local (DImode, SLOT_TEMP)));
DONE;
}
if (!TARGET_AVX512F)
{ {
ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
DONE; DONE;
} }
else
operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
}) })
(define_expand "floatunsdisf2" (define_expand "floatunsdisf2"
[(use (match_operand:SF 0 "register_operand")) [(set (match_operand:SF 0 "register_operand")
(use (match_operand:DI 1 "nonimmediate_operand"))] (unsigned_float:SF
(match_operand:DI 1 "nonimmediate_operand")))]
"TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH" "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
"x86_emit_floatuns (operands); DONE;") {
if (!TARGET_AVX512F)
{
x86_emit_floatuns (operands);
DONE;
}
})
(define_expand "floatunsdidf2" (define_expand "floatunsdidf2"
[(use (match_operand:DF 0 "register_operand")) [(set (match_operand:DF 0 "register_operand")
(use (match_operand:DI 1 "nonimmediate_operand"))] (unsigned_float:DF
"(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) (match_operand:DI 1 "nonimmediate_operand")))]
"(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
&& TARGET_SSE2 && TARGET_SSE_MATH" && TARGET_SSE2 && TARGET_SSE_MATH"
{ {
if (TARGET_64BIT) if (!TARGET_64BIT)
x86_emit_floatuns (operands); {
else ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); DONE;
DONE; }
if (!TARGET_AVX512F)
{
x86_emit_floatuns (operands);
DONE;
}
}) })
;; Load effective address instructions ;; Load effective address instructions
......
2018-05-23 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/cvt-3.c: New test.
2018-05-23 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/cvt-2.c: New test.
2018-05-23 Alexander Monakov <amonakov@ispras.ru> 2018-05-23 Alexander Monakov <amonakov@ispras.ru>
* gcc.dg/pr79985.c: New testcase. * gcc.dg/pr79985.c: New testcase.
......
/* { 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 } } } } */
/* { dg-do compile } */
/* { dg-options "-O2 -mavx512f -mfpmath=sse" } */
float ui2f (unsigned int x) { return x; }
double ui2d (unsigned int x) { return x; }
#ifdef __x86_64__
float ul2f (unsigned long x) { return x; }
double ul2d (unsigned long x) { return x; }
#endif
/* { dg-final { scan-assembler-times "vcvtusi2ss" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "vcvtusi2sd" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "vcvtusi2ss" 2 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "vcvtusi2sd" 2 { target { ! ia32 } } } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment