From 8429c35f2efa87dd516eef0fa25bf72cb8b64364 Mon Sep 17 00:00:00 2001 From: Valentina Sona Date: Wed, 19 Apr 2023 22:27:30 +0200 Subject: [PATCH] Insert boolean not on equal to zero comparisons Implements the transformation (x == 0) -> (!x) via the boolean not opcode, inside the two's complement arithmetic normalization pass. --- ...sComplementArithmeticNormalizationPass.cpp | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/IRCanonicalization/TwosComplementArithmeticNormalizationPass.cpp b/lib/IRCanonicalization/TwosComplementArithmeticNormalizationPass.cpp index 8b9b6c405..930a2cf85 100644 --- a/lib/IRCanonicalization/TwosComplementArithmeticNormalizationPass.cpp +++ b/lib/IRCanonicalization/TwosComplementArithmeticNormalizationPass.cpp @@ -74,6 +74,29 @@ public: } }; +class BooleanNotBuilder { + + OpaqueFunctionsPool Pool; + llvm::IRBuilder<> Builder; + +public: + BooleanNotBuilder(llvm::Function &F) : + Pool(F.getParent(), false), Builder(F.getContext()) { + initBooleanNotPool(Pool); + } + + void SetInsertPoint(llvm::Instruction *I) { Builder.SetInsertPoint(I); } + + llvm::CallInst *operator()(llvm::Type *IntType, llvm::Value *Val) { + revng_assert(isa(IntType)); + llvm::Function *Func = Pool.get(IntType, + Builder.getIntNTy(1), + IntType, + "boolean_not"); + return Builder.CreateCall(Func, { Val }); + } +}; + using Predicate = llvm::ICmpInst::Predicate; static bool isGreater(Predicate P) { @@ -86,6 +109,7 @@ bool TANP::runOnFunction(llvm::Function &F) { UnaryMinusBuilder BuildUnaryMinus{ F }; BinaryNotBuilder BuildBinaryNot{ F }; + BooleanNotBuilder BuildBooleanNot{ F }; llvm::IRBuilder<> Builder{ F.getContext() }; bool Changed = false; @@ -179,7 +203,6 @@ bool TANP::runOnFunction(llvm::Function &F) { } else if (Predicate Pred; match(&I, m_ICmp(Pred, m_Value(Val), m_APInt(Int)))) { - const auto IntType = Val->getType(); llvm::Value *Unknown = nullptr; @@ -243,12 +266,14 @@ bool TANP::runOnFunction(llvm::Function &F) { else NewV = Builder.CreateAnd(NewV, WrappingComparison); } - } else if (Int->isSignBitSet() - and Int->isSignedIntN(IntType->getIntegerBitWidth())) { + } else if (Int->isNegative()) { BuildUnaryMinus.SetInsertPoint(&I); auto UnaryMinus = BuildUnaryMinus(IntType, *Int); Builder.SetInsertPoint(UnaryMinus->getNextNonDebugInstruction()); NewV = Builder.CreateICmp(Pred, Val, UnaryMinus); + } else if (Pred == Predicate::ICMP_EQ and Int->isNullValue()) { + BuildBooleanNot.SetInsertPoint(&I); + NewV = BuildBooleanNot(Val->getType(), Val); } }