Static Value-Flow Analysis
Loading...
Searching...
No Matches
Functions
AbstractInterpretation.cpp File Reference
#include "AE/Svfexe/AbstractInterpretation.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 <deque>

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 isCmpBranchFeasible 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 310 of file AbstractInterpretation.cpp.

313{
314 // Normalize: always reason from the LHS perspective.
315 // If we are the RHS operand, swap the predicate direction.
316 if (!isLHS)
317 {
318 // a > b from b's perspective: b < a
319 static const Map<s32_t, s32_t> swapPred =
320 {
343 };
344 auto it = swapPred.find(predicate);
345 if (it == swapPred.end()) return IntervalValue::top();
346 predicate = it->second;
347 }
348
349 // If false branch, negate the predicate.
350 if (succ == 0)
351 {
352 static const Map<s32_t, s32_t> negPred =
353 {
376 };
377 auto it = negPred.find(predicate);
378 if (it == negPred.end()) return IntervalValue::top();
379 predicate = it->second;
380 }
381
382 // Now compute the constraint on LHS given: LHS <predicate> other
384 switch (predicate)
385 {
386 case CmpStmt::ICMP_EQ:
390 break;
391 case CmpStmt::ICMP_NE:
396 return IntervalValue::top(); // no useful narrowing
402 break;
408 break;
414 break;
420 break;
421 default:
422 return IntervalValue::top();
423 }
424 return result;
425}
@ 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 281 of file AbstractInterpretation.cpp.

282{
283 if (var->getInEdges().empty())
284 return nullptr;
285 SVFStmt* inStmt = *var->getInEdges().begin();
286 if (const LoadStmt* ls = SVFUtil::dyn_cast<LoadStmt>(inStmt))
287 return ls;
288 if (const CopyStmt* cs = SVFUtil::dyn_cast<CopyStmt>(inStmt))
289 {
290 const SVFVar* src = cs->getRHSVar();
291 if (!src->getInEdges().empty())
292 return SVFUtil::dyn_cast<LoadStmt>(*src->getInEdges().begin());
293 }
294 return nullptr;
295}
const GEdgeSetTy & getInEdges() const