mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[JumpThreading] Teach jump threading how to analyze (and (cmp A, C1), (cmp A, C2)) after InstCombine has turned it into (cmp (add A, C3), C4)
Currently JumpThreading can use LazyValueInfo to analyze an 'and' or 'or' of compare if the compare is fed by a livein of a basic block. This can be used to to prove the condition can't be met for some predecessor and the jump from that predecessor can be moved to the false path of the condition. But if the compare is something that InstCombine turns into an add and a single compare, it can't be analyzed because the livein is now an input to the add and not the compare. This patch adds a new method to LVI to get a ConstantRange on an edge. Then we teach jump threading to detect the add livein feeding a compare and to get the ConstantRange and propagate it. Differential Revision: https://reviews.llvm.org/D33262 llvm-svn: 306085
This commit is contained in:
parent
6f60e44c50
commit
bb07faeae4
@ -93,6 +93,13 @@ public:
|
|||||||
Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
|
Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
|
||||||
Instruction *CxtI = nullptr);
|
Instruction *CxtI = nullptr);
|
||||||
|
|
||||||
|
/// Return the ConstantRage constraint that is known to hold for the
|
||||||
|
/// specified value on the specified edge. This may be only be called
|
||||||
|
/// on integer-typed Values.
|
||||||
|
ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
|
||||||
|
BasicBlock *ToBB,
|
||||||
|
Instruction *CxtI = nullptr);
|
||||||
|
|
||||||
/// Inform the analysis cache that we have threaded an edge from
|
/// Inform the analysis cache that we have threaded an edge from
|
||||||
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
|
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
|
||||||
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
|
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
|
||||||
|
@ -1660,6 +1660,26 @@ Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstantRange LazyValueInfo::getConstantRangeOnEdge(Value *V,
|
||||||
|
BasicBlock *FromBB,
|
||||||
|
BasicBlock *ToBB,
|
||||||
|
Instruction *CxtI) {
|
||||||
|
unsigned Width = V->getType()->getIntegerBitWidth();
|
||||||
|
const DataLayout &DL = FromBB->getModule()->getDataLayout();
|
||||||
|
LVILatticeVal Result =
|
||||||
|
getImpl(PImpl, AC, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
|
||||||
|
|
||||||
|
if (Result.isUndefined())
|
||||||
|
return ConstantRange(Width, /*isFullSet=*/false);
|
||||||
|
if (Result.isConstantRange())
|
||||||
|
return Result.getConstantRange();
|
||||||
|
// We represent ConstantInt constants as constant ranges but other kinds
|
||||||
|
// of integer constants, i.e. ConstantExpr will be tagged as constants
|
||||||
|
assert(!(Result.isConstant() && isa<ConstantInt>(Result.getConstant())) &&
|
||||||
|
"ConstantInt value must be represented as constantrange");
|
||||||
|
return ConstantRange(Width, /*isFullSet=*/true);
|
||||||
|
}
|
||||||
|
|
||||||
static LazyValueInfo::Tristate getPredicateResult(unsigned Pred, Constant *C,
|
static LazyValueInfo::Tristate getPredicateResult(unsigned Pred, Constant *C,
|
||||||
const LVILatticeVal &Val,
|
const LVILatticeVal &Val,
|
||||||
const DataLayout &DL,
|
const DataLayout &DL,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "llvm/Analysis/Loads.h"
|
#include "llvm/Analysis/Loads.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
|
#include "llvm/IR/ConstantRange.h"
|
||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/IntrinsicInst.h"
|
#include "llvm/IR/IntrinsicInst.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
@ -635,6 +636,46 @@ bool JumpThreadingPass::ComputeValueKnownInPredecessors(
|
|||||||
return !Result.empty();
|
return !Result.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstCombine can fold some forms of constant range checks into
|
||||||
|
// (icmp (add (x, C1)), C2). See if we have we have such a thing with
|
||||||
|
// x as a live-in.
|
||||||
|
{
|
||||||
|
using namespace PatternMatch;
|
||||||
|
Value *AddLHS;
|
||||||
|
ConstantInt *AddConst;
|
||||||
|
if (isa<ConstantInt>(CmpConst) &&
|
||||||
|
match(CmpLHS, m_Add(m_Value(AddLHS), m_ConstantInt(AddConst)))) {
|
||||||
|
if (!isa<Instruction>(AddLHS) ||
|
||||||
|
cast<Instruction>(AddLHS)->getParent() != BB) {
|
||||||
|
for (BasicBlock *P : predecessors(BB)) {
|
||||||
|
// If the value is known by LazyValueInfo to be a ConstantRange in
|
||||||
|
// a predecessor, use that information to try to thread this
|
||||||
|
// block.
|
||||||
|
ConstantRange CR = LVI->getConstantRangeOnEdge(
|
||||||
|
AddLHS, P, BB, CxtI ? CxtI : cast<Instruction>(CmpLHS));
|
||||||
|
// Propagate the range through the addition.
|
||||||
|
CR = CR.add(AddConst->getValue());
|
||||||
|
|
||||||
|
// Get the range where the compare returns true.
|
||||||
|
ConstantRange CmpRange = ConstantRange::makeExactICmpRegion(
|
||||||
|
Pred, cast<ConstantInt>(CmpConst)->getValue());
|
||||||
|
|
||||||
|
Constant *ResC;
|
||||||
|
if (CmpRange.contains(CR))
|
||||||
|
ResC = ConstantInt::getTrue(CmpType);
|
||||||
|
else if (CmpRange.inverse().contains(CR))
|
||||||
|
ResC = ConstantInt::getFalse(CmpType);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Result.push_back(std::make_pair(ResC, P));
|
||||||
|
}
|
||||||
|
|
||||||
|
return !Result.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find a constant value for the LHS of a comparison,
|
// Try to find a constant value for the LHS of a comparison,
|
||||||
// and evaluate it statically if we can.
|
// and evaluate it statically if we can.
|
||||||
PredValueInfoTy LHSVals;
|
PredValueInfoTy LHSVals;
|
||||||
|
Loading…
Reference in New Issue
Block a user