bool taintStoreAddress(StoreInst* SI, Value* DepVal,
const char* calling_func = __builtin_FUNCTION()) {
DEBUG(dbgs() << "Called from " << calling_func << '\n');
+ // Set the insertion point right after the 'DepVal'.
+ Instruction* Inst = nullptr;
IRBuilder<true, NoFolder> Builder(SI);
BasicBlock* BB = SI->getParent();
Value* Address = SI->getPointerOperand();
auto BE = BB->end();
auto BBI = BasicBlock::iterator(LI);
BBI++;
- while (true) {
- for (; BBI != BE; BBI++) {
- auto* Inst = dyn_cast<Instruction>(&*BBI);
- if (Inst == nullptr) {
- continue;
- }
- if (Inst->getOpcode() == Instruction::Store) {
+ for (; BBI != BE; BBI++) {
+ auto* Inst = dyn_cast<Instruction>(&*BBI);
+ if (Inst == nullptr) {
+ continue;
+ }
+ if (Inst->getOpcode() == Instruction::Store) {
+ return Inst;
+ } else if (Inst->getOpcode() == Instruction::Br) {
+ auto* BrInst = dyn_cast<BranchInst>(Inst);
+ if (BrInst->isConditional()) {
return Inst;
- } else if (Inst->getOpcode() == Instruction::Br) {
- auto* BrInst = dyn_cast<BranchInst>(Inst);
- if (BrInst->isConditional()) {
- return Inst;
- } else {
- // Reinitialize iterators with the destination of the unconditional
- // branch.
- BB = BrInst->getSuccessor(0);
- BBI = BB->begin();
- BE = BB->end();
- break;
- }
+ } else {
+ return nullptr;
}
}
- if (BBI == BE) {
- return nullptr;
- }
}
+ return nullptr;
}
// XXX-comment: Returns whether the code has been changed.
// Returns true if the code is changed, and false otherwise.
void TaintRelaxedLoads(LoadInst* LI) {
- IRBuilder<true, NoFolder> Builder(LI->getNextNode());
+ // For better performance, we can add a "AND X 0" instruction before the
+ // condition.
+ auto* FirstInst = findFirstStoreCondBranchInst(LI);
+ Instruction* InsertPoint = nullptr;
+ if (FirstInst == nullptr) {
+ InsertPoint = LI->getParent()->getTerminator();
+ InsertPoint = LI->getNextNode();
+ } else {
+ InsertPoint = LI->getNextNode();
+ }
+ IRBuilder<true, NoFolder> Builder(InsertPoint);
+ auto* AndZero = dyn_cast<Instruction>(
+ Builder.CreateAnd(LI, Constant::getNullValue(LI->getType())));
auto* FakeCondition = dyn_cast<Instruction>(Builder.CreateICmp(
- CmpInst::ICMP_EQ, LI, Constant::getNullValue(LI->getType())));
+ CmpInst::ICMP_NE, AndZero, Constant::getNullValue(LI->getType())));
AddFakeConditionalBranch(FakeCondition->getNextNode(), FakeCondition);
}
if (StoreAddressDependOnValue(dyn_cast<StoreInst>(FirstInst), LI)) {
continue;
}
- } else if (FirstInst->getOpcode() == Instruction::Br) {
+ } else if (FirstInst->getOpcode() == Instruction::Br &&
+ isa<BranchInst>(FirstInst)) {
if (ConditionalBranchDependsOnValue(dyn_cast<BranchInst>(FirstInst),
LI)) {
continue;
}
// We really need to process the relaxed load now.
- TaintRelaxedLoads(LI);
- Changed = true;
+ StoreInst* SI = nullptr;;
+ if (FirstInst && (SI = dyn_cast<StoreInst>(FirstInst))) {
+ // For immediately coming stores, taint the address of the store.
+ taintStoreAddress(SI, LI);
+ } else {
+ // For immediately coming branch, directly add a fake branch.
+ TaintRelaxedLoads(LI);
+ Changed = true;
+ }
}
return Changed;
}