+2019-10-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/92131
+ * tree-vrp.c (extract_range_from_plus_minus_expr): If the resulting
+ range would be symbolic, drop to varying for any explicit overflow
+ in the constant part or if neither range is a singleton.
+
2019-10-18 Georg-Johann Lay <avr@gjlay.de>
- Backport from 2019-10-18 trunk r277143.
+ Backport from trunk
+ 2019-10-18 Georg-Johann Lay <avr@gjlay.de>
PR target/86040
* config/avr/avr.c (avr_out_lpm): Do not shortcut-return.
+2019-10-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20191023-1.c: New test.
+
2019-10-18 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/69455
--- /dev/null
+/* PR tree-optimization/92131 */
+/* Testcase by Armin Rigo <arigo@tunes.org> */
+
+long b, c, d, e, f, i;
+char g, h, j, k;
+int *aa;
+
+static void error (void) __attribute__((noipa));
+static void error (void) { __builtin_abort(); }
+
+static void see_me_here (void) __attribute__((noipa));
+static void see_me_here (void) {}
+
+static void aaa (void) __attribute__((noipa));
+static void aaa (void) {}
+
+static void a (void) __attribute__((noipa));
+static void a (void) {
+ long am, ao;
+ if (aa == 0) {
+ aaa();
+ if (j)
+ goto ay;
+ }
+ return;
+ay:
+ aaa();
+ if (k) {
+ aaa();
+ goto az;
+ }
+ return;
+az:
+ if (i)
+ if (g)
+ if (h)
+ if (e)
+ goto bd;
+ return;
+bd:
+ am = 0;
+ while (am < e) {
+ switch (c) {
+ case 8:
+ goto bh;
+ case 4:
+ return;
+ }
+ bh:
+ if (am >= 0)
+ b = -am;
+ ao = am + b;
+ f = ao & 7;
+ if (f == 0)
+ see_me_here();
+ if (ao >= 0)
+ am++;
+ else
+ error();
+ }
+}
+
+int main (void)
+{
+ j++;
+ k++;
+ i++;
+ g++;
+ h++;
+ e = 1;
+ a();
+ return 0;
+}
max_ovf = 1;
}
- /* If we have overflow for the constant part and the resulting
- range will be symbolic, drop to VR_VARYING. */
- if ((min_ovf && sym_min_op0 != sym_min_op1)
- || (max_ovf && sym_max_op0 != sym_max_op1))
+ /* If the resulting range will be symbolic, we need to eliminate any
+ explicit or implicit overflow introduced in the above computation
+ because compare_values could make an incorrect use of it. That's
+ why we require one of the ranges to be a singleton. */
+ if ((sym_min_op0 != sym_min_op1 || sym_max_op0 != sym_max_op1)
+ && (min_ovf || max_ovf
+ || (min_op0 != max_op0 && min_op1 != max_op1)))
{
set_value_range_to_varying (vr);
return;