Skip to content

Commit

Permalink
Remove icmp BPF builtin
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte committed Apr 2, 2024
1 parent 3f884d3 commit a54ce2b
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 281 deletions.
64 changes: 1 addition & 63 deletions llvm/lib/Target/SBF/SBFAdjustOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
#include "SBFTargetMachine.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsBPF.h" // TODO: jle.
#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"

#define DEBUG_TYPE "sbf-adjust-opt"
Expand Down Expand Up @@ -59,7 +57,6 @@ class SBFAdjustOptImpl {
Module *M;
SmallVector<PassThroughInfo, 16> PassThroughs;

bool adjustICmpToBuiltin();
void adjustBasicBlock(BasicBlock &BB);
bool serializeICMPCrossBB(BasicBlock &BB);
void adjustInst(Instruction &I);
Expand All @@ -71,72 +68,13 @@ class SBFAdjustOptImpl {
} // End anonymous namespace

bool SBFAdjustOptImpl::run() {
bool Changed = adjustICmpToBuiltin();

for (Function &F : *M)
for (auto &BB : F) {
adjustBasicBlock(BB);
for (auto &I : BB)
adjustInst(I);
}
return insertPassThrough() || Changed;
}

// Commit acabad9ff6bf ("[InstCombine] try to canonicalize icmp with
// trunc op into mask and cmp") added a transformation to
// convert "(conv)a < power_2_const" to "a & <const>" in certain
// cases and bpf kernel verifier has to handle the resulted code
// conservatively and this may reject otherwise legitimate program.
// Here, we change related icmp code to a builtin which will
// be restored to original icmp code later to prevent that
// InstCombine transformatin.
bool SBFAdjustOptImpl::adjustICmpToBuiltin() {
bool Changed = false;
ICmpInst *ToBeDeleted = nullptr;
for (Function &F : *M)
for (auto &BB : F)
for (auto &I : BB) {
if (ToBeDeleted) {
ToBeDeleted->eraseFromParent();
ToBeDeleted = nullptr;
}

auto *Icmp = dyn_cast<ICmpInst>(&I);
if (!Icmp)
continue;

Value *Op0 = Icmp->getOperand(0);
if (!isa<TruncInst>(Op0))
continue;

auto ConstOp1 = dyn_cast<ConstantInt>(Icmp->getOperand(1));
if (!ConstOp1)
continue;

auto ConstOp1Val = ConstOp1->getValue().getZExtValue();
auto Op = Icmp->getPredicate();
if (Op == ICmpInst::ICMP_ULT || Op == ICmpInst::ICMP_UGE) {
if ((ConstOp1Val - 1) & ConstOp1Val)
continue;
} else if (Op == ICmpInst::ICMP_ULE || Op == ICmpInst::ICMP_UGT) {
if (ConstOp1Val & (ConstOp1Val + 1))
continue;
} else {
continue;
}

Constant *Opcode =
ConstantInt::get(Type::getInt32Ty(BB.getContext()), Op);
Function *Fn = Intrinsic::getDeclaration(
M, Intrinsic::bpf_compare, {Op0->getType(), ConstOp1->getType()});
auto *NewInst = CallInst::Create(Fn, {Opcode, Op0, ConstOp1});
NewInst->insertBefore(&I);
Icmp->replaceAllUsesWith(NewInst);
Changed = true;
ToBeDeleted = Icmp;
}

return Changed;
return insertPassThrough();
}

bool SBFAdjustOptImpl::insertPassThrough() {
Expand Down
49 changes: 1 addition & 48 deletions llvm/lib/Target/SBF/SBFCheckAndAdjustIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,10 @@
#include "SBFTargetMachine.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"

#define DEBUG_TYPE "sbf-check-and-opt-ir"

Expand All @@ -46,7 +42,6 @@ class SBFCheckAndAdjustIR final : public ModulePass {
void checkIR(Module &M);
bool adjustIR(Module &M);
bool removePassThroughBuiltin(Module &M);
bool removeCompareBuiltin(Module &M);
};
} // End anonymous namespace

Expand Down Expand Up @@ -121,50 +116,8 @@ bool SBFCheckAndAdjustIR::removePassThroughBuiltin(Module &M) {
return Changed;
}

bool SBFCheckAndAdjustIR::removeCompareBuiltin(Module &M) {
// Remove __builtin_bpf_compare()'s which are used to prevent
// certain IR optimizations. Now major IR optimizations are done,
// remove them.
bool Changed = false;
CallInst *ToBeDeleted = nullptr;
for (Function &F : M)
for (auto &BB : F)
for (auto &I : BB) {
if (ToBeDeleted) {
ToBeDeleted->eraseFromParent();
ToBeDeleted = nullptr;
}

auto *Call = dyn_cast<CallInst>(&I);
if (!Call)
continue;
auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
if (!GV)
continue;
if (!GV->getName().startswith("llvm.bpf.compare"))
continue;

Changed = true;
Value *Arg0 = Call->getArgOperand(0);
Value *Arg1 = Call->getArgOperand(1);
Value *Arg2 = Call->getArgOperand(2);

auto OpVal = cast<ConstantInt>(Arg0)->getValue().getZExtValue();
CmpInst::Predicate Opcode = (CmpInst::Predicate)OpVal;

auto *ICmp = new ICmpInst(Opcode, Arg1, Arg2);
ICmp->insertBefore(Call);

Call->replaceAllUsesWith(ICmp);
ToBeDeleted = Call;
}
return Changed;
}

bool SBFCheckAndAdjustIR::adjustIR(Module &M) {
bool Changed = removePassThroughBuiltin(M);
Changed = removeCompareBuiltin(M) || Changed;
return Changed;
return removePassThroughBuiltin(M);
}

bool SBFCheckAndAdjustIR::runOnModule(Module &M) {
Expand Down
85 changes: 0 additions & 85 deletions llvm/test/CodeGen/SBF/adjust-opt-icmp3.ll

This file was deleted.

85 changes: 0 additions & 85 deletions llvm/test/CodeGen/SBF/adjust-opt-icmp4.ll

This file was deleted.

0 comments on commit a54ce2b

Please sign in to comment.