out whether a complex number is degenerate in some way, having only real
or only complex parts. */
-typedef enum
+enum
{
UNINITIALIZED = 0,
ONLY_REAL = 1,
ONLY_IMAG = 2,
VARYING = 3
-} complex_lattice_t;
+};
+
+/* The type complex_lattice_t holds combinations of the above
+ constants. */
+typedef int complex_lattice_t;
#define PAIR(a, b) ((a) << 2 | (b))
{
int zerop = false;
- if (TREE_CODE (t) == REAL_CST)
+ /* Operations with real or imaginary part of a complex number zero
+ cannot be treated the same as operations with a real or imaginary
+ operand if we care about the signs of zeros in the result. */
+ if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
zerop = REAL_VALUES_IDENTICAL (TREE_REAL_CST (t), dconst0);
else if (TREE_CODE (t) == FIXED_CST)
zerop = fixed_zerop (t);
case INDIRECT_REF:
case COMPONENT_REF:
case ARRAY_REF:
+ case VIEW_CONVERT_EXPR:
{
tree inner_type = TREE_TYPE (TREE_TYPE (t));
gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
if (code == MULT_EXPR)
- bcode = BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
+ bcode = ((enum built_in_function)
+ (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
else if (code == RDIV_EXPR)
- bcode = BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
+ bcode = ((enum built_in_function)
+ (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
else
gcc_unreachable ();
fn = built_in_decls[bcode];
update_complex_assignment (gsi, rr, ri);
}
-/* Expand complex division to scalars, straightforward algorithm.
+/* Keep this algorithm in sync with fold-const.c:const_binop().
+
+ Expand complex division to scalars, straightforward algorithm.
a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
t = br*br + bi*bi
*/
update_complex_assignment (gsi, rr, ri);
}
-/* Expand complex division to scalars, modified algorithm to minimize
+/* Keep this algorithm in sync with fold-const.c:const_binop().
+
+ Expand complex division to scalars, modified algorithm to minimize
overflow with wide input ranges. */
static void
/* Examine |br| < |bi|, and branch. */
t1 = gimplify_build1 (gsi, ABS_EXPR, inner_type, br);
t2 = gimplify_build1 (gsi, ABS_EXPR, inner_type, bi);
- compare = fold_build2 (LT_EXPR, boolean_type_node, t1, t2);
+ compare = fold_build2_loc (gimple_location (gsi_stmt (*gsi)),
+ LT_EXPR, boolean_type_node, t1, t2);
STRIP_NOPS (compare);
bb_cond = bb_true = bb_false = bb_join = NULL;
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
- cond = fold_build2 (EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
+ cond = fold_build2_loc (gimple_location (stmt),
+ EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
stmt = gimple_build_cond_from_tree (cond, NULL_TREE, NULL_TREE);
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);