This is an archive of the discontinued LLVM Phabricator instance.

[Analyzer] Quick Fix for exponential execution time when simpilifying complex additive expressions
ClosedPublic

Authored by baloghadamsoftware on Jul 19 2018, 3:30 AM.

Details

Summary

Patch SValBuilder Comparison Rearrangement (with Restrictions and Analyzer Option) not only rearranges comparisons but also binary expressions. This latter behavior is not protected by the analyzer option. Hower, since no complexity threshold is enforced to the symbols this may result in exponential execution time if the expressions are too complex: Huge static analysis performance regression for very simple testcase. For a quick fix we extended the analyzer option to also cover the additive cases.

This is only a temporary fix, the final solution should be enforcing the complexity threshold to the symbols.

Diff Detail

Repository
rL LLVM

Event Timeline

NoQ accepted this revision.Jul 19 2018, 10:04 AM

I was thinking of two flags, but that'll work too.

This revision is now accepted and ready to land.Jul 19 2018, 10:04 AM
This revision was automatically updated to reflect the committed changes.

I getting the following error when analyzing test/Analysis/plist-macros.cpp, usign z3 as constraint manager (-analyzer-constraints=z3 -DANALYZER_CM_Z3):

/home/mgadelha/llvm/tools/clang/test/Analysis/plist-macros.cpp:640:16: error: CHECK-NEXT: expected string not found in input
// CHECK-NEXT: <key>line</key><integer>36</integer>
               ^
/home/mgadelha/llvm/build/tools/clang/test/Analysis/Output/plist-macros.cpp.tmp.plist:562:2: note: scanning from here
 <key>line</key><integer>37</integer>
 ^

I bisected back to this commit. I reverted it locally and the error goes away.

Any idea why it doesn't work with z3?

NoQ added a comment.Jul 25 2018, 5:47 PM

I getting the following error when analyzing test/Analysis/plist-macros.cpp, usign z3 as constraint manager (-analyzer-constraints=z3 -DANALYZER_CM_Z3):

/home/mgadelha/llvm/tools/clang/test/Analysis/plist-macros.cpp:640:16: error: CHECK-NEXT: expected string not found in input
// CHECK-NEXT: <key>line</key><integer>36</integer>
               ^
/home/mgadelha/llvm/build/tools/clang/test/Analysis/Output/plist-macros.cpp.tmp.plist:562:2: note: scanning from here
 <key>line</key><integer>37</integer>
 ^

I bisected back to this commit. I reverted it locally and the error goes away.

Any idea why it doesn't work with z3?

Uhm, dunno, plist/FileCheck tests are annoying. What i usually do to make sense out of them is update the tested output with the actual output and look at git diff. From that it's usually obvious what exactly happened (warnings added, warnings removed, warnings moved to a different location, intermediate diagnostics added, intermediate diagnostics removed, intermediate diagnostics moved to a different location). Could you do that and see if it makes sense or attach the diff here so that we could have a look?

Uhm, dunno, plist/FileCheck tests are annoying. What i usually do to make sense out of them is update the tested output with the actual output and look at git diff. From that it's usually obvious what exactly happened (warnings added, warnings removed, warnings moved to a different location, intermediate diagnostics added, intermediate diagnostics removed, intermediate diagnostics moved to a different location). Could you do that and see if it makes sense or attach the diff here so that we could have a look?

The diff using Z3 is the removal of all lines inserted in plist-macros.cpp by this commit. I think it's a note in the first if (assuming condition is true) of:

#define noPathNoteMacro y+y
int macroInExpressionNoNote(int *p, int y) {
  y++;
  if (5 + noPathNoteMacro)
    if (p)
      ;
  return *p; // expected-warning {{Dereference of null pointer}}
}

Maybe using Z3 as CM, the CSA finds the other path, where the condition is false?

NoQ added a comment.EditedJul 25 2018, 6:31 PM

The "Assuming..." diagnostic piece isn't the same as "Taking true/false branch" diagnostic piece. The former indicates that a constraint is added. The latter indicate how the path flows between program points.

The absence of "Assuming..." indicates that Z3 didn't need to make an assumption; it already knew that the condition is true.

I understand how Z3 could figure this out. Indeed, 5 + (y + 1) + (y + 1) = 2y + 7 is an odd number, and therefore it cannot be equal to 0.

I don't understand how our rearrangement could figure this out. Might it have been an incorrect rearrangement?

In any case, it is clear that both behaviors are currently correct and the test needs to be updated to reflect the Z3's superpower. I suggest using FileCheck's -check-prefixes= to highlight the difference. See cfg-rich-constructors.cpp for an example of how to use those.