i386: Fix up V2SFmode vcond* with -mxop [PR100581]

ix86_expand_sse_movcc has special TARGET_XOP handling and the recent
addition of support of v*cond* patterns for V2SFmode results in
ICEs because the expected pattern doesn't exist.  We can handle it
using 128-bit vpcmov (if we ignore the upper 64 bits like we ignore in
other TARGET_MMX_WITH_SSE support).

2021-05-13  Uroš Bizjak  <ubizjak@gmail.com>

gcc/
	PR target/100581
	* config/i386/i386-expand.c (ix86_expand_sse_movcc): Force mode
	sizes < 16 to a register when constructing vpcmov pattern.
	* config/i386/mmx.md (*xop_pcmov_<mode>): Use MMXMODE124 mode.

gcc/testsuite/

	PR target/100581
	* g++.target/i386/pr100581.C: New test.
This commit is contained in:
Uros Bizjak 2021-05-13 11:09:53 +02:00
parent 23eb66d1d4
commit f1693741cb
3 changed files with 16 additions and 6 deletions

View file

@ -3661,7 +3661,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
{
op_true = force_reg (mode, op_true);
if (!nonimmediate_operand (op_false, mode))
if (GET_MODE_SIZE (mode) < 16
|| !nonimmediate_operand (op_false, mode))
op_false = force_reg (mode, op_false);
emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cmp,

View file

@ -1816,11 +1816,11 @@
;; XOP parallel XMM conditional moves
(define_insn "*xop_pcmov_<mode>"
[(set (match_operand:MMXMODEI 0 "register_operand" "=x")
(if_then_else:MMXMODEI
(match_operand:MMXMODEI 3 "register_operand" "x")
(match_operand:MMXMODEI 1 "register_operand" "x")
(match_operand:MMXMODEI 2 "register_operand" "x")))]
[(set (match_operand:MMXMODE124 0 "register_operand" "=x")
(if_then_else:MMXMODE124
(match_operand:MMXMODE124 3 "register_operand" "x")
(match_operand:MMXMODE124 1 "register_operand" "x")
(match_operand:MMXMODE124 2 "register_operand" "x")))]
"TARGET_XOP && TARGET_MMX_WITH_SSE"
"vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sse4arg")])

View file

@ -0,0 +1,9 @@
/* PR target/100581 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -mxop" } */
typedef float __attribute__((__vector_size__(8))) v64f32;
v64f32 af, bf, ff_a, ff_b;
v64f32 f() { return ff_a > ff_b ? af : bf; }