mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
The comparision "max(x,y)==x" is equivalent to "x>=y". Since the max is
often expressed as "x >= y ? x : y", there is a good chance we can extract the existing "x >= y" from it and use that as a replacement for "max(x,y)==x". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131049 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
33c110e602
commit
e864b5b840
@ -1376,6 +1376,26 @@ static const Type *GetCompareTy(Value *Op) {
|
||||
return CmpInst::makeCmpResultType(Op->getType());
|
||||
}
|
||||
|
||||
/// ExtractEquivalentCondition - Rummage around inside V looking for something
|
||||
/// equivalent to the comparison "LHS Pred RHS". Return such a value if found,
|
||||
/// otherwise return null. Helper function for analyzing max/min idioms.
|
||||
static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred,
|
||||
Value *LHS, Value *RHS) {
|
||||
SelectInst *SI = dyn_cast<SelectInst>(V);
|
||||
if (!SI)
|
||||
return 0;
|
||||
CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition());
|
||||
if (!Cmp)
|
||||
return 0;
|
||||
Value *CmpLHS = Cmp->getOperand(0), *CmpRHS = Cmp->getOperand(1);
|
||||
if (Pred == Cmp->getPredicate() && LHS == CmpLHS && RHS == CmpRHS)
|
||||
return Cmp;
|
||||
if (Pred == CmpInst::getSwappedPredicate(Cmp->getPredicate()) &&
|
||||
LHS == CmpRHS && RHS == CmpLHS)
|
||||
return Cmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
@ -1907,19 +1927,32 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
break;
|
||||
case CmpInst::ICMP_EQ:
|
||||
case CmpInst::ICMP_SLE:
|
||||
// Equivalent to "A EqP B".
|
||||
// Equivalent to "A EqP B". This may be the same as the condition tested
|
||||
// in the max/min; if so, we can just return that.
|
||||
if (Value *V = ExtractEquivalentCondition(LHS, EqP, A, B))
|
||||
return V;
|
||||
if (Value *V = ExtractEquivalentCondition(RHS, EqP, A, B))
|
||||
return V;
|
||||
// Otherwise, see if "A EqP B" simplifies.
|
||||
if (MaxRecurse)
|
||||
if (Value *V = SimplifyICmpInst(EqP, A, B, TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
break;
|
||||
case CmpInst::ICMP_NE:
|
||||
case CmpInst::ICMP_SGT:
|
||||
// Equivalent to "A inverse-EqP B".
|
||||
case CmpInst::ICMP_SGT: {
|
||||
CmpInst::Predicate InvEqP = CmpInst::getInversePredicate(EqP);
|
||||
// Equivalent to "A InvEqP B". This may be the same as the condition
|
||||
// tested in the max/min; if so, we can just return that.
|
||||
if (Value *V = ExtractEquivalentCondition(LHS, InvEqP, A, B))
|
||||
return V;
|
||||
if (Value *V = ExtractEquivalentCondition(RHS, InvEqP, A, B))
|
||||
return V;
|
||||
// Otherwise, see if "A InvEqP B" simplifies.
|
||||
if (MaxRecurse)
|
||||
if (Value *V = SimplifyICmpInst(CmpInst::getInversePredicate(EqP), A, B,
|
||||
TD, DT, MaxRecurse-1))
|
||||
if (Value *V = SimplifyICmpInst(InvEqP, A, B, TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
break;
|
||||
}
|
||||
case CmpInst::ICMP_SGE:
|
||||
// Always true.
|
||||
return Constant::getAllOnesValue(ITy);
|
||||
@ -1964,19 +1997,32 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
break;
|
||||
case CmpInst::ICMP_EQ:
|
||||
case CmpInst::ICMP_ULE:
|
||||
// Equivalent to "A EqP B".
|
||||
// Equivalent to "A EqP B". This may be the same as the condition tested
|
||||
// in the max/min; if so, we can just return that.
|
||||
if (Value *V = ExtractEquivalentCondition(LHS, EqP, A, B))
|
||||
return V;
|
||||
if (Value *V = ExtractEquivalentCondition(RHS, EqP, A, B))
|
||||
return V;
|
||||
// Otherwise, see if "A EqP B" simplifies.
|
||||
if (MaxRecurse)
|
||||
if (Value *V = SimplifyICmpInst(EqP, A, B, TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
break;
|
||||
case CmpInst::ICMP_NE:
|
||||
case CmpInst::ICMP_UGT:
|
||||
// Equivalent to "A inverse-EqP B".
|
||||
case CmpInst::ICMP_UGT: {
|
||||
CmpInst::Predicate InvEqP = CmpInst::getInversePredicate(EqP);
|
||||
// Equivalent to "A InvEqP B". This may be the same as the condition
|
||||
// tested in the max/min; if so, we can just return that.
|
||||
if (Value *V = ExtractEquivalentCondition(LHS, InvEqP, A, B))
|
||||
return V;
|
||||
if (Value *V = ExtractEquivalentCondition(RHS, InvEqP, A, B))
|
||||
return V;
|
||||
// Otherwise, see if "A InvEqP B" simplifies.
|
||||
if (MaxRecurse)
|
||||
if (Value *V = SimplifyICmpInst(CmpInst::getInversePredicate(EqP), A, B,
|
||||
TD, DT, MaxRecurse-1))
|
||||
if (Value *V = SimplifyICmpInst(InvEqP, A, B, TD, DT, MaxRecurse-1))
|
||||
return V;
|
||||
break;
|
||||
}
|
||||
case CmpInst::ICMP_UGE:
|
||||
// Always true.
|
||||
return Constant::getAllOnesValue(ITy);
|
||||
|
@ -231,3 +231,39 @@ define i1 @maxmin8(i32 %x, i32 %y, i32 %z) {
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @eqcmp1(i32 %x, i32 %y) {
|
||||
; CHECK: @eqcmp1
|
||||
%c = icmp sge i32 %x, %y
|
||||
%max = select i1 %c, i32 %x, i32 %y
|
||||
%r = icmp eq i32 %max, %x
|
||||
ret i1 %r
|
||||
; CHECK: ret i1 %c
|
||||
}
|
||||
|
||||
define i1 @eqcmp2(i32 %x, i32 %y) {
|
||||
; CHECK: @eqcmp2
|
||||
%c = icmp sge i32 %x, %y
|
||||
%max = select i1 %c, i32 %x, i32 %y
|
||||
%r = icmp eq i32 %x, %max
|
||||
ret i1 %r
|
||||
; CHECK: ret i1 %c
|
||||
}
|
||||
|
||||
define i1 @eqcmp3(i32 %x, i32 %y) {
|
||||
; CHECK: @eqcmp3
|
||||
%c = icmp uge i32 %x, %y
|
||||
%max = select i1 %c, i32 %x, i32 %y
|
||||
%r = icmp eq i32 %max, %x
|
||||
ret i1 %r
|
||||
; CHECK: ret i1 %c
|
||||
}
|
||||
|
||||
define i1 @eqcmp4(i32 %x, i32 %y) {
|
||||
; CHECK: @eqcmp4
|
||||
%c = icmp uge i32 %x, %y
|
||||
%max = select i1 %c, i32 %x, i32 %y
|
||||
%r = icmp eq i32 %x, %max
|
||||
ret i1 %r
|
||||
; CHECK: ret i1 %c
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user