[IRBuilder] Introduce helpers for and/or of multiple values at once

We had versions of this code scattered around, so consolidate into one location.

Not strictly NFC since the order of intermediate results may change in some places, but since these operations are associatives, should not change results.

llvm-svn: 365259
This commit is contained in:
Philip Reames 2019-07-06 03:46:18 +00:00
parent 82b078300a
commit 9a2f14b656
4 changed files with 26 additions and 25 deletions

View File

@ -1214,6 +1214,14 @@ public:
return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name); return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
} }
Value *CreateAnd(ArrayRef<Value*> Ops) {
assert(!Ops.empty());
Value *Accum = Ops[0];
for (unsigned i = 1; i < Ops.size(); i++)
Accum = CreateAnd(Accum, Ops[i]);
return Accum;
}
Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
if (auto *RC = dyn_cast<Constant>(RHS)) { if (auto *RC = dyn_cast<Constant>(RHS)) {
if (RC->isNullValue()) if (RC->isNullValue())
@ -1232,6 +1240,14 @@ public:
return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name); return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
} }
Value *CreateOr(ArrayRef<Value*> Ops) {
assert(!Ops.empty());
Value *Accum = Ops[0];
for (unsigned i = 1; i < Ops.size(); i++)
Accum = CreateOr(Accum, Ops[i]);
return Accum;
}
Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Value *V = foldConstant(Instruction::Xor, LHS, RHS, Name)) return V; if (Value *V = foldConstant(Instruction::Xor, LHS, RHS, Name)) return V;
return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);

View File

@ -1943,7 +1943,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Value *S1S2 = IRB.CreateAnd(S1, S2); Value *S1S2 = IRB.CreateAnd(S1, S2);
Value *V1S2 = IRB.CreateAnd(V1, S2); Value *V1S2 = IRB.CreateAnd(V1, S2);
Value *S1V2 = IRB.CreateAnd(S1, V2); Value *S1V2 = IRB.CreateAnd(S1, V2);
setShadow(&I, IRB.CreateOr(S1S2, IRB.CreateOr(V1S2, S1V2))); setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
setOriginForNaryOp(I); setOriginForNaryOp(I);
} }
@ -1965,7 +1965,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Value *S1S2 = IRB.CreateAnd(S1, S2); Value *S1S2 = IRB.CreateAnd(S1, S2);
Value *V1S2 = IRB.CreateAnd(V1, S2); Value *V1S2 = IRB.CreateAnd(V1, S2);
Value *S1V2 = IRB.CreateAnd(S1, V2); Value *S1V2 = IRB.CreateAnd(S1, V2);
setShadow(&I, IRB.CreateOr(S1S2, IRB.CreateOr(V1S2, S1V2))); setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
setOriginForNaryOp(I); setOriginForNaryOp(I);
} }
@ -3508,7 +3508,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
D = CreateAppToShadowCast(IRB, D); D = CreateAppToShadowCast(IRB, D);
// Result shadow if condition shadow is 1. // Result shadow if condition shadow is 1.
Sa1 = IRB.CreateOr(IRB.CreateXor(C, D), IRB.CreateOr(Sc, Sd)); Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
} }
Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select"); Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
setShadow(&I, Sa); setShadow(&I, Sa);

View File

@ -793,14 +793,9 @@ bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,
// Emit the new guard condition // Emit the new guard condition
IRBuilder<> Builder(findInsertPt(Guard, Checks)); IRBuilder<> Builder(findInsertPt(Guard, Checks));
Value *LastCheck = nullptr; Value *AllChecks = Builder.CreateAnd(Checks);
for (auto *Check : Checks)
if (!LastCheck)
LastCheck = Check;
else
LastCheck = Builder.CreateAnd(LastCheck, Check);
auto *OldCond = Guard->getOperand(0); auto *OldCond = Guard->getOperand(0);
Guard->setOperand(0, LastCheck); Guard->setOperand(0, AllChecks);
RecursivelyDeleteTriviallyDeadInstructions(OldCond); RecursivelyDeleteTriviallyDeadInstructions(OldCond);
LLVM_DEBUG(dbgs() << "Widened checks = " << NumWidened << "\n"); LLVM_DEBUG(dbgs() << "Widened checks = " << NumWidened << "\n");
@ -824,14 +819,9 @@ bool LoopPredication::widenWidenableBranchGuardConditions(
// Emit the new guard condition // Emit the new guard condition
IRBuilder<> Builder(findInsertPt(BI, Checks)); IRBuilder<> Builder(findInsertPt(BI, Checks));
Value *LastCheck = nullptr; Value *AllChecks = Builder.CreateAnd(Checks);
for (auto *Check : Checks)
if (!LastCheck)
LastCheck = Check;
else
LastCheck = Builder.CreateAnd(LastCheck, Check);
auto *OldCond = BI->getCondition(); auto *OldCond = BI->getCondition();
BI->setCondition(LastCheck); BI->setCondition(AllChecks);
assert(isGuardAsWidenableBranch(BI) && assert(isGuardAsWidenableBranch(BI) &&
"Stopped being a guard after transform?"); "Stopped being a guard after transform?");
RecursivelyDeleteTriviallyDeadInstructions(OldCond); RecursivelyDeleteTriviallyDeadInstructions(OldCond);

View File

@ -180,14 +180,9 @@ static void buildPartialUnswitchConditionalBranch(BasicBlock &BB,
BasicBlock &UnswitchedSucc, BasicBlock &UnswitchedSucc,
BasicBlock &NormalSucc) { BasicBlock &NormalSucc) {
IRBuilder<> IRB(&BB); IRBuilder<> IRB(&BB);
Value *Cond = Invariants.front();
for (Value *Invariant : Value *Cond = Direction ? IRB.CreateOr(Invariants) :
make_range(std::next(Invariants.begin()), Invariants.end())) IRB.CreateAnd(Invariants);
if (Direction)
Cond = IRB.CreateOr(Cond, Invariant);
else
Cond = IRB.CreateAnd(Cond, Invariant);
IRB.CreateCondBr(Cond, Direction ? &UnswitchedSucc : &NormalSucc, IRB.CreateCondBr(Cond, Direction ? &UnswitchedSucc : &NormalSucc,
Direction ? &NormalSucc : &UnswitchedSucc); Direction ? &NormalSucc : &UnswitchedSucc);
} }