[llvm] r251606 - [LVI/CVP] Teach LVI about range metadata
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 28 21:36:58 PDT 2015
Already fixed in 251614
On 10/28/2015 09:32 PM, Sanjoy Das wrote:
> Looks like this broke some bots:
> http://lab.llvm.org:8011/builders/lld-x86_64-darwin13/builds/16233
>
> Philip Reames via llvm-commits wrote:
>> Author: reames
>> Date: Wed Oct 28 22:57:17 2015
>> New Revision: 251606
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=251606&view=rev
>> Log:
>> [LVI/CVP] Teach LVI about range metadata
>>
>> Somewhat shockingly for an analysis pass which is computing constant
>> ranges, LVI did not understand the ranges provided by range metadata.
>>
>> As part of this change, I included a change to CVP primarily because
>> doing so made it much easier to write small self contained test
>> cases. CVP was previously only handling the non-local operand case,
>> but given that LVI can sometimes figure out information about
>> instructions standalone, I don't see any reason to restrict this.
>> There could possibly be a compile time impact from this, but I
>> suspect it should be minimal. If anyone has an example which
>> substaintially regresses, please let me know. I could restrict the
>> block local handling to ICmps feeding Terminator instructions if needed.
>>
>> Note that this patch continues a somewhat bad practice in LVI. In
>> many cases, we know facts about values, and separate context
>> sensitive facts about values. LVI makes no effort to distinguish and
>> will frequently cache the same value fact repeatedly for different
>> contexts. I would like to change this, but that's a large enough
>> change that I want it to go in separately with clear documentation of
>> what's changing. Other examples of this include the non-null
>> handling, and arguments.
>>
>> As a meta comment: the entire motivation of this change was being
>> able to write smaller (aka reasonable sized) test cases for a future
>> patch teaching LVI about select instructions.
>>
>> Differential Revision: http://reviews.llvm.org/D13543
>>
>>
>> Modified:
>> llvm/trunk/lib/Analysis/LazyValueInfo.cpp
>> llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>> llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll
>>
>> Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=251606&r1=251605&r2=251606&view=diff
>> ==============================================================================
>>
>> --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
>> +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Oct 28 22:57:17 2015
>> @@ -26,6 +26,7 @@
>> #include "llvm/IR/Dominators.h"
>> #include "llvm/IR/Instructions.h"
>> #include "llvm/IR/IntrinsicInst.h"
>> +#include "llvm/IR/LLVMContext.h"
>> #include "llvm/IR/PatternMatch.h"
>> #include "llvm/IR/ValueHandle.h"
>> #include "llvm/Support/Debug.h"
>> @@ -497,6 +498,25 @@ LVILatticeVal LazyValueInfoCache::getBlo
>> return lookup(Val)[BB];
>> }
>>
>> +static LVILatticeVal getFromRangeMetadata(Instruction *BBI) {
>> + switch (BBI->getOpcode()) {
>> + default: break;
>> + case Instruction::Load:
>> + case Instruction::Call:
>> + case Instruction::Invoke:
>> + if (MDNode *Ranges = BBI->getMetadata(LLVMContext::MD_range))
>> + if (auto *IType = dyn_cast<IntegerType>(BBI->getType())) {
>> + ConstantRange Result = getConstantRangeFromMetadata(*Ranges);
>> + return LVILatticeVal::getRange(Result);
>> + }
>> + break;
>> + };
>> + // Nothing known - Note that we do not want overdefined here. We
>> may know
>> + // something else about the value and not having range metadata
>> shouldn't
>> + // cause us to throw away those facts.
>> + return LVILatticeVal();
>> +}
>> +
>> bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) {
>> if (isa<Constant>(Val))
>> return true;
>> @@ -539,6 +559,10 @@ bool LazyValueInfoCache::solveBlockValue
>> return true;
>> }
>>
>> + // If this is an instruction which supports range metadata, return
>> the
>> + // implied range. TODO: This should be an intersection, not a union.
>> + Res.mergeIn(getFromRangeMetadata(BBI), DL);
>> +
>> // We can only analyze the definitions of certain classes of
>> instructions
>> // (integral binops and casts at the moment), so bail if this
>> isn't one.
>> LVILatticeVal Result;
>> @@ -1015,6 +1039,8 @@ LVILatticeVal LazyValueInfoCache::getVal
>> << CxtI->getName()<< "'\n");
>>
>> LVILatticeVal Result;
>> + if (auto *I = dyn_cast<Instruction>(V))
>> + Result = getFromRangeMetadata(I);
>> mergeAssumeBlockValueConstantRange(V, Result, CxtI);
>>
>> DEBUG(dbgs()<< " Result = "<< Result<< "\n");
>>
>> Modified:
>> llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp?rev=251606&r1=251605&r2=251606&view=diff
>> ==============================================================================
>>
>> --- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>> (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>> Wed Oct 28 22:57:17 2015
>> @@ -181,44 +181,24 @@ bool CorrelatedValuePropagation::process
>> return true;
>> }
>>
>> -/// processCmp - If the value of this comparison could be determined
>> locally,
>> -/// constant propagation would already have figured it out. Instead,
>> walk
>> -/// the predecessors and statically evaluate the comparison based on
>> information
>> -/// available on that edge. If a given static evaluation is true on
>> ALL
>> -/// incoming edges, then it's true universally and we can simplify
>> the compare.
>> +/// processCmp - See if LazyValueInfo's ability to exploit edge
>> conditions,
>> +/// or range information is sufficient to prove this comparison.
>> Even for
>> +/// local conditions, this can sometimes prove conditions
>> instcombine can't by
>> +/// exploiting range information.
>> bool CorrelatedValuePropagation::processCmp(CmpInst *C) {
>> Value *Op0 = C->getOperand(0);
>> - if (isa<Instruction>(Op0)&&
>> - cast<Instruction>(Op0)->getParent() == C->getParent())
>> - return false;
>> -
>> Constant *Op1 = dyn_cast<Constant>(C->getOperand(1));
>> if (!Op1) return false;
>>
>> - pred_iterator PI = pred_begin(C->getParent()), PE =
>> pred_end(C->getParent());
>> - if (PI == PE) return false;
>> -
>> - LazyValueInfo::Tristate Result =
>> LVI->getPredicateOnEdge(C->getPredicate(),
>> - C->getOperand(0), Op1, *PI,
>> - C->getParent(), C);
>> + LazyValueInfo::Tristate Result =
>> + LVI->getPredicateAt(C->getPredicate(), Op0, Op1, C);
>> if (Result == LazyValueInfo::Unknown) return false;
>>
>> - ++PI;
>> - while (PI != PE) {
>> - LazyValueInfo::Tristate Res =
>> LVI->getPredicateOnEdge(C->getPredicate(),
>> - C->getOperand(0), Op1, *PI,
>> - C->getParent(), C);
>> - if (Res != Result) return false;
>> - ++PI;
>> - }
>> -
>> ++NumCmps;
>> -
>> if (Result == LazyValueInfo::True)
>> C->replaceAllUsesWith(ConstantInt::getTrue(C->getContext()));
>> else
>> C->replaceAllUsesWith(ConstantInt::getFalse(C->getContext()));
>> -
>> C->eraseFromParent();
>>
>> return true;
>>
>> Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll?rev=251606&r1=251605&r2=251606&view=diff
>> ==============================================================================
>>
>> --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll
>> (original)
>> +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll
>> Wed Oct 28 22:57:17 2015
>> @@ -165,3 +165,27 @@ sw.default:
>> %or2 = or i1 %cmp7, %cmp8
>> ret i1 false
>> }
>> +
>> +define i1 @test8(i64* %p) {
>> +; CHECK-LABEL: @test8
>> +; CHECK: ret i1 false
>> + %a = load i64, i64* %p, !range !{i64 4, i64 255}
>> + %res = icmp eq i64 %a, 0
>> + ret i1 %res
>> +}
>> +
>> +define i1 @test9(i64* %p) {
>> +; CHECK-LABEL: @test9
>> +; CHECK: ret i1 true
>> + %a = load i64, i64* %p, !range !{i64 0, i64 1}
>> + %res = icmp eq i64 %a, 0
>> + ret i1 %res
>> +}
>> +
>> +define i1 @test10(i64* %p) {
>> +; CHECK-LABEL: @test10
>> +; CHECK: ret i1 false
>> + %a = load i64, i64* %p, !range !{i64 4, i64 8, i64 15, i64 20}
>> + %res = icmp eq i64 %a, 0
>> + ret i1 %res
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list