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 <deque>
#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 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 335 of file AbstractInterpretation.cpp.

338{
339 // Normalize: always reason from the LHS perspective.
340 // If we are the RHS operand, swap the predicate direction.
341 if (!isLHS)
342 {
343 // a > b from b's perspective: b < a
344 static const Map<s32_t, s32_t> swapPred =
345 {
368 };
369 auto it = swapPred.find(predicate);
370 if (it == swapPred.end()) return IntervalValue::top();
371 predicate = it->second;
372 }
373
374 // If false branch, negate the predicate.
375 if (succ == 0)
376 {
377 static const Map<s32_t, s32_t> negPred =
378 {
401 };
402 auto it = negPred.find(predicate);
403 if (it == negPred.end()) return IntervalValue::top();
404 predicate = it->second;
405 }
406
407 // Now compute the constraint on LHS given: LHS <predicate> other
409 switch (predicate)
410 {
411 case CmpStmt::ICMP_EQ:
415 break;
416 case CmpStmt::ICMP_NE:
421 return IntervalValue::top(); // no useful narrowing
427 break;
433 break;
439 break;
445 break;
446 default:
447 return IntervalValue::top();
448 }
449 return result;
450}
@ 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 306 of file AbstractInterpretation.cpp.

307{
308 if (var->getInEdges().empty())
309 return nullptr;
310 SVFStmt* inStmt = *var->getInEdges().begin();
311 if (const LoadStmt* ls = SVFUtil::dyn_cast<LoadStmt>(inStmt))
312 return ls;
313 if (const CopyStmt* cs = SVFUtil::dyn_cast<CopyStmt>(inStmt))
314 {
315 const SVFVar* src = cs->getRHSVar();
316 if (!src->getInEdges().empty())
317 return SVFUtil::dyn_cast<LoadStmt>(*src->getInEdges().begin());
318 }
319 return nullptr;
320}
const GEdgeSetTy & getInEdges() const