--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-options "-O2 -fgimple" } */
+
+static int o;
+
+__attribute__((noipa))
+int
+n ()
+{
+ return 129105662;
+}
+
+
+int __GIMPLE (ssa,startwith("vrp1"),guessed_local(1073741824))
+main ()
+{
+ int am;
+ int ak;
+ int ay;
+ int D_3044;
+ int tem[1];
+ int _10;
+ int _11;
+ int _12;
+ int _21;
+ int _23;
+ int _24;
+ int _25;
+ int _26;
+ int _27;
+ int _29;
+
+ __BB(2,guessed_local(1073741824)):
+ tem[0ul] = _Literal (int) -1;
+ o = 2147483645;
+ goto __BB6(precise(134217728));
+
+ __BB(10,guessed_local(17434151171)):
+ goto __BB3(precise(134217728));
+
+ __BB(3,loop_header(2),guessed_local(19522579055)):
+ ak_20 = __PHI (__BB10: ak_22, __BB6: ak_30);
+ am_7 = __PHI (__BB10: am_9, __BB6: am_31);
+ ay_16 = __PHI (__BB10: ay_17, __BB6: ay_32);
+be:
+ am_9 = am_7 + 1;
+ _10 = n ();
+ _11 = _10 + _Literal (int) -129105632;
+ _12 = am_9 << _11;
+ if (_12 == 0)
+ goto __BB4(guessed(126835753));
+ else
+ goto __BB5(guessed(7381975));
+
+ __BB(4,guessed_local(18448837212)):
+ ay_17 = ay_16 - _Literal (int) -2147483648;
+ _21 = ak_20 + _Literal (int) -1;
+ ak_22 = _21 + 2147483647;
+ if (ak_22 != 0)
+ goto __BB10(guessed(126835753));
+ else
+ goto __BB9(guessed(7381975));
+
+ __BB(5,guessed_local(1073741842)):
+ _23 = o;
+ _24 = _Literal (int) -2 - _23;
+ o = _24;
+ _25 = ak_20 + _Literal (int) -1;
+ __MEM <int> ((int *)&tem) = _25;
+ _26 = ay_16 >> 31;
+ _27 = ak_20 + _26;
+ if (_27 != 2147483645)
+ goto __BB7(guessed(67108864));
+ else
+ goto __BB8(guessed(67108864));
+
+ __BB(9,guessed_local(1014686041)):
+ goto __BB6(precise(134217728));
+
+ __BB(6,loop_header(1),guessed_local(2088427865)):
+ ak_30 = __PHI (__BB2: _Literal (int) -1, __BB9: 0);
+ am_31 = __PHI (__BB2: _Literal (int) -1, __BB9: am_9);
+ ay_32 = __PHI (__BB2: _Literal (int) -1782460880, __BB9: 3);
+az:
+ goto __BB3(precise(134217728));
+
+ __BB(7,guessed_local(536870921)):
+ goto __BB8(precise(134217728));
+
+ __BB(8,guessed_local(1073741842)):
+ _29 = __PHI (__BB5: 0, __BB7: 1);
+ if (_29 != 0)
+ goto __BB11;
+ else
+ goto __BB12;
+
+ __BB(11):
+ __builtin_abort ();
+
+ __BB(12):
+ return _29;
+
+}
+
+
+
tree *evolution_of_loop, int limit);
t_bool follow_ssa_edge_inner_loop_phi (gphi *loop_phi_node,
tree *evolution_of_loop, int limit);
- tree add_to_evolution (tree chrec_before, enum tree_code code,
- tree to_add, gimple *at_stmt);
+ tree add_to_evolution (tree chrec_before, tree to_add, gimple *at_stmt);
tree add_to_evolution_1 (tree chrec_before, tree to_add, gimple *at_stmt);
class loop *loop;
*/
tree
-scev_dfs::add_to_evolution (tree chrec_before, enum tree_code code,
- tree to_add, gimple *at_stmt)
+scev_dfs::add_to_evolution (tree chrec_before, tree to_add, gimple *at_stmt)
{
- tree type = chrec_type (to_add);
tree res = NULL_TREE;
if (to_add == NULL_TREE)
fprintf (dump_file, ")\n");
}
- if (code == MINUS_EXPR)
- {
- if (INTEGRAL_TYPE_P (type)
- && TYPE_OVERFLOW_UNDEFINED (type)
- && !expr_not_equal_to (to_add,
- wi::to_wide (TYPE_MIN_VALUE (type))))
- {
- tree utype = unsigned_type_for (type);
- to_add = chrec_convert_rhs (utype, to_add);
- to_add = chrec_fold_multiply (utype, to_add,
- build_int_cst_type (utype, -1));
- to_add = chrec_convert_rhs (type, to_add);
- }
- else
- to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
- ? build_real (type, dconstm1)
- : build_int_cst_type (type, -1));
- }
-
res = add_to_evolution_1 (chrec_before, to_add, at_stmt);
if (dump_file && (dump_flags & TDF_SCEV))
res = follow_ssa_edge_expr (at_stmt, rhs0, &evol, limit);
if (res == t_true)
*evolution_of_loop = add_to_evolution
- (chrec_convert (type, evol, at_stmt), code, rhs1, at_stmt);
+ (chrec_convert (type, evol, at_stmt), rhs1, at_stmt);
else if (res == t_false)
{
res = follow_ssa_edge_expr
if (res == t_true)
*evolution_of_loop = add_to_evolution
(chrec_convert (type, *evolution_of_loop, at_stmt),
- code, rhs0, at_stmt);
+ rhs0, at_stmt);
}
}
if (res == t_true)
*evolution_of_loop = add_to_evolution
(chrec_convert (type, *evolution_of_loop, at_stmt),
- code, rhs0, at_stmt);
+ rhs0, at_stmt);
}
else
res = t_false;
break;
- case MINUS_EXPR:
- /* This case is under the form "opnd0 = rhs0 - rhs1". */
- if (TREE_CODE (rhs0) == SSA_NAME)
- gcc_unreachable (); /* Handled in caller. */
- else
- /* Otherwise, match an assignment under the form:
- "a = ... - ...". */
- /* And there is nothing to do. */
- res = t_false;
- break;
-
default:
res = t_false;
}
/* Fallthru. */
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
- case MINUS_EXPR:
/* This case is under the form "rhs0 +- rhs1". */
- if (TREE_CODE (rhs0) == SSA_NAME
- && (TREE_CODE (rhs1) != SSA_NAME || code == MINUS_EXPR))
+ if (TREE_CODE (rhs0) == SSA_NAME && TREE_CODE (rhs1) != SSA_NAME)
{
/* Match an assignment under the form:
"a = b +- ...". */
if (res == t_true)
*evolution_of_loop = add_to_evolution
(chrec_convert (type, *evolution_of_loop, at_stmt),
- code, rhs1, at_stmt);
+ rhs1, at_stmt);
return res;
}
/* Else search for the SCC in both rhs0 and rhs1. */
return follow_ssa_edge_binary (at_stmt, type, rhs0, code, rhs1,
evolution_of_loop, limit);
+
+ case MINUS_EXPR:
+ /* This case is under the form "rhs0 - rhs1". */
+ if (TREE_CODE (rhs0) == SSA_NAME)
+ {
+ /* Match an assignment under the form:
+ "a = b +- ...". */
+ t_bool res = follow_ssa_edge_expr (at_stmt, rhs0,
+ evolution_of_loop, limit);
+ if (res != t_true)
+ return res;
+ /* We have to avoid negating INT_MIN given that a) invokes UB,
+ b) results in a wrong scev_direction. See PR126171. */
+ if (INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_UNDEFINED (type)
+ && !expr_not_equal_to (rhs1,
+ wi::to_wide (TYPE_MIN_VALUE (type))))
+ {
+ tree utype = unsigned_type_for (type);
+ tree to_add = chrec_convert_rhs (utype, rhs1);
+ to_add = chrec_fold_multiply (utype, to_add,
+ build_int_cst_type (utype, -1));
+ *evolution_of_loop
+ = chrec_convert (utype, *evolution_of_loop, at_stmt);
+ *evolution_of_loop = add_to_evolution (*evolution_of_loop,
+ to_add, at_stmt);
+ *evolution_of_loop
+ = chrec_convert (type, *evolution_of_loop, at_stmt);
+ }
+ else
+ {
+ tree to_add = chrec_fold_multiply (type, rhs1,
+ build_minus_one_cst (type));
+ *evolution_of_loop
+ = add_to_evolution (chrec_convert (type, *evolution_of_loop,
+ at_stmt),
+ to_add, at_stmt);
+ }
+ return res;
+ }
+ /* There is nothing to do. */
+ return t_false;
+
default:
return t_false;
}