mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 21:31:03 +00:00
LVI: Recognize the form instcombine canonicalizes range checks into when forming constant ranges.
This could probably be made a lot smarter, but this is a common case and doesn't require LVI to scan a lot of code. With this change CVP can optimize away the "shift == 0" case in Hashing.h that only gets hit when "shift" is in a range not containing 0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151919 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0c7374d87e
commit
8979e5f372
@ -24,6 +24,7 @@
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/ConstantRange.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/PatternMatch.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
@ -31,6 +32,7 @@
|
||||
#include <map>
|
||||
#include <stack>
|
||||
using namespace llvm;
|
||||
using namespace PatternMatch;
|
||||
|
||||
char LazyValueInfo::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LazyValueInfo, "lazy-value-info",
|
||||
@ -795,9 +797,8 @@ bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom,
|
||||
// If the condition of the branch is an equality comparison, we may be
|
||||
// able to infer the value.
|
||||
ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition());
|
||||
if (ICI && ICI->getOperand(0) == Val &&
|
||||
isa<Constant>(ICI->getOperand(1))) {
|
||||
if (ICI->isEquality()) {
|
||||
if (ICI && isa<Constant>(ICI->getOperand(1))) {
|
||||
if (ICI->isEquality() && ICI->getOperand(0) == Val) {
|
||||
// We know that V has the RHS constant if this is a true SETEQ or
|
||||
// false SETNE.
|
||||
if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ))
|
||||
@ -807,12 +808,23 @@ bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(ICI->getOperand(1))) {
|
||||
// Recognize the range checking idiom that InstCombine produces.
|
||||
// (X-C1) u< C2 --> [C1, C1+C2)
|
||||
ConstantInt *NegOffset = 0;
|
||||
if (ICI->getPredicate() == ICmpInst::ICMP_ULT)
|
||||
match(ICI->getOperand(0), m_Add(m_Specific(Val),
|
||||
m_ConstantInt(NegOffset)));
|
||||
|
||||
ConstantInt *CI = dyn_cast<ConstantInt>(ICI->getOperand(1));
|
||||
if (CI && (ICI->getOperand(0) == Val || NegOffset)) {
|
||||
// Calculate the range of values that would satisfy the comparison.
|
||||
ConstantRange CmpRange(CI->getValue(), CI->getValue()+1);
|
||||
ConstantRange TrueValues =
|
||||
ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange);
|
||||
|
||||
if (NegOffset) // Apply the offset from above.
|
||||
TrueValues = TrueValues.subtract(NegOffset->getValue());
|
||||
|
||||
// If we're interested in the false dest, invert the condition.
|
||||
if (!isTrueDest) TrueValues = TrueValues.inverse();
|
||||
|
||||
|
43
test/Transforms/CorrelatedValuePropagation/range.ll
Normal file
43
test/Transforms/CorrelatedValuePropagation/range.ll
Normal file
@ -0,0 +1,43 @@
|
||||
; RUN: opt -correlated-propagation -S < %s | FileCheck %s
|
||||
|
||||
declare i32 @foo()
|
||||
|
||||
define i32 @test1(i32 %a) nounwind {
|
||||
%a.off = add i32 %a, -8
|
||||
%cmp = icmp ult i32 %a.off, 8
|
||||
br i1 %cmp, label %then, label %else
|
||||
|
||||
then:
|
||||
%dead = icmp eq i32 %a, 7
|
||||
br i1 %dead, label %end, label %else
|
||||
|
||||
else:
|
||||
ret i32 1
|
||||
|
||||
end:
|
||||
ret i32 2
|
||||
|
||||
; CHECK: @test1
|
||||
; CHECK: then:
|
||||
; CHECK-NEXT: br i1 false, label %end, label %else
|
||||
}
|
||||
|
||||
define i32 @test2(i32 %a) nounwind {
|
||||
%a.off = add i32 %a, -8
|
||||
%cmp = icmp ult i32 %a.off, 8
|
||||
br i1 %cmp, label %then, label %else
|
||||
|
||||
then:
|
||||
%dead = icmp ugt i32 %a, 15
|
||||
br i1 %dead, label %end, label %else
|
||||
|
||||
else:
|
||||
ret i32 1
|
||||
|
||||
end:
|
||||
ret i32 2
|
||||
|
||||
; CHECK: @test2
|
||||
; CHECK: then:
|
||||
; CHECK-NEXT: br i1 false, label %end, label %else
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user