mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Teach instsimplify that X+Y>=X+Z is the same as Y>=Z if neither side overflows,
plus some variations of this. According to my auto-simplifier this occurs a lot but usually in combination with max/min idioms. Because max/min aren't handled yet this unfortunately doesn't have much effect in the testsuite. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125462 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d239e5af64
commit
52fb846578
@ -986,7 +986,7 @@ static Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) &&
|
||||
cast<OverflowingBinaryOperator>(Op0)->hasNoUnsignedWrap())
|
||||
return X;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1016,7 +1016,7 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) &&
|
||||
cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap())
|
||||
return X;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1588,6 +1588,53 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
}
|
||||
}
|
||||
|
||||
// Special logic for binary operators.
|
||||
BinaryOperator *LBO = dyn_cast<BinaryOperator>(LHS);
|
||||
BinaryOperator *RBO = dyn_cast<BinaryOperator>(RHS);
|
||||
if (MaxRecurse && (LBO || RBO)) {
|
||||
|
||||
// Analyze the case when either LHS or RHS is an add instruction.
|
||||
Value *A = 0, *B = 0, *C = 0, *D = 0;
|
||||
// LHS = A + B (or A and B are null); RHS = C + D (or C and D are null).
|
||||
bool NoLHSWrapProblem = false, NoRHSWrapProblem = false;
|
||||
if (LBO && LBO->getOpcode() == Instruction::Add) {
|
||||
A = LBO->getOperand(0); B = LBO->getOperand(1);
|
||||
NoLHSWrapProblem = ICmpInst::isEquality(Pred) ||
|
||||
(CmpInst::isUnsigned(Pred) && LBO->hasNoUnsignedWrap()) ||
|
||||
(CmpInst::isSigned(Pred) && LBO->hasNoSignedWrap());
|
||||
}
|
||||
if (RBO && RBO->getOpcode() == Instruction::Add) {
|
||||
C = RBO->getOperand(0); D = RBO->getOperand(1);
|
||||
NoRHSWrapProblem = ICmpInst::isEquality(Pred) ||
|
||||
(CmpInst::isUnsigned(Pred) && RBO->hasNoUnsignedWrap()) ||
|
||||
(CmpInst::isSigned(Pred) && RBO->hasNoSignedWrap());
|
||||
}
|
||||
|
||||
// icmp (X+Y), X -> icmp Y, 0 for equalities or if there is no overflow.
|
||||
if ((A == RHS || B == RHS) && NoLHSWrapProblem)
|
||||
if (Value *V = SimplifyICmpInst(Pred, A == RHS ? B : A,
|
||||
Constant::getNullValue(RHS->getType()),
|
||||
TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
|
||||
// icmp X, (X+Y) -> icmp 0, Y for equalities or if there is no overflow.
|
||||
if ((C == LHS || D == LHS) && NoRHSWrapProblem)
|
||||
if (Value *V = SimplifyICmpInst(Pred,
|
||||
Constant::getNullValue(LHS->getType()),
|
||||
C == LHS ? D : C, TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
|
||||
// icmp (X+Y), (X+Z) -> icmp Y,Z for equalities or if there is no overflow.
|
||||
if (A && C && (A == C || A == D || B == C || B == D) &&
|
||||
NoLHSWrapProblem && NoRHSWrapProblem) {
|
||||
// Determine Y and Z in the form icmp (X+Y), (X+Z).
|
||||
Value *Y = (A == C || A == D) ? B : A;
|
||||
Value *Z = (C == A || C == B) ? D : C;
|
||||
if (Value *V = SimplifyICmpInst(Pred, Y, Z, TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
}
|
||||
}
|
||||
|
||||
// If the comparison is with the result of a select instruction, check whether
|
||||
// comparing with either branch of the select always yields the same value.
|
||||
if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))
|
||||
|
@ -91,6 +91,26 @@ define i1 @add3(i8 %x, i8 %y) {
|
||||
; CHECK: ret i1 %c
|
||||
}
|
||||
|
||||
define i1 @add4(i32 %x, i32 %y) {
|
||||
; CHECK: @add4
|
||||
%z = add nsw i32 %y, 1
|
||||
%s1 = add nsw i32 %x, %y
|
||||
%s2 = add nsw i32 %x, %z
|
||||
%c = icmp slt i32 %s1, %s2
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @add5(i32 %x, i32 %y) {
|
||||
; CHECK: @add5
|
||||
%z = add nuw i32 %y, 1
|
||||
%s1 = add nuw i32 %x, %z
|
||||
%s2 = add nuw i32 %x, %y
|
||||
%c = icmp ugt i32 %s1, %s2
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @addpowtwo(i32 %x, i32 %y) {
|
||||
; CHECK: @addpowtwo
|
||||
%l = lshr i32 %x, 1
|
Loading…
Reference in New Issue
Block a user