static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
static tree associate_trees (tree, tree, enum tree_code, tree);
static tree const_binop (enum tree_code, tree, tree, int);
-static enum tree_code invert_tree_comparison (enum tree_code, bool);
static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code);
static tree combine_comparisons (enum tree_code, enum tree_code,
comparisons, except for NE_EXPR and EQ_EXPR, so we receive a machine mode
as well: if reversing the comparison is unsafe, return ERROR_MARK. */
-static enum tree_code
+enum tree_code
invert_tree_comparison (enum tree_code code, bool honor_nans)
{
if (honor_nans && flag_trapping_math)
v2 = TREE_CHAIN (v2);
}
- return 1;
+ return v1 == v2;
}
case COMPLEX_CST:
&& (TREE_CODE (arg1) != REAL_CST
|| REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
|| (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
- return fold_build2 (PLUS_EXPR, type, arg0, negate_expr (arg1));
+ return fold_build2 (PLUS_EXPR, type,
+ fold_convert (type, arg0),
+ fold_convert (type, negate_expr (arg1)));
/* Try folding difference of addresses. */
{
if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
{
tem = build_real (type, r);
- return fold_build2 (MULT_EXPR, type, arg0, tem);
+ return fold_build2 (MULT_EXPR, type,
+ fold_convert (type, arg0), tem);
}
}
}
switch (code)
{
case GE_EXPR:
- arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- return fold_build2 (GT_EXPR, type, arg0, arg1);
+ arg1 = const_binop (MINUS_EXPR, arg1,
+ build_int_cst (TREE_TYPE (arg1), 1), 0);
+ return fold_build2 (GT_EXPR, type, arg0,
+ fold_convert (TREE_TYPE (arg0), arg1));
case LT_EXPR:
- arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- return fold_build2 (LE_EXPR, type, arg0, arg1);
+ arg1 = const_binop (MINUS_EXPR, arg1,
+ build_int_cst (TREE_TYPE (arg1), 1), 0);
+ return fold_build2 (LE_EXPR, type, arg0,
+ fold_convert (TREE_TYPE (arg0), arg1));
default:
break;
&& (arglist = TREE_OPERAND (arg0, 1))
&& TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
&& ! TREE_CHAIN (arglist))
- return fold_build2 (code, type,
- build1 (INDIRECT_REF, char_type_node,
- TREE_VALUE (arglist)),
- fold_convert (char_type_node,
- integer_zero_node));
+ {
+ tree iref = build_fold_indirect_ref (TREE_VALUE (arglist));
+ return fold_build2 (code, type, iref,
+ build_int_cst (TREE_TYPE (iref), 0));
+ }
}
/* We can fold X/C1 op C2 where C1 and C2 are integer constants
}
return NULL_TREE;
+ case BIT_FIELD_REF:
+ if (TREE_CODE (arg0) == VECTOR_CST
+ && type == TREE_TYPE (TREE_TYPE (arg0))
+ && host_integerp (arg1, 1)
+ && host_integerp (op2, 1))
+ {
+ unsigned HOST_WIDE_INT width = tree_low_cst (arg1, 1);
+ unsigned HOST_WIDE_INT idx = tree_low_cst (op2, 1);
+
+ if (width != 0
+ && simple_cst_equal (arg1, TYPE_SIZE (type)) == 1
+ && (idx % width) == 0
+ && (idx = idx / width)
+ < TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))
+ {
+ tree elements = TREE_VECTOR_CST_ELTS (arg0);
+ while (idx-- > 0 && elements)
+ elements = TREE_CHAIN (elements);
+ if (elements)
+ return TREE_VALUE (elements);
+ else
+ return fold_convert (type, integer_zero_node);
+ }
+ }
+ return NULL_TREE;
+
default:
return NULL_TREE;
} /* switch (code) */
of an indirection through OP0, or NULL_TREE if no simplification is
possible. */
-static tree
+tree
fold_indirect_ref_1 (tree type, tree op0)
{
tree sub = op0;