Static Value-Flow Analysis
Loading...
Searching...
No Matches
Functions
AbstractInterpretation.cpp File Reference
#include "AE/Svfexe/AbstractInterpretation.h"
#include "AE/Svfexe/SparseAbstractInterpretation.h"
#include "AE/Svfexe/AbsExtAPI.h"
#include "SVFIR/SVFIR.h"
#include "Util/Options.h"
#include "Util/WorkList.h"
#include "Graphs/CallGraph.h"
#include "WPA/Andersen.h"
#include <cmath>
#include <memory>

Go to the source code of this file.

Functions

static const LoadStmtfindBackingLoad (const SVFVar *var)
 
static IntervalValue computeCmpConstraint (s32_t predicate, s64_t succ, bool isLHS, const IntervalValue &self, const IntervalValue &other)
 

Function Documentation

◆ computeCmpConstraint()

static IntervalValue computeCmpConstraint ( s32_t  predicate,
s64_t  succ,
bool  isLHS,
const IntervalValue self,
const IntervalValue other 
)
static

Compute the interval constraint on one cmp operand given the predicate, branch direction (succ), which side it is on, and the other operand's interval. Returns top if no useful narrowing is possible.

Called from collectBranchRefinement for each non-constant operand that has a backing load. Given a branch condition like:

cmp = icmp sgt a, 5 ; a > 5 br i1 cmp, label T, F

On the true branch (succ=1), operand a (isLHS=true) is constrained to [6, +inf). On the false branch (succ=0), a is constrained to (-inf, 5]. The result is used to narrow the ObjVar behind a's load.

Definition at line 374 of file AbstractInterpretation.cpp.

377{
378 // Normalize: always reason from the LHS perspective.
379 // If we are the RHS operand, swap the predicate direction.
380 if (!isLHS)
381 {
382 // a > b from b's perspective: b < a
383 static const Map<s32_t, s32_t> swapPred =
384 {
407 };
408 auto it = swapPred.find(predicate);
409 if (it == swapPred.end()) return IntervalValue::top();
410 predicate = it->second;
411 }
412
413 // If false branch, negate the predicate.
414 if (succ == 0)
415 {
416 static const Map<s32_t, s32_t> negPred =
417 {
440 };
441 auto it = negPred.find(predicate);
442 if (it == negPred.end()) return IntervalValue::top();
443 predicate = it->second;
444 }
445
446 // Now compute the constraint on LHS given: LHS <predicate> other
448 switch (predicate)
449 {
450 case CmpStmt::ICMP_EQ:
454 break;
455 case CmpStmt::ICMP_NE:
460 return IntervalValue::top(); // no useful narrowing
466 break;
472 break;
478 break;
484 break;
485 default:
486 return IntervalValue::top();
487 }
488 return result;
489}
@ ICMP_SGT
signed greater than
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ ICMP_UGE
unsigned greater or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ ICMP_NE
not equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_ULT
unsigned less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_SLE
signed less or equal
void meet_with(const IntervalValue &other)
Return a intersected IntervalValue.
static BoundedInt minus_infinity()
Get minus infinity -inf.
static BoundedInt plus_infinity()
Get plus infinity +inf.
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ findBackingLoad()

static const LoadStmt * findBackingLoad ( const SVFVar var)
static

Given a cmp operand, walk its SSA def edge to find the LoadStmt that produced it. This lets us trace back to the ObjVar in memory so that branch narrowing can refine the stored value.

Example: for cmp = icmp sgt a, 5 where a = load i32, ptr p, calling findBackingLoad(a) returns the LoadStmt, and we can then narrow the ObjVar behind p.

Follows one level of CopyStmt (e.g., zext/sext) if the load is not directly on the cmp operand. Returns nullptr if no load is found.

Definition at line 345 of file AbstractInterpretation.cpp.

346{
347 if (var->getInEdges().empty())
348 return nullptr;
349 SVFStmt* inStmt = *var->getInEdges().begin();
350 if (const LoadStmt* ls = SVFUtil::dyn_cast<LoadStmt>(inStmt))
351 return ls;
352 if (const CopyStmt* cs = SVFUtil::dyn_cast<CopyStmt>(inStmt))
353 {
354 const SVFVar* src = cs->getRHSVar();
355 if (!src->getInEdges().empty())
356 return SVFUtil::dyn_cast<LoadStmt>(*src->getInEdges().begin());
357 }
358 return nullptr;
359}
const GEdgeSetTy & getInEdges() const