[NFC][CVP] Count all the no-wraps we proved

Summary:
It looks like this is the only missing statistic in the CVP pass.
Since we prove NSW and NUW separately i'd think we should count them separately too.

Reviewers: nikic, spatel, reames

Reviewed By: spatel

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68740

llvm-svn: 375230
This commit is contained in:
Roman Lebedev 2019-10-18 13:20:16 +00:00
parent ffcd7698ae
commit fa0ac2558e
1 changed files with 74 additions and 20 deletions

View File

@ -64,6 +64,18 @@ STATISTIC(NumAShrs, "Number of ashr converted to lshr");
STATISTIC(NumSRems, "Number of srem converted to urem");
STATISTIC(NumSExt, "Number of sext converted to zext");
STATISTIC(NumAnd, "Number of ands removed");
STATISTIC(NumNW, "Number of no-wrap deductions");
STATISTIC(NumNSW, "Number of no-signed-wrap deductions");
STATISTIC(NumNUW, "Number of no-unsigned-wrap deductions");
STATISTIC(NumAddNW, "Number of no-wrap deductions for add");
STATISTIC(NumAddNSW, "Number of no-signed-wrap deductions for add");
STATISTIC(NumAddNUW, "Number of no-unsigned-wrap deductions for add");
STATISTIC(NumSubNW, "Number of no-wrap deductions for sub");
STATISTIC(NumSubNSW, "Number of no-signed-wrap deductions for sub");
STATISTIC(NumSubNUW, "Number of no-unsigned-wrap deductions for sub");
STATISTIC(NumMulNW, "Number of no-wrap deductions for mul");
STATISTIC(NumMulNSW, "Number of no-signed-wrap deductions for mul");
STATISTIC(NumMulNUW, "Number of no-unsigned-wrap deductions for mul");
STATISTIC(NumOverflows, "Number of overflow checks removed");
STATISTIC(NumSaturating,
"Number of saturating arithmetics converted to normal arithmetics");
@ -419,18 +431,58 @@ static bool willNotOverflow(BinaryOpIntrinsic *BO, LazyValueInfo *LVI) {
return NWRegion.contains(LRange);
}
static void setDeducedOverflowingFlags(Value *V, Instruction::BinaryOps Opcode,
bool NewNSW, bool NewNUW) {
Statistic *OpcNW, *OpcNSW, *OpcNUW;
switch (Opcode) {
case Instruction::Add:
OpcNW = &NumAddNW;
OpcNSW = &NumAddNSW;
OpcNUW = &NumAddNUW;
break;
case Instruction::Sub:
OpcNW = &NumSubNW;
OpcNSW = &NumSubNSW;
OpcNUW = &NumSubNUW;
break;
case Instruction::Mul:
OpcNW = &NumMulNW;
OpcNSW = &NumMulNSW;
OpcNUW = &NumMulNUW;
break;
default:
llvm_unreachable("Will not be called with other binops");
}
auto *Inst = dyn_cast<Instruction>(V);
if (NewNSW) {
++NumNW;
++OpcNW;
++NumNSW;
++OpcNSW;
if (Inst)
Inst->setHasNoSignedWrap();
}
if (NewNUW) {
++NumNW;
++OpcNW;
++NumNUW;
++OpcNUW;
if (Inst)
Inst->setHasNoUnsignedWrap();
}
}
// Rewrite this with.overflow intrinsic as non-overflowing.
static void processOverflowIntrinsic(WithOverflowInst *WO) {
IRBuilder<> B(WO);
Value *NewOp = B.CreateBinOp(
WO->getBinaryOp(), WO->getLHS(), WO->getRHS(), WO->getName());
// Constant-folding could have happened.
if (auto *Inst = dyn_cast<Instruction>(NewOp)) {
if (WO->isSigned())
Inst->setHasNoSignedWrap();
else
Inst->setHasNoUnsignedWrap();
}
Instruction::BinaryOps Opcode = WO->getBinaryOp();
bool NSW = WO->isSigned();
bool NUW = !WO->isSigned();
Value *NewOp =
B.CreateBinOp(Opcode, WO->getLHS(), WO->getRHS(), WO->getName());
setDeducedOverflowingFlags(NewOp, Opcode, NSW, NUW);
StructType *ST = cast<StructType>(WO->getType());
Constant *Struct = ConstantStruct::get(ST,
@ -443,13 +495,13 @@ static void processOverflowIntrinsic(WithOverflowInst *WO) {
}
static void processSaturatingInst(SaturatingInst *SI) {
Instruction::BinaryOps Opcode = SI->getBinaryOp();
bool NSW = SI->isSigned();
bool NUW = !SI->isSigned();
BinaryOperator *BinOp = BinaryOperator::Create(
SI->getBinaryOp(), SI->getLHS(), SI->getRHS(), SI->getName(), SI);
Opcode, SI->getLHS(), SI->getRHS(), SI->getName(), SI);
BinOp->setDebugLoc(SI->getDebugLoc());
if (SI->isSigned())
BinOp->setHasNoSignedWrap();
else
BinOp->setHasNoUnsignedWrap();
setDeducedOverflowingFlags(BinOp, Opcode, NSW, NUW);
SI->replaceAllUsesWith(BinOp);
SI->eraseFromParent();
@ -676,6 +728,7 @@ static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) {
BasicBlock *BB = BinOp->getParent();
Instruction::BinaryOps Opcode = BinOp->getOpcode();
Value *LHS = BinOp->getOperand(0);
Value *RHS = BinOp->getOperand(1);
@ -683,21 +736,22 @@ static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) {
ConstantRange RRange = LVI->getConstantRange(RHS, BB, BinOp);
bool Changed = false;
bool NewNUW = false, NewNSW = false;
if (!NUW) {
ConstantRange NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
BinOp->getOpcode(), RRange, OBO::NoUnsignedWrap);
bool NewNUW = NUWRange.contains(LRange);
BinOp->setHasNoUnsignedWrap(NewNUW);
Opcode, RRange, OBO::NoUnsignedWrap);
NewNUW = NUWRange.contains(LRange);
Changed |= NewNUW;
}
if (!NSW) {
ConstantRange NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(
BinOp->getOpcode(), RRange, OBO::NoSignedWrap);
bool NewNSW = NSWRange.contains(LRange);
BinOp->setHasNoSignedWrap(NewNSW);
Opcode, RRange, OBO::NoSignedWrap);
NewNSW = NSWRange.contains(LRange);
Changed |= NewNSW;
}
setDeducedOverflowingFlags(BinOp, Opcode, NewNSW, NewNUW);
return Changed;
}