mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
[InstCombine] improve readability for icmp with cast folds; NFC
1. Update function name and stale code comments. 2. Use variable names that are less ambiguous. 3. Move operand checks into the function as early exits. llvm-svn: 369390
This commit is contained in:
parent
54215e5d31
commit
5950893514
@ -4026,74 +4026,78 @@ Instruction *InstCombiner::foldICmpEquality(ICmpInst &I) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle icmp (cast x to y), (cast/cst). We only handle extending casts so
|
/// Handle icmp (cast x), (cast or constant).
|
||||||
/// far.
|
Instruction *InstCombiner::foldICmpWithCastOp(ICmpInst &ICmp) {
|
||||||
Instruction *InstCombiner::foldICmpWithCastAndCast(ICmpInst &ICmp) {
|
auto *CastOp0 = dyn_cast<CastInst>(ICmp.getOperand(0));
|
||||||
const CastInst *LHSCI = cast<CastInst>(ICmp.getOperand(0));
|
if (!CastOp0)
|
||||||
Value *LHSCIOp = LHSCI->getOperand(0);
|
return nullptr;
|
||||||
Type *SrcTy = LHSCIOp->getType();
|
if (!isa<Constant>(ICmp.getOperand(1)) && !isa<CastInst>(ICmp.getOperand(1)))
|
||||||
Type *DestTy = LHSCI->getType();
|
return nullptr;
|
||||||
|
|
||||||
|
Value *Op0Src = CastOp0->getOperand(0);
|
||||||
|
Type *SrcTy = CastOp0->getSrcTy();
|
||||||
|
Type *DestTy = CastOp0->getDestTy();
|
||||||
|
|
||||||
// Turn icmp (ptrtoint x), (ptrtoint/c) into a compare of the input if the
|
// Turn icmp (ptrtoint x), (ptrtoint/c) into a compare of the input if the
|
||||||
// integer type is the same size as the pointer type.
|
// integer type is the same size as the pointer type.
|
||||||
const auto& CompatibleSizes = [&](Type* SrcTy, Type* DestTy) -> bool {
|
auto CompatibleSizes = [&](Type *SrcTy, Type *DestTy) {
|
||||||
if (isa<VectorType>(SrcTy)) {
|
if (isa<VectorType>(SrcTy)) {
|
||||||
SrcTy = cast<VectorType>(SrcTy)->getElementType();
|
SrcTy = cast<VectorType>(SrcTy)->getElementType();
|
||||||
DestTy = cast<VectorType>(DestTy)->getElementType();
|
DestTy = cast<VectorType>(DestTy)->getElementType();
|
||||||
}
|
}
|
||||||
return DL.getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth();
|
return DL.getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth();
|
||||||
};
|
};
|
||||||
if (LHSCI->getOpcode() == Instruction::PtrToInt &&
|
if (CastOp0->getOpcode() == Instruction::PtrToInt &&
|
||||||
CompatibleSizes(SrcTy, DestTy)) {
|
CompatibleSizes(SrcTy, DestTy)) {
|
||||||
Value *RHSOp = nullptr;
|
Value *NewOp1 = nullptr;
|
||||||
if (auto *RHSC = dyn_cast<PtrToIntOperator>(ICmp.getOperand(1))) {
|
if (auto *PtrToIntOp1 = dyn_cast<PtrToIntOperator>(ICmp.getOperand(1))) {
|
||||||
Value *RHSCIOp = RHSC->getOperand(0);
|
Value *PtrSrc = PtrToIntOp1->getOperand(0);
|
||||||
if (RHSCIOp->getType()->getPointerAddressSpace() ==
|
if (PtrSrc->getType()->getPointerAddressSpace() ==
|
||||||
LHSCIOp->getType()->getPointerAddressSpace()) {
|
Op0Src->getType()->getPointerAddressSpace()) {
|
||||||
RHSOp = RHSC->getOperand(0);
|
NewOp1 = PtrToIntOp1->getOperand(0);
|
||||||
// If the pointer types don't match, insert a bitcast.
|
// If the pointer types don't match, insert a bitcast.
|
||||||
if (LHSCIOp->getType() != RHSOp->getType())
|
if (Op0Src->getType() != NewOp1->getType())
|
||||||
RHSOp = Builder.CreateBitCast(RHSOp, LHSCIOp->getType());
|
NewOp1 = Builder.CreateBitCast(NewOp1, Op0Src->getType());
|
||||||
}
|
}
|
||||||
} else if (auto *RHSC = dyn_cast<Constant>(ICmp.getOperand(1))) {
|
} else if (auto *RHSC = dyn_cast<Constant>(ICmp.getOperand(1))) {
|
||||||
RHSOp = ConstantExpr::getIntToPtr(RHSC, SrcTy);
|
NewOp1 = ConstantExpr::getIntToPtr(RHSC, SrcTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RHSOp)
|
if (NewOp1)
|
||||||
return new ICmpInst(ICmp.getPredicate(), LHSCIOp, RHSOp);
|
return new ICmpInst(ICmp.getPredicate(), Op0Src, NewOp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code below only handles extension cast instructions, so far.
|
// The code below only handles extension cast instructions, so far.
|
||||||
// Enforce this.
|
// Enforce this.
|
||||||
if (LHSCI->getOpcode() != Instruction::ZExt &&
|
if (CastOp0->getOpcode() != Instruction::ZExt &&
|
||||||
LHSCI->getOpcode() != Instruction::SExt)
|
CastOp0->getOpcode() != Instruction::SExt)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
bool isSignedExt = LHSCI->getOpcode() == Instruction::SExt;
|
bool isSignedExt = CastOp0->getOpcode() == Instruction::SExt;
|
||||||
bool isSignedCmp = ICmp.isSigned();
|
bool isSignedCmp = ICmp.isSigned();
|
||||||
|
|
||||||
if (auto *CI = dyn_cast<CastInst>(ICmp.getOperand(1))) {
|
if (auto *CastOp1 = dyn_cast<CastInst>(ICmp.getOperand(1))) {
|
||||||
// Not an extension from the same type?
|
// Not an extension from the same type?
|
||||||
Value *RHSCIOp = CI->getOperand(0);
|
Value *Op1Src = CastOp1->getOperand(0);
|
||||||
if (RHSCIOp->getType() != LHSCIOp->getType())
|
if (Op1Src->getType() != Op0Src->getType())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// If the signedness of the two casts doesn't agree (i.e. one is a sext
|
// If the signedness of the two casts doesn't agree (i.e. one is a sext
|
||||||
// and the other is a zext), then we can't handle this.
|
// and the other is a zext), then we can't handle this.
|
||||||
if (CI->getOpcode() != LHSCI->getOpcode())
|
if (CastOp1->getOpcode() != CastOp0->getOpcode())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Deal with equality cases early.
|
// Deal with equality cases early.
|
||||||
if (ICmp.isEquality())
|
if (ICmp.isEquality())
|
||||||
return new ICmpInst(ICmp.getPredicate(), LHSCIOp, RHSCIOp);
|
return new ICmpInst(ICmp.getPredicate(), Op0Src, Op1Src);
|
||||||
|
|
||||||
// A signed comparison of sign extended values simplifies into a
|
// A signed comparison of sign extended values simplifies into a
|
||||||
// signed comparison.
|
// signed comparison.
|
||||||
if (isSignedCmp && isSignedExt)
|
if (isSignedCmp && isSignedExt)
|
||||||
return new ICmpInst(ICmp.getPredicate(), LHSCIOp, RHSCIOp);
|
return new ICmpInst(ICmp.getPredicate(), Op0Src, Op1Src);
|
||||||
|
|
||||||
// The other three cases all fold into an unsigned comparison.
|
// The other three cases all fold into an unsigned comparison.
|
||||||
return new ICmpInst(ICmp.getUnsignedPredicate(), LHSCIOp, RHSCIOp);
|
return new ICmpInst(ICmp.getUnsignedPredicate(), Op0Src, Op1Src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we aren't dealing with a constant on the RHS, exit early.
|
// If we aren't dealing with a constant on the RHS, exit early.
|
||||||
@ -4104,21 +4108,21 @@ Instruction *InstCombiner::foldICmpWithCastAndCast(ICmpInst &ICmp) {
|
|||||||
// Compute the constant that would happen if we truncated to SrcTy then
|
// Compute the constant that would happen if we truncated to SrcTy then
|
||||||
// re-extended to DestTy.
|
// re-extended to DestTy.
|
||||||
Constant *Res1 = ConstantExpr::getTrunc(C, SrcTy);
|
Constant *Res1 = ConstantExpr::getTrunc(C, SrcTy);
|
||||||
Constant *Res2 = ConstantExpr::getCast(LHSCI->getOpcode(), Res1, DestTy);
|
Constant *Res2 = ConstantExpr::getCast(CastOp0->getOpcode(), Res1, DestTy);
|
||||||
|
|
||||||
// If the re-extended constant didn't change...
|
// If the re-extended constant didn't change...
|
||||||
if (Res2 == C) {
|
if (Res2 == C) {
|
||||||
// Deal with equality cases early.
|
// Deal with equality cases early.
|
||||||
if (ICmp.isEquality())
|
if (ICmp.isEquality())
|
||||||
return new ICmpInst(ICmp.getPredicate(), LHSCIOp, Res1);
|
return new ICmpInst(ICmp.getPredicate(), Op0Src, Res1);
|
||||||
|
|
||||||
// A signed comparison of sign extended values simplifies into a
|
// A signed comparison of sign extended values simplifies into a
|
||||||
// signed comparison.
|
// signed comparison.
|
||||||
if (isSignedExt && isSignedCmp)
|
if (isSignedExt && isSignedCmp)
|
||||||
return new ICmpInst(ICmp.getPredicate(), LHSCIOp, Res1);
|
return new ICmpInst(ICmp.getPredicate(), Op0Src, Res1);
|
||||||
|
|
||||||
// The other three cases all fold into an unsigned comparison.
|
// The other three cases all fold into an unsigned comparison.
|
||||||
return new ICmpInst(ICmp.getUnsignedPredicate(), LHSCIOp, Res1);
|
return new ICmpInst(ICmp.getUnsignedPredicate(), Op0Src, Res1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The re-extended constant changed, partly changed (in the case of a vector),
|
// The re-extended constant changed, partly changed (in the case of a vector),
|
||||||
@ -4137,7 +4141,7 @@ Instruction *InstCombiner::foldICmpWithCastAndCast(ICmpInst &ICmp) {
|
|||||||
// We're performing an unsigned comp with a sign extended value.
|
// We're performing an unsigned comp with a sign extended value.
|
||||||
// This is true if the input is >= 0. [aka >s -1]
|
// This is true if the input is >= 0. [aka >s -1]
|
||||||
Constant *NegOne = Constant::getAllOnesValue(SrcTy);
|
Constant *NegOne = Constant::getAllOnesValue(SrcTy);
|
||||||
Value *Result = Builder.CreateICmpSGT(LHSCIOp, NegOne, ICmp.getName());
|
Value *Result = Builder.CreateICmpSGT(Op0Src, NegOne, ICmp.getName());
|
||||||
|
|
||||||
// Finally, return the value computed.
|
// Finally, return the value computed.
|
||||||
if (ICmp.getPredicate() == ICmpInst::ICMP_ULT)
|
if (ICmp.getPredicate() == ICmpInst::ICMP_ULT)
|
||||||
@ -5212,17 +5216,8 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
|||||||
if (Instruction *Res = foldICmpBitCast(I, Builder))
|
if (Instruction *Res = foldICmpBitCast(I, Builder))
|
||||||
return Res;
|
return Res;
|
||||||
|
|
||||||
if (isa<CastInst>(Op0)) {
|
if (Instruction *R = foldICmpWithCastOp(I))
|
||||||
// Handle the special case of: icmp (cast bool to X), <cst>
|
return R;
|
||||||
// This comes up when you have code like
|
|
||||||
// int X = A < B;
|
|
||||||
// if (X) ...
|
|
||||||
// For generality, we handle any zero-extension of any operand comparison
|
|
||||||
// with a constant or another cast from the same type.
|
|
||||||
if (isa<Constant>(Op1) || isa<CastInst>(Op1))
|
|
||||||
if (Instruction *R = foldICmpWithCastAndCast(I))
|
|
||||||
return R;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Instruction *Res = foldICmpBinOp(I))
|
if (Instruction *Res = foldICmpBinOp(I))
|
||||||
return Res;
|
return Res;
|
||||||
|
@ -861,7 +861,7 @@ private:
|
|||||||
Constant *RHSC);
|
Constant *RHSC);
|
||||||
Instruction *foldICmpAddOpConst(Value *X, const APInt &C,
|
Instruction *foldICmpAddOpConst(Value *X, const APInt &C,
|
||||||
ICmpInst::Predicate Pred);
|
ICmpInst::Predicate Pred);
|
||||||
Instruction *foldICmpWithCastAndCast(ICmpInst &ICI);
|
Instruction *foldICmpWithCastOp(ICmpInst &ICI);
|
||||||
|
|
||||||
Instruction *foldICmpUsingKnownBits(ICmpInst &Cmp);
|
Instruction *foldICmpUsingKnownBits(ICmpInst &Cmp);
|
||||||
Instruction *foldICmpWithDominatingICmp(ICmpInst &Cmp);
|
Instruction *foldICmpWithDominatingICmp(ICmpInst &Cmp);
|
||||||
|
Loading…
Reference in New Issue
Block a user