+2019-10-21 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2019-09-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR go/91617
+ * fold-const.c (range_check_type): For enumeral and boolean
+ type, pass 1 to type_for_size langhook instead of
+ TYPE_UNSIGNED (etype). Return unsigned_type_for result whenever
+ etype isn't TYPE_UNSIGNED INTEGER_TYPE.
+ (build_range_check): Don't call unsigned_type_for for pointer types.
+ * match.pd (X / C1 op C2): Don't call unsigned_type_for on
+ range_check_type result.
+
+ 2019-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91351
+ * tree-cfg.c (generate_range_test): Use range_check_type instead of
+ unsigned_type_for.
+ * tree-cfgcleanup.c (convert_single_case_switch): Punt if
+ range_check_type returns NULL.
+ * tree-switch-conversion.c (switch_conversion::build_one_array):
+ Use range_check_type instead of unsigned_type_for, don't perform
+ linear opt if it returns NULL.
+ (bit_test_cluster::find_bit_tests): Formatting fix.
+ (bit_test_cluster::emit): Use range_check_type instead of
+ unsigned_type_for.
+ (switch_decision_tree::try_switch_expansion): Punt if range_check_type
+ returns NULL.
+
2019-10-18 Georg-Johann Lay <avr@gjlay.de>
Backport from 2019-10-18 trunk r277143.
/* First make sure that arithmetics in this type is valid, then make sure
that it wraps around. */
if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE)
- etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
- TYPE_UNSIGNED (etype));
+ etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1);
- if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS (etype))
+ if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_UNSIGNED (etype))
{
tree utype, minv, maxv;
else
return NULL_TREE;
}
+ else if (POINTER_TYPE_P (etype))
+ etype = unsigned_type_for (etype);
return etype;
}
if (etype == NULL_TREE)
return NULL_TREE;
- if (POINTER_TYPE_P (etype))
- etype = unsigned_type_for (etype);
-
high = fold_convert_loc (loc, etype, high);
low = fold_convert_loc (loc, etype, low);
exp = fold_convert_loc (loc, etype, exp);
tree etype = range_check_type (TREE_TYPE (@0));
if (etype)
{
- if (! TYPE_UNSIGNED (etype))
- etype = unsigned_type_for (etype);
hi = fold_convert (etype, hi);
lo = fold_convert (etype, lo);
hi = const_binop (MINUS_EXPR, etype, hi, lo);
2019-10-21 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2019-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91351
+ * g++.dg/opt/pr91351.C: New test.
+
2019-08-09 Jakub Jelinek <jakub@redhat.com>
PR c/91401
--- /dev/null
+// PR tree-optimization/91351
+// { dg-do run }
+// { dg-options "-O2 -fstrict-enums" }
+
+enum E { e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12,
+ e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25 };
+
+__attribute__((noipa)) void
+foo ()
+{
+ __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+bar ()
+{
+}
+
+__attribute__((noipa)) void
+baz (E e)
+{
+ switch (e)
+ {
+ case e11:
+ case e12:
+ case e13: foo (); break;
+ case e24: break;
+ case e14:
+ case e15: break;
+ default: bar (); break;
+ }
+}
+
+int
+main ()
+{
+ baz (e3);
+}
tree *lhs, tree *rhs)
{
tree type = TREE_TYPE (index);
- tree utype = unsigned_type_for (type);
+ tree utype = range_check_type (type);
low = fold_convert (utype, low);
high = fold_convert (utype, high);
if (high)
{
tree lhs, rhs;
+ if (range_check_type (TREE_TYPE (index)) == NULL_TREE)
+ return false;
generate_range_test (bb, index, low, high, &lhs, &rhs);
cond = gimple_build_cond (LE_EXPR, lhs, rhs, NULL_TREE, NULL_TREE);
}
vec<constructor_elt, va_gc> *constructor = m_constructors[num];
wide_int coeff_a, coeff_b;
bool linear_p = contains_linear_function_p (constructor, &coeff_a, &coeff_b);
- if (linear_p)
+ tree type;
+ if (linear_p
+ && (type = range_check_type (TREE_TYPE ((*constructor)[0].value))))
{
if (dump_file && coeff_a.to_uhwi () > 0)
fprintf (dump_file, "Linear transformation with A = %" PRId64
coeff_b.to_shwi ());
/* We must use type of constructor values. */
- tree t = unsigned_type_for (TREE_TYPE ((*constructor)[0].value));
gimple_seq seq = NULL;
- tree tmp = gimple_convert (&seq, t, m_index_expr);
- tree tmp2 = gimple_build (&seq, MULT_EXPR, t,
- wide_int_to_tree (t, coeff_a), tmp);
- tree tmp3 = gimple_build (&seq, PLUS_EXPR, t, tmp2,
- wide_int_to_tree (t, coeff_b));
+ tree tmp = gimple_convert (&seq, type, m_index_expr);
+ tree tmp2 = gimple_build (&seq, MULT_EXPR, type,
+ wide_int_to_tree (type, coeff_a), tmp);
+ tree tmp3 = gimple_build (&seq, PLUS_EXPR, type, tmp2,
+ wide_int_to_tree (type, coeff_b));
tree tmp4 = gimple_convert (&seq, TREE_TYPE (name), tmp3);
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
load = gimple_build_assign (name, tmp4);
entire));
}
else
- for (int i = end - 1; i >= start; i--)
+ for (int i = end - 1; i >= start; i--)
output.safe_push (clusters[i]);
end = start;
unsigned int i, j, k;
unsigned int count;
- tree unsigned_index_type = unsigned_type_for (index_type);
+ tree unsigned_index_type = range_check_type (index_type);
gimple_stmt_iterator gsi;
gassign *shift_stmt;
tree index_type = TREE_TYPE (index_expr);
basic_block bb = gimple_bb (m_switch);
- if (gimple_switch_num_labels (m_switch) == 1)
+ if (gimple_switch_num_labels (m_switch) == 1
+ || range_check_type (index_type) == NULL_TREE)
return false;
/* Find the default case target label. */