Skip to content

Commit

Permalink
llvm-slicer-crit: improve the precision of matching without PTA
Browse files Browse the repository at this point in the history
We can handle also constant expressions and global variables.
  • Loading branch information
mchalupa committed Dec 13, 2022
1 parent c0224b5 commit d6ef356
Showing 1 changed file with 47 additions and 4 deletions.
51 changes: 47 additions & 4 deletions tools/llvm-slicer-crit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,49 @@ static inline bool isNumber(const std::string &s) {
}

static inline bool mayBeTheVar(const llvm::Value *val, const std::string &var) {
// global variables have names, just compare it
if (auto *G = llvm::dyn_cast<llvm::GlobalVariable>(val)) {
return G->getName() == var;
}

// for other cases, we must relay on the information about allocas
auto name = valuesToVariables.find(val);
if (name != valuesToVariables.end() && name->second != var) {
return false;
}

// either the var matches or we do not know the var,
// which we must take as a match
return true;
}

static llvm::Value *constExprVar(const llvm::ConstantExpr *CE) {
using namespace llvm;
Value *var = nullptr;
Instruction *Inst = CE->getAsInstruction();

switch (Inst->getOpcode()) {
case Instruction::GetElementPtr:
var = cast<GetElementPtrInst>(Inst)->getPointerOperand();
break;
case Instruction::BitCast:
var = Inst->getOperand(0);
break;
default:
break;
}

#if LLVM_VERSION_MAJOR < 5
delete Inst;
#else
Inst->deleteValue();
#endif

if (var && isa<ConstantExpr>(var))
var = constExprVar(cast<ConstantExpr>(var));
return var;
}

static bool usesTheVariable(const llvm::Instruction &I, const std::string &var,
bool isglobal = false,
LLVMPointerAnalysis *pta = nullptr) {
Expand All @@ -56,17 +90,26 @@ static bool usesTheVariable(const llvm::Instruction &I, const std::string &var,
if (!pta) {
// try basic cases that we can decide without PTA
using namespace llvm;
const Value *operand = nullptr;
if (auto *S = dyn_cast<StoreInst>(&I)) {
auto *A = S->getPointerOperand()->stripPointerCasts();
if (isa<AllocaInst>(A) && !mayBeTheVar(A, var)) {
return false;
if (auto *C = dyn_cast<ConstantExpr>(A)) {
operand = constExprVar(C);
} else if ((isa<AllocaInst>(A) || isa<GlobalVariable>(A))) {
operand = A;
}
} else if (auto *L = dyn_cast<LoadInst>(&I)) {
auto *A = L->getPointerOperand()->stripPointerCasts();
if (isa<AllocaInst>(A) && !mayBeTheVar(A, var)) {
return false;
if (auto *C = dyn_cast<ConstantExpr>(A)) {
operand = constExprVar(C);
} else if ((isa<AllocaInst>(A) || isa<GlobalVariable>(A))) {
operand = A;
}
}

if (operand && !mayBeTheVar(operand, var)) {
return false;
}
return true;
}

Expand Down

0 comments on commit d6ef356

Please sign in to comment.