tree ctype = build_complex_type (type);
tree call = build_call_expr_internal_loc (loc, ifn, ctype, 2,
arg0, arg1);
- tree tgt = save_expr (call);
+ tree tgt;
+ if (ovf_only)
+ {
+ tgt = call;
+ intres = NULL_TREE;
+ }
+ else
+ {
+ /* Force SAVE_EXPR even for calls which satisfy tree_invariant_p_1,
+ as while the call itself is const, the REALPART_EXPR store is
+ certainly not. And in any case, we want just one call,
+ not multiple and trying to CSE them later. */
+ TREE_SIDE_EFFECTS (call) = 1;
+ tgt = save_expr (call);
+ }
intres = build1_loc (loc, REALPART_EXPR, type, tgt);
ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt);
ovfres = fold_convert_loc (loc, boolean_type_node, ovfres);
tree ctype = build_complex_type (type);
tree call = build_call_expr_internal_loc (loc, ifn, ctype, 2,
args[0], args[1]);
+ /* Force SAVE_EXPR even for calls which satisfy tree_invariant_p_1,
+ as while the call itself is const, the REALPART_EXPR store is
+ certainly not. And in any case, we want just one call,
+ not multiple and trying to CSE them later. */
+ TREE_SIDE_EFFECTS (call) = 1;
tree tgt = save_expr (call);
tree intres = build1_loc (loc, REALPART_EXPR, type, tgt);
tree ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt);
call = build_call_expr_internal_loc (loc, ifn, ctype, 2,
intres, args[2]);
+ TREE_SIDE_EFFECTS (call) = 1;
tgt = save_expr (call);
intres = build1_loc (loc, REALPART_EXPR, type, tgt);
tree ovfres2 = build1_loc (loc, IMAGPART_EXPR, type, tgt);
--- /dev/null
+/* PR middle-end/108789 */
+
+int
+add (unsigned *r, const unsigned *a, const unsigned *b)
+{
+ return __builtin_add_overflow (*a, *b, r);
+}
+
+int
+mul (unsigned *r, const unsigned *a, const unsigned *b)
+{
+ return __builtin_mul_overflow (*a, *b, r);
+}
+
+int
+main ()
+{
+ unsigned x;
+
+ /* 1073741824U + 1073741824U should not overflow. */
+ x = (__INT_MAX__ + 1U) / 2;
+ if (add (&x, &x, &x))
+ __builtin_abort ();
+
+ /* 256U * 256U should not overflow */
+ x = 1U << (sizeof (int) * __CHAR_BIT__ / 4);
+ if (mul (&x, &x, &x))
+ __builtin_abort ();
+
+ /* 2147483648U + 2147483648U should overflow */
+ x = __INT_MAX__ + 1U;
+ if (!add (&x, &x, &x))
+ __builtin_abort ();
+
+ /* 65536U * 65536U should overflow */
+ x = 1U << (sizeof (int) * __CHAR_BIT__ / 2);
+ if (!mul (&x, &x, &x))
+ __builtin_abort ();
+}