3030#include " llvm/IR/InstrTypes.h"
3131#include " llvm/IR/Instruction.h"
3232#include " llvm/IR/Instructions.h"
33+ #include " llvm/IR/IntrinsicInst.h"
3334#include " llvm/IR/LLVMContext.h"
3435#include " llvm/IR/Type.h"
3536#include " llvm/IR/Value.h"
@@ -296,20 +297,25 @@ IDELinearConstantAnalysis::getNormalFlowFunction(n_t Curr, n_t /*Succ*/) {
296297 d_t ValueOp = Store->getValueOperand ();
297298 // Case I: Storing a constant integer.
298299 if (llvm::isa<llvm::ConstantInt>(ValueOp)) {
299- // return Identity<d_t>::getInstance();
300- return strongUpdateStore (Store, [](d_t Source) {
301- return LLVMZeroValue::isLLVMZeroValue (Source);
302- });
300+ return strongUpdateStore (Store, LLVMZeroValue::isLLVMZeroValue);
303301 }
302+
304303 // Case II: Storing an integer typed value.
305304 if (ValueOp->getType ()->isIntegerTy ()) {
306305 return strongUpdateStore (Store);
307306 }
308307 }
308+
309+ if (const auto *GEP = llvm::dyn_cast<llvm::GetElementPtrInst>(Curr)) {
310+ if (GEP->getResultElementType ()->isIntegerTy ()) {
311+ const auto *Op = GEP->getPointerOperand ();
312+ return generateFlow (GEP, Op);
313+ }
314+ }
309315 // check load instructions
310316 if (const auto *Load = llvm::dyn_cast<llvm::LoadInst>(Curr)) {
311317 // only consider i32 load
312- if (Load->getPointerOperandType ()-> getPointerElementType ()->isIntegerTy ()) {
318+ if (Load->getType ()->isIntegerTy ()) {
313319 return generateFlowIf<d_t >(Load, [Load](d_t Source) {
314320 return Source == Load->getPointerOperand ();
315321 });
@@ -327,6 +333,21 @@ IDELinearConstantAnalysis::getNormalFlowFunction(n_t Curr, n_t /*Succ*/) {
327333 llvm::isa<llvm::ConstantInt>(Rop));
328334 });
329335 }
336+
337+ if (const auto *Extract = llvm::dyn_cast<llvm::ExtractValueInst>(Curr)) {
338+ const auto *Agg = Extract->getAggregateOperand ();
339+
340+ // / We are extracting the result of a BinaryOpIntrinsic
341+ // / The first parameter holds the resulting integer if
342+ // / no error occured during the operation
343+ if (const auto *BinIntrinsic =
344+ llvm::dyn_cast<llvm::BinaryOpIntrinsic>(Agg)) {
345+ if (Extract->getType ()->isIntegerTy ()) {
346+ return generateFlow<d_t >(Curr, Agg);
347+ }
348+ }
349+ }
350+
330351 return identityFlow<d_t >();
331352}
332353
@@ -417,6 +438,25 @@ IDELinearConstantAnalysis::initialSeeds() {
417438 return Seeds;
418439}
419440
441+ IDELinearConstantAnalysis::FlowFunctionPtrType
442+ IDELinearConstantAnalysis::getSummaryFlowFunction (n_t Curr, f_t /* CalleeFun*/ ) {
443+
444+ if (const auto *BinIntrinsic =
445+ llvm::dyn_cast<llvm::BinaryOpIntrinsic>(Curr)) {
446+ auto *Lop = BinIntrinsic->getLHS ();
447+ auto *Rop = BinIntrinsic->getRHS ();
448+
449+ return generateFlowIf<d_t >(BinIntrinsic, [this , Lop, Rop](d_t Source) {
450+ // / Intentionally include nonlinear operations here for being able to
451+ // / explicitly set them to BOTTOM in the edge function
452+ return (Lop == Source) || (Rop == Source) ||
453+ (isZeroValue (Source) && llvm::isa<llvm::ConstantInt>(Lop) &&
454+ llvm::isa<llvm::ConstantInt>(Rop));
455+ });
456+ }
457+ return nullptr ;
458+ }
459+
420460IDELinearConstantAnalysis::d_t
421461IDELinearConstantAnalysis::createZeroValue () const {
422462 // create a special value to represent the zero value!
@@ -538,6 +578,29 @@ IDELinearConstantAnalysis::getCallToRetEdgeFunction(
538578 return EdgeIdentity<l_t >::getInstance ();
539579}
540580
581+ std::shared_ptr<EdgeFunction<IDELinearConstantAnalysis::l_t >>
582+ IDELinearConstantAnalysis::getSummaryEdgeFunction (n_t Curr, d_t CurrNode,
583+ n_t /* Succ*/ , d_t SuccNode) {
584+
585+ if (const auto *BinIntrinsic =
586+ llvm::dyn_cast<llvm::BinaryOpIntrinsic>(Curr)) {
587+ auto *Lop = BinIntrinsic->getLHS ();
588+ auto *Rop = BinIntrinsic->getRHS ();
589+ unsigned OP = BinIntrinsic->getBinaryOp ();
590+
591+ // For non linear constant computation we propagate bottom
592+ if ((CurrNode == Lop && !llvm::isa<llvm::ConstantInt>(Rop)) ||
593+ (CurrNode == Rop && !llvm::isa<llvm::ConstantInt>(Lop))) {
594+ return AllBottom<l_t >::getInstance ();
595+ }
596+
597+ if (Curr == SuccNode && CurrNode != SuccNode) {
598+ return std::make_shared<lca::BinOp>(OP, Lop, Rop, CurrNode);
599+ }
600+ }
601+ return EdgeIdentity<l_t >::getInstance ();
602+ }
603+
541604std::shared_ptr<EdgeFunction<IDELinearConstantAnalysis::l_t >>
542605IDELinearConstantAnalysis::allTopFunction () {
543606 return std::make_shared<AllTop<l_t >>();
@@ -709,13 +772,7 @@ IDELinearConstantAnalysis::getLCAResults(SolverResults<n_t, d_t, l_t> SR) {
709772 return AggResults;
710773}
711774
712- void IDELinearConstantAnalysis::LCAResult::print (llvm::raw_ostream &OS) {
713- OS << this ;
714- }
715-
716- IDELinearConstantAnalysis::LCAResult::operator std::string () const {
717- std::string Buffer;
718- llvm::raw_string_ostream OS (Buffer);
775+ void IDELinearConstantAnalysis::LCAResult::print (llvm::raw_ostream &OS) const {
719776 OS << " Line " << LineNr << " : " << SrcNode << ' \n ' ;
720777 OS << " Var(s): " ;
721778 for (auto It = VariableToValue.begin (); It != VariableToValue.end (); ++It) {
@@ -728,7 +785,6 @@ IDELinearConstantAnalysis::LCAResult::operator std::string() const {
728785 for (const auto *Ir : IRTrace) {
729786 OS << " " << llvmIRToString (Ir) << ' \n ' ;
730787 }
731- return Buffer;
732788}
733789
734790} // namespace psr
0 commit comments