Fix vec_cmp comparison mode

vec_cmps assign the result of a vector comparison to a mask.
The optab was called with the destination having mode mask_mode
but with the source (the comparison) having mode VOIDmode,
which led to invalid rtl if the source operand was used directly.

gcc/
2016-11-15  Richard Sandiford  <richard.sandiford@arm.com>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

	* optabs.c (vector_compare_rtx): Add a cmp_mode parameter
	and use it in the final call to gen_rtx_fmt_ee.
	(expand_vec_cond_expr): Update accordingly.
	(expand_vec_cmp_expr): Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r242489
This commit is contained in:
Richard Sandiford 2016-11-16 13:09:12 +00:00 committed by Richard Sandiford
parent 41c7cac56c
commit 45a9968b37
2 changed files with 21 additions and 9 deletions

View File

@ -1,3 +1,12 @@
2016-11-16 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* optabs.c (vector_compare_rtx): Add a cmp_mode parameter
and use it in the final call to gen_rtx_fmt_ee.
(expand_vec_cond_expr): Update accordingly.
(expand_vec_cmp_expr): Likewise.
2016-11-16 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>

View File

@ -5283,14 +5283,15 @@ get_rtx_code (enum tree_code tcode, bool unsignedp)
return code;
}
/* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
unsigned operators. OPNO holds an index of the first comparison
operand in insn with code ICODE. Do not generate compare instruction. */
/* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
select signed or unsigned operators. OPNO holds the index of the
first comparison operand for insn ICODE. Do not generate the
compare instruction itself. */
static rtx
vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
bool unsignedp, enum insn_code icode,
unsigned int opno)
vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
tree t_op0, tree t_op1, bool unsignedp,
enum insn_code icode, unsigned int opno)
{
struct expand_operand ops[2];
rtx rtx_op0, rtx_op1;
@ -5318,7 +5319,7 @@ vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
create_input_operand (&ops[1], rtx_op1, m1);
if (!maybe_legitimize_operands (icode, opno, 2, ops))
gcc_unreachable ();
return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
}
/* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
@ -5644,7 +5645,8 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
return 0;
}
comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode, 4);
comparison = vector_compare_rtx (VOIDmode, tcode, op0a, op0b, unsignedp,
icode, 4);
rtx_op1 = expand_normal (op1);
rtx_op2 = expand_normal (op2);
@ -5688,7 +5690,8 @@ expand_vec_cmp_expr (tree type, tree exp, rtx target)
return 0;
}
comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode, 2);
comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
unsignedp, icode, 2);
create_output_operand (&ops[0], target, mask_mode);
create_fixed_operand (&ops[1], comparison);
create_fixed_operand (&ops[2], XEXP (comparison, 0));