From: Nikita Popov Date: Tue, 4 Jun 2019 16:24:09 +0000 (+0000) Subject: [LVI][CVP] Add support for urem, srem and sdiv X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b2b5f09bd30407b1fdd49dc9db283d603e1f153c;p=llvm [LVI][CVP] Add support for urem, srem and sdiv The underlying ConstantRange functionality has been added in D60952, D61207 and D61238, this just exposes it for LVI. I'm switching the code from using a whitelist to a blacklist, as we're down to one unsupported operation here (xor) and writing it this way seems more obvious :) Differential Revision: https://reviews.llvm.org/D62822 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362519 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 280dd3ea604..53e9f49a571 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -1082,31 +1082,18 @@ bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV, assert(BO->getOperand(0)->getType()->isSized() && "all operands to binary operators are sized"); - - // Filter out operators we don't know how to reason about before attempting to - // recurse on our operand(s). This can cut a long search short if we know - // we're not going to be able to get any useful information anyways. - switch (BO->getOpcode()) { - case Instruction::Add: - case Instruction::Sub: - case Instruction::Mul: - case Instruction::UDiv: - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: - case Instruction::And: - case Instruction::Or: - return solveBlockValueBinaryOpImpl(BBLV, BO, BB, - [BO](const ConstantRange &CR1, const ConstantRange &CR2) { - return CR1.binaryOp(BO->getOpcode(), CR2); - }); - default: - // Unhandled instructions are overdefined. + if (BO->getOpcode() == Instruction::Xor) { + // Xor is the only operation not supported by ConstantRange::binaryOp(). LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined (unknown binary operator).\n"); BBLV = ValueLatticeElement::getOverdefined(); return true; - }; + } + + return solveBlockValueBinaryOpImpl(BBLV, BO, BB, + [BO](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.binaryOp(BO->getOpcode(), CR2); + }); } bool LazyValueInfoImpl::solveBlockValueOverflowIntrinsic( diff --git a/test/Transforms/CorrelatedValuePropagation/basic.ll b/test/Transforms/CorrelatedValuePropagation/basic.ll index a063d0cf5bd..630cfcb6bc1 100644 --- a/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -931,7 +931,7 @@ define i1 @urem_unknown(i32 %a) { ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[UREM]], 30 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; entry: %urem = urem i32 %a, 30 @@ -949,9 +949,9 @@ define i1 @srem_unknown(i32 %a) { ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[SREM]], -30 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: -; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK-NEXT: ret i1 true ; CHECK: exit2: -; CHECK-NEXT: ret i1 [[CMP2]] +; CHECK-NEXT: ret i1 true ; entry: %srem = srem i32 %a, 30 @@ -972,9 +972,9 @@ define i1 @sdiv_unknown(i32 %a) { ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[SREM]], -17459217 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: -; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK-NEXT: ret i1 true ; CHECK: exit2: -; CHECK-NEXT: ret i1 [[CMP2]] +; CHECK-NEXT: ret i1 true ; entry: %srem = sdiv i32 %a, 123