From: Richard Biener <rguenther@suse.de>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH] Fix PR80776
Date: Mon, 27 Nov 2017 14:34:00 -0000 [thread overview]
Message-ID: <alpine.LSU.2.20.1711271436550.12252@zhemvz.fhfr.qr> (raw)
The following avoids -Wformat-overflow false positives by teaching
EVRP the trick about __builtin_unreachable () "other" edges and
attaching range info to SSA names. EVRP does a better job in keeping
ranges for every SSA name from conditional info (VRP "optimizes" its
costly ASSERT_EXPR insertion process).
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
This will also fix the testcase from PR83072 but it doesn't really
fix all cases I want to fix with a fix for it. OTOH it might be
this is enough for stage3.
Richard.
2017-11-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/80776
* gimple-ssa-evrp-analyze.h (evrp_range_analyzer::set_ssa_range_info):
Declare.
* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::set_ssa_range_info):
New function.
(evrp_range_analyzer::record_ranges_from_incoming_edges):
If the incoming edge is an effective fallthru because the other
edge only reaches a __builtin_unreachable () then record ranges
derived from the controlling condition in SSA info.
(evrp_range_analyzer::record_ranges_from_phis): Use set_ssa_range_info.
(evrp_range_analyzer::record_ranges_from_stmt): Likewise.
* gcc.dg/pr80776-1.c: New testcase.
* gcc.dg/pr80776-2.c: Likewise.
Index: gcc/gimple-ssa-evrp-analyze.c
===================================================================
--- gcc/gimple-ssa-evrp-analyze.c (revision 255163)
+++ gcc/gimple-ssa-evrp-analyze.c (working copy)
@@ -91,6 +91,31 @@ evrp_range_analyzer::try_find_new_range
return NULL;
}
+/* For LHS record VR in the SSA info. */
+void
+evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range *vr)
+{
+ /* Set the SSA with the value range. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
+ {
+ if ((vr->type == VR_RANGE
+ || vr->type == VR_ANTI_RANGE)
+ && (TREE_CODE (vr->min) == INTEGER_CST)
+ && (TREE_CODE (vr->max) == INTEGER_CST))
+ set_range_info (lhs, vr->type,
+ wi::to_wide (vr->min),
+ wi::to_wide (vr->max));
+ }
+ else if (POINTER_TYPE_P (TREE_TYPE (lhs))
+ && ((vr->type == VR_RANGE
+ && range_includes_zero_p (vr->min,
+ vr->max) == 0)
+ || (vr->type == VR_ANTI_RANGE
+ && range_includes_zero_p (vr->min,
+ vr->max) == 1)))
+ set_ptr_nonnull (lhs);
+}
+
void
evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
{
@@ -134,10 +159,19 @@ evrp_range_analyzer::record_ranges_from_
if (vr)
vrs.safe_push (std::make_pair (asserts[i].name, vr));
}
+
+ /* If pred_e is really a fallthru we can record value ranges
+ in SSA names as well. */
+ bool is_fallthru = assert_unreachable_fallthru_edge_p (pred_e);
+
/* Push updated ranges only after finding all of them to avoid
ordering issues that can lead to worse ranges. */
for (unsigned i = 0; i < vrs.length (); ++i)
- push_value_range (vrs[i].first, vrs[i].second);
+ {
+ push_value_range (vrs[i].first, vrs[i].second);
+ if (is_fallthru)
+ set_ssa_range_info (vrs[i].first, vrs[i].second);
+ }
}
}
}
@@ -185,24 +219,7 @@ evrp_range_analyzer::record_ranges_from_
vr_values->update_value_range (lhs, &vr_result);
/* Set the SSA with the value range. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
- {
- if ((vr_result.type == VR_RANGE
- || vr_result.type == VR_ANTI_RANGE)
- && (TREE_CODE (vr_result.min) == INTEGER_CST)
- && (TREE_CODE (vr_result.max) == INTEGER_CST))
- set_range_info (lhs, vr_result.type,
- wi::to_wide (vr_result.min),
- wi::to_wide (vr_result.max));
- }
- else if (POINTER_TYPE_P (TREE_TYPE (lhs))
- && ((vr_result.type == VR_RANGE
- && range_includes_zero_p (vr_result.min,
- vr_result.max) == 0)
- || (vr_result.type == VR_ANTI_RANGE
- && range_includes_zero_p (vr_result.min,
- vr_result.max) == 1)))
- set_ptr_nonnull (lhs);
+ set_ssa_range_info (lhs, &vr_result);
}
}
@@ -224,21 +241,7 @@ evrp_range_analyzer::record_ranges_from_
vr_values->update_value_range (output, &vr);
/* Set the SSA with the value range. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
- {
- if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
- && (TREE_CODE (vr.min) == INTEGER_CST)
- && (TREE_CODE (vr.max) == INTEGER_CST))
- set_range_info (output, vr.type,
- wi::to_wide (vr.min),
- wi::to_wide (vr.max));
- }
- else if (POINTER_TYPE_P (TREE_TYPE (output))
- && ((vr.type == VR_RANGE
- && range_includes_zero_p (vr.min, vr.max) == 0)
- || (vr.type == VR_ANTI_RANGE
- && range_includes_zero_p (vr.min, vr.max) == 1)))
- set_ptr_nonnull (output);
+ set_ssa_range_info (output, &vr);
}
else
vr_values->set_defs_to_varying (stmt);
Index: gcc/gimple-ssa-evrp-analyze.h
===================================================================
--- gcc/gimple-ssa-evrp-analyze.h (revision 255163)
+++ gcc/gimple-ssa-evrp-analyze.h (working copy)
@@ -68,6 +68,7 @@ class evrp_range_analyzer
value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
void record_ranges_from_incoming_edge (basic_block);
void record_ranges_from_phis (basic_block);
+ void set_ssa_range_info (tree, value_range *);
/* STACK holds the old VR. */
auto_vec<std::pair <tree, value_range*> > stack;
Index: gcc/testsuite/gcc.dg/pr80776-1.c
===================================================================
--- gcc/testsuite/gcc.dg/pr80776-1.c (nonexistent)
+++ gcc/testsuite/gcc.dg/pr80776-1.c (working copy)
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wformat-overflow" } */
+
+extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
+__attribute__ ((__nothrow__ , __leaf__)) sprintf (char *__restrict __s, const char *__restrict __fmt, ...)
+{
+ return __builtin___sprintf_chk (__s, 2 - 1,
+ __builtin_object_size (__s, 2 > 1), __fmt, __builtin_va_arg_pack ());
+}
+char number[sizeof "999999"];
+int somerandom (void);
+void
+Foo (void)
+{
+ int i = somerandom ();
+ if (! (0 <= i))
+ __builtin_unreachable ();
+ if (! (0 <= i && i <= 999999))
+ __builtin_unreachable ();
+ sprintf (number, "%d", i); /* { dg-bogus "writing" } */
+}
Index: gcc/testsuite/gcc.dg/pr80776-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr80776-2.c (nonexistent)
+++ gcc/testsuite/gcc.dg/pr80776-2.c (working copy)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wformat-overflow" } */
+
+extern int sprintf (char *restrict, const char *restrict, ...)
+ __attribute__ ((__nothrow__));
+ extern int foo (void);
+
+int
+Fgenerate_new_buffer_name (void)
+{
+ char number[2];
+ int i = foo ();
+ if (i < 0)
+ __builtin_unreachable ();
+ if (i >= 2)
+ __builtin_unreachable ();
+ return sprintf (number, "%d", i); /* { dg-bogus "writing" } */
+}
next reply other threads:[~2017-11-27 13:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-27 14:34 Richard Biener [this message]
2017-11-27 17:29 ` Jeff Law
2017-11-28 9:49 ` Richard Biener
2017-11-28 15:15 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LSU.2.20.1711271436550.12252@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).