mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-25 00:29:20 +00:00
New InstCombine pattern: (icmp ult/ule (A + C1), C3) | (icmp ult/ule (A + C2), C3) to (icmp ult/ule ((A & ~(C1 ^ C2)) + max(C1, C2)), C3) under certain condition
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216135 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9ec471a5d8
commit
ee1b45f2a2
@ -1612,6 +1612,61 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fold (icmp ult/ule (A + C1), C3) | (icmp ult/ule (A + C2), C3)
|
||||
// --> (icmp ult/ule ((A & ~(C1 ^ C2)) + max(C1, C2)), C3)
|
||||
// The original condition actually refers to the following two ranges:
|
||||
// [MAX_UINT-C1+1, MAX_UINT-C1+1+C3] and [MAX_UINT-C2+1, MAX_UINT-C2+1+C3]
|
||||
// We can fold these two ranges if:
|
||||
// 1) C1 and C2 is unsigned greater than C3.
|
||||
// 2) The two ranges are separated.
|
||||
// 3) C1 ^ C2 is one-bit mask.
|
||||
// 4) LowRange1 ^ LowRange2 and HighRange1 ^ HighRange2 are one-bit mask.
|
||||
// This implies all values in the two ranges differ by exactly one bit.
|
||||
|
||||
if ((LHSCC == ICmpInst::ICMP_ULT || LHSCC == ICmpInst::ICMP_ULE) &&
|
||||
LHSCC == RHSCC && LHSCst && RHSCst && LHS->hasOneUse() &&
|
||||
RHS->hasOneUse() && LHSCst->getType() == RHSCst->getType() &&
|
||||
LHSCst->getValue() == (RHSCst->getValue())) {
|
||||
|
||||
Value *LAdd = LHS->getOperand(0);
|
||||
Value *RAdd = RHS->getOperand(0);
|
||||
|
||||
Value *LAddOpnd, *RAddOpnd;
|
||||
ConstantInt *LAddCst, *RAddCst;
|
||||
if (match(LAdd, m_Add(m_Value(LAddOpnd), m_ConstantInt(LAddCst))) &&
|
||||
match(RAdd, m_Add(m_Value(RAddOpnd), m_ConstantInt(RAddCst))) &&
|
||||
LAddCst->getValue().ugt(LHSCst->getValue()) &&
|
||||
RAddCst->getValue().ugt(LHSCst->getValue())) {
|
||||
|
||||
APInt DiffCst = LAddCst->getValue() ^ RAddCst->getValue();
|
||||
if (LAddOpnd == RAddOpnd && DiffCst.isPowerOf2()) {
|
||||
ConstantInt *MaxAddCst = nullptr;
|
||||
if (LAddCst->getValue().ult(RAddCst->getValue()))
|
||||
MaxAddCst = RAddCst;
|
||||
else
|
||||
MaxAddCst = LAddCst;
|
||||
|
||||
APInt RRangeLow = -RAddCst->getValue();
|
||||
APInt RRangeHigh = RRangeLow + LHSCst->getValue();
|
||||
APInt LRangeLow = -LAddCst->getValue();
|
||||
APInt LRangeHigh = LRangeLow + LHSCst->getValue();
|
||||
APInt LowRangeDiff = RRangeLow ^ LRangeLow;
|
||||
APInt HighRangeDiff = RRangeHigh ^ LRangeHigh;
|
||||
APInt RangeDiff = LRangeLow.sgt(RRangeLow) ? LRangeLow - RRangeLow
|
||||
: RRangeLow - LRangeLow;
|
||||
|
||||
if (LowRangeDiff.isPowerOf2() && LowRangeDiff == HighRangeDiff &&
|
||||
RangeDiff.ugt(LHSCst->getValue())) {
|
||||
Value *MaskCst = ConstantInt::get(LAddCst->getType(), ~DiffCst);
|
||||
|
||||
Value *NewAnd = Builder->CreateAnd(LAddOpnd, MaskCst);
|
||||
Value *NewAdd = Builder->CreateAdd(NewAnd, MaxAddCst);
|
||||
return (Builder->CreateICmp(LHS->getPredicate(), NewAdd, LHSCst));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
|
||||
if (PredicatesFoldable(LHSCC, RHSCC)) {
|
||||
if (LHS->getOperand(0) == RHS->getOperand(1) &&
|
||||
|
@ -480,3 +480,29 @@ define i32 @test45(i32 %x, i32 %y, i32 %z) {
|
||||
%or1 = or i32 %and, %y
|
||||
ret i32 %or1
|
||||
}
|
||||
|
||||
define i1 @test46(i8 signext %c) {
|
||||
%c.off = add i8 %c, -97
|
||||
%cmp1 = icmp ult i8 %c.off, 26
|
||||
%c.off17 = add i8 %c, -65
|
||||
%cmp2 = icmp ult i8 %c.off17, 26
|
||||
%or = or i1 %cmp1, %cmp2
|
||||
ret i1 %or
|
||||
; CHECK-LABEL: @test46(
|
||||
; CHECK-NEXT: and i8 %c, -33
|
||||
; CHECK-NEXT: add i8 %1, -65
|
||||
; CHECK-NEXT: icmp ult i8 %2, 26
|
||||
}
|
||||
|
||||
define i1 @test47(i8 signext %c) {
|
||||
%c.off = add i8 %c, -65
|
||||
%cmp1 = icmp ule i8 %c.off, 26
|
||||
%c.off17 = add i8 %c, -97
|
||||
%cmp2 = icmp ule i8 %c.off17, 26
|
||||
%or = or i1 %cmp1, %cmp2
|
||||
ret i1 %or
|
||||
; CHECK-LABEL: @test47(
|
||||
; CHECK-NEXT: and i8 %c, -33
|
||||
; CHECK-NEXT: add i8 %1, -65
|
||||
; CHECK-NEXT: icmp ult i8 %2, 27
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user