Skip to content

Commit 1fb9274

Browse files
committed
[analyzer][Z3] Restore the original timeout of 15s
Discussion here: https://discourse.llvm.org/t/analyzer-rfc-taming-z3-query-times/79520/15?u=szelethus The original patch, llvm#97298 introduced new timeouts backed by thorough testing and measurements to keep the running time of Z3 within reasonable limits. The measurements also showed that only certain reports and certain TUs were responsible for the poor performance of Z3 refutation. Unfortunately, it seems like that on machines with different characteristics (slower machines) the current timeouts don't just axe 0.01% of reports, but many more as well. Considering that timeouts are inherently nondeterministic as a cutoff point, this lead reports sets being vastly different on the same projects with the same configuration. The discussion link shows that all configurations introduced in the patch with their default values lead to severa nondeterminism of the analyzer. As we, and others use the analyzer as a gating tool for PRs, we should revert to the original defaults. We should respect that * There are still parts of the analyzer that are either proven or suspected to contain nondeterministic code (like pointer sets), * A 15s timeout is more likely to hit the same reports every time on a wider range of machines, but is still inherently nondeterministic, but an infinite timeout leads to the tool hanging, * If you measure the performance of the analyzer on your machines, you can and should achieve some speedup with little or no observable nondeterminism.
1 parent 181cc75 commit 1fb9274

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,20 +189,23 @@ ANALYZER_OPTION(
189189
"crosscheck-with-z3-eqclass-timeout-threshold",
190190
"Set a timeout for bug report equivalence classes in milliseconds. "
191191
"If we exhaust this threshold, we will drop the bug report eqclass "
192-
"instead of doing more Z3 queries. Set 0 for no timeout.", 700)
192+
"instead of doing more Z3 queries. On fast machines, 700 is a sane value. "
193+
"Set 0 for no timeout.", 0)
193194

194195
ANALYZER_OPTION(
195196
unsigned, Z3CrosscheckTimeoutThreshold,
196197
"crosscheck-with-z3-timeout-threshold",
197-
"Set a timeout for individual Z3 queries in milliseconds. "
198-
"Set 0 for no timeout.", 300)
198+
"Set a timeout for individual Z3 queries in milliseconds. On fast "
199+
"machines, 400 is a sane value. "
200+
"Set 0 for no timeout.", 15'000)
199201

200202
ANALYZER_OPTION(
201203
unsigned, Z3CrosscheckRLimitThreshold,
202204
"crosscheck-with-z3-rlimit-threshold",
203-
"Set the Z3 resource limit threshold. This sets a deterministic cutoff "
204-
"point for Z3 queries, as longer queries usually consume more resources. "
205-
"Set 0 for unlimited.", 400'000)
205+
"Set the Z3 resource limit threshold. This sets a supposedly deterministic "
206+
"cutoff point for Z3 queries, as longer queries usually consume more "
207+
"resources. "
208+
"Set 0 for unlimited.", 0)
206209

207210
ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile,
208211
"report-in-main-source-file",

clang/test/Analysis/analyzer-config.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
// CHECK-NEXT: cplusplus.Move:WarnOn = KnownsAndLocals
4242
// CHECK-NEXT: cplusplus.SmartPtrModeling:ModelSmartPtrDereference = false
4343
// CHECK-NEXT: crosscheck-with-z3 = false
44-
// CHECK-NEXT: crosscheck-with-z3-eqclass-timeout-threshold = 700
45-
// CHECK-NEXT: crosscheck-with-z3-rlimit-threshold = 400000
46-
// CHECK-NEXT: crosscheck-with-z3-timeout-threshold = 300
44+
// CHECK-NEXT: crosscheck-with-z3-eqclass-timeout-threshold = 0
45+
// CHECK-NEXT: crosscheck-with-z3-rlimit-threshold = 0
46+
// CHECK-NEXT: crosscheck-with-z3-timeout-threshold = 15000
4747
// CHECK-NEXT: ctu-dir = ""
4848
// CHECK-NEXT: ctu-import-cpp-threshold = 8
4949
// CHECK-NEXT: ctu-import-threshold = 24

clang/unittests/StaticAnalyzer/Z3CrosscheckOracleTest.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ static const AnalyzerOptions DefaultOpts = [] {
3838

3939
// Remember to update the tests in this file when these values change.
4040
// Also update the doc comment of `interpretQueryResult`.
41-
assert(Config.Z3CrosscheckRLimitThreshold == 400'000);
42-
assert(Config.Z3CrosscheckTimeoutThreshold == 300_ms);
41+
assert(Config.Z3CrosscheckRLimitThreshold == 0);
42+
assert(Config.Z3CrosscheckTimeoutThreshold == 15'000_ms);
4343
// Usually, when the timeout/rlimit threshold is reached, Z3 only slightly
4444
// overshoots until it realizes that it overshoot and needs to back off.
4545
// Consequently, the measured timeout should be fairly close to the threshold.
@@ -74,13 +74,13 @@ TEST_F(Z3CrosscheckOracleTest, SATWhenItGoesOverTime) {
7474
}
7575

7676
TEST_F(Z3CrosscheckOracleTest, UNSATWhenItGoesOverTime) {
77-
ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 310_ms, 1000_step}));
77+
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 310_ms, 1000_step}));
7878
}
7979

8080
TEST_F(Z3CrosscheckOracleTest, RejectsTimeout) {
8181
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step}));
8282
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step}));
83-
ASSERT_EQ(RejectEQClass, interpretQueryResult({UNDEF, 310_ms, 1000_step}));
83+
ASSERT_EQ(RejectReport, interpretQueryResult({UNDEF, 310_ms, 1000_step}));
8484
}
8585

8686
TEST_F(Z3CrosscheckOracleTest, RejectsUNSATs) {
@@ -97,7 +97,7 @@ TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfSpendsTooMuchTotalTime) {
9797
// Simulate long queries, that barely doesn't trigger the timeout.
9898
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step}));
9999
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step}));
100-
ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 290_ms, 1000_step}));
100+
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step}));
101101
}
102102

103103
TEST_F(Z3CrosscheckOracleTest, SATWhenItSpendsTooMuchTotalTime) {
@@ -114,7 +114,7 @@ TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfAttemptsManySmallQueries) {
114114
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 20_ms, 1000_step}));
115115
}
116116
// Do one more to trigger the heuristic.
117-
ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 1_ms, 1000_step}));
117+
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 1_ms, 1000_step}));
118118
}
119119

120120
TEST_F(Z3CrosscheckOracleTest, SATWhenIfAttemptsManySmallQueries) {
@@ -131,7 +131,7 @@ TEST_F(Z3CrosscheckOracleTest, SATWhenIfAttemptsManySmallQueries) {
131131
TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfExhaustsRLimit) {
132132
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step}));
133133
ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step}));
134-
ASSERT_EQ(RejectEQClass, interpretQueryResult({UNDEF, 25_ms, 405'000_step}));
134+
ASSERT_EQ(RejectReport, interpretQueryResult({UNDEF, 25_ms, 405'000_step}));
135135
}
136136

137137
TEST_F(Z3CrosscheckOracleTest, SATWhenItExhaustsRLimit) {

0 commit comments

Comments
 (0)