summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2012-10-12 11:20:00 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2012-10-12 09:20:00 +0000
commite6ed43b0bcaf9f639b351568e4b6f24812420983 (patch)
tree73742261d3406e6d52ca7c2f1160f753923c5a10 /gcc
parentbf90c4cd8e91c2e3d6dbb25af5ca31fba535fde1 (diff)
downloadgcc-e6ed43b0bcaf9f639b351568e4b6f24812420983.tar.gz
optabs.c (vector_compare_rtx): Change prototype.
2012-10-12 Marc Glisse <marc.glisse@inria.fr> * optabs.c (vector_compare_rtx): Change prototype. (expand_vec_cond_expr): Handle VEC_COND_EXPR whose first operand is not a comparison. * gimplify.c (gimplify_expr): Handle VEC_COND_EXPR. From-SVN: r192393
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gimplify.c1
-rw-r--r--gcc/optabs.c37
3 files changed, 31 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c44c5ab7646..0784c8a7825 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ * optabs.c (vector_compare_rtx): Change prototype.
+ (expand_vec_cond_expr): Handle VEC_COND_EXPR whose first operand
+ is not a comparison.
+ * gimplify.c (gimplify_expr): Handle VEC_COND_EXPR.
+
2012-10-12 Richard Biener <rguenther@suse.de>
PR tree-optimization/54894
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 979715ab95e..b83a6346eca 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7683,6 +7683,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
}
case FMA_EXPR:
+ case VEC_COND_EXPR:
case VEC_PERM_EXPR:
/* Classified as tcc_expression. */
goto expr_3;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 8a6c6a330b4..a63394d1312 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6388,20 +6388,14 @@ get_rtx_code (enum tree_code tcode, bool unsignedp)
unsigned operators. Do not generate compare instruction. */
static rtx
-vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
+vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
+ bool unsignedp, enum insn_code icode)
{
struct expand_operand ops[2];
- enum rtx_code rcode;
- tree t_op0, t_op1;
rtx rtx_op0, rtx_op1;
+ enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
- /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
- ensures that condition is a relational operation. */
- gcc_assert (COMPARISON_CLASS_P (cond));
-
- rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
- t_op0 = TREE_OPERAND (cond, 0);
- t_op1 = TREE_OPERAND (cond, 1);
+ gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
/* Expand operands. */
rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
@@ -6684,11 +6678,26 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
enum machine_mode mode = TYPE_MODE (vec_cond_type);
enum machine_mode cmp_op_mode;
bool unsignedp;
+ tree op0a, op0b;
+ enum tree_code tcode;
- gcc_assert (COMPARISON_CLASS_P (op0));
+ if (COMPARISON_CLASS_P (op0))
+ {
+ op0a = TREE_OPERAND (op0, 0);
+ op0b = TREE_OPERAND (op0, 1);
+ tcode = TREE_CODE (op0);
+ }
+ else
+ {
+ /* Fake op0 < 0. */
+ gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0)));
+ op0a = op0;
+ op0b = build_zero_cst (TREE_TYPE (op0));
+ tcode = LT_EXPR;
+ }
+ unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
+ cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
- unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)));
- cmp_op_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0)));
gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
&& GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
@@ -6697,7 +6706,7 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
if (icode == CODE_FOR_nothing)
return 0;
- comparison = vector_compare_rtx (op0, unsignedp, icode);
+ comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
rtx_op1 = expand_normal (op1);
rtx_op2 = expand_normal (op2);