diff options
author | Nikita Popov <npopov@redhat.com> | 2023-11-03 13:03:51 +0100 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2023-11-03 13:12:39 +0100 |
commit | 236197a065879c900a450e5236adbb76578006cb (patch) | |
tree | eeff67c5831ad389a5d8e474051fcb471fde1963 /llvm/lib/IR/ConstantFold.cpp | |
parent | 51485019fb34a48dc6226bfa42d7449091e3f03d (diff) | |
download | llvm-236197a065879c900a450e5236adbb76578006cb.zip llvm-236197a065879c900a450e5236adbb76578006cb.tar.gz llvm-236197a065879c900a450e5236adbb76578006cb.tar.bz2 |
[ConstantFold] Simplify evaluateICmpRelation() implementation (NFCI)
Clarify that most of this only works on pointer icmps, and remove
the unnecessary isSigned parameter, as well as the ConstantInt
fallback.
Also perform complexity sorting upfront, so we don't need to deal
with swapped cases in the individual branches.
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 106 |
1 files changed, 38 insertions, 68 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index a4df579..d4bc74e 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1142,57 +1142,51 @@ static ICmpInst::Predicate areGlobalsPotentiallyEqual(const GlobalValue *GV1, /// If we can determine that the two constants have a particular relation to /// each other, we should return the corresponding ICmp predicate, otherwise /// return ICmpInst::BAD_ICMP_PREDICATE. -/// -/// To simplify this code we canonicalize the relation so that the first -/// operand is always the most "complex" of the two. We consider simple -/// constants (like ConstantInt) to be the simplest, followed by -/// GlobalValues, followed by ConstantExpr's (the most complex). -/// -static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, - bool isSigned) { +static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2) { assert(V1->getType() == V2->getType() && "Cannot compare different types of values!"); if (V1 == V2) return ICmpInst::ICMP_EQ; - if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1) && - !isa<BlockAddress>(V1)) { - if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2) && - !isa<BlockAddress>(V2)) { - // We distilled this down to a simple case, use the standard constant - // folder. - ConstantInt *R = nullptr; - ICmpInst::Predicate pred = ICmpInst::ICMP_EQ; - R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); - if (R && !R->isZero()) - return pred; - pred = isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; - R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); - if (R && !R->isZero()) - return pred; - pred = isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; - R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); - if (R && !R->isZero()) - return pred; - - // If we couldn't figure it out, bail. - return ICmpInst::BAD_ICMP_PREDICATE; - } - - // If the first operand is simple, swap operands. - ICmpInst::Predicate SwappedRelation = - evaluateICmpRelation(V2, V1, isSigned); + // The following folds only apply to pointers. + if (!V1->getType()->isPointerTy()) + return ICmpInst::BAD_ICMP_PREDICATE; + + // To simplify this code we canonicalize the relation so that the first + // operand is always the most "complex" of the two. We consider simple + // constants (like ConstantPointerNull) to be the simplest, followed by + // BlockAddress, GlobalValues, and ConstantExpr's (the most complex). + auto GetComplexity = [](Constant *V) { + if (isa<ConstantExpr>(V)) + return 3; + if (isa<GlobalValue>(V)) + return 2; + if (isa<BlockAddress>(V)) + return 1; + return 0; + }; + if (GetComplexity(V1) < GetComplexity(V2)) { + ICmpInst::Predicate SwappedRelation = evaluateICmpRelation(V2, V1); if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) return ICmpInst::getSwappedPredicate(SwappedRelation); + return ICmpInst::BAD_ICMP_PREDICATE; + } - } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V1)) { - if (isa<ConstantExpr>(V2)) { // Swap as necessary. - ICmpInst::Predicate SwappedRelation = - evaluateICmpRelation(V2, V1, isSigned); - if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) - return ICmpInst::getSwappedPredicate(SwappedRelation); - return ICmpInst::BAD_ICMP_PREDICATE; + if (const BlockAddress *BA = dyn_cast<BlockAddress>(V1)) { + // Now we know that the RHS is a BlockAddress or simple + // constant (which, since the types must match, means that it is a + // ConstantPointerNull). + if (const BlockAddress *BA2 = dyn_cast<BlockAddress>(V2)) { + // Block address in another function can't equal this one, but block + // addresses in the current function might be the same if blocks are + // empty. + if (BA2->getFunction() != BA->getFunction()) + return ICmpInst::ICMP_NE; + } else { + // Block addresses aren't null. + assert(isa<ConstantPointerNull>(V2) && "Canonicalization guarantee!"); + return ICmpInst::ICMP_NE; } - + } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V1)) { // Now we know that the RHS is a GlobalValue, BlockAddress or simple // constant (which, since the types must match, means that it's a // ConstantPointerNull). @@ -1212,30 +1206,6 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, GV->getType()->getAddressSpace())) return ICmpInst::ICMP_UGT; } - } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(V1)) { - if (isa<ConstantExpr>(V2)) { // Swap as necessary. - ICmpInst::Predicate SwappedRelation = - evaluateICmpRelation(V2, V1, isSigned); - if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) - return ICmpInst::getSwappedPredicate(SwappedRelation); - return ICmpInst::BAD_ICMP_PREDICATE; - } - - // Now we know that the RHS is a GlobalValue, BlockAddress or simple - // constant (which, since the types must match, means that it is a - // ConstantPointerNull). - if (const BlockAddress *BA2 = dyn_cast<BlockAddress>(V2)) { - // Block address in another function can't equal this one, but block - // addresses in the current function might be the same if blocks are - // empty. - if (BA2->getFunction() != BA->getFunction()) - return ICmpInst::ICMP_NE; - } else { - // Block addresses aren't null, don't equal the address of globals. - assert((isa<ConstantPointerNull>(V2) || isa<GlobalValue>(V2)) && - "Canonicalization guarantee!"); - return ICmpInst::ICMP_NE; - } } else { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a // constantexpr, a global, block address, or a simple constant. @@ -1429,7 +1399,7 @@ Constant *llvm::ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, } else { // Evaluate the relation between the two constants, per the predicate. int Result = -1; // -1 = unknown, 0 = known false, 1 = known true. - switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(Predicate))) { + switch (evaluateICmpRelation(C1, C2)) { default: llvm_unreachable("Unknown relational!"); case ICmpInst::BAD_ICMP_PREDICATE: break; // Couldn't determine anything about these constants. |