[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