10b57cec5SDimitry Andric //===- InstCombineCompares.cpp --------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the visitICmp and visitFCmp functions. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "InstCombineInternal.h" 140b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 155f757f3fSDimitry Andric #include "llvm/ADT/ScopeExit.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 170b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 1806c3fb27SDimitry Andric #include "llvm/Analysis/CaptureTracking.h" 194824e7fdSDimitry Andric #include "llvm/Analysis/CmpInstAnalysis.h" 200b57cec5SDimitry Andric #include "llvm/Analysis/ConstantFolding.h" 210b57cec5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h" 225f757f3fSDimitry Andric #include "llvm/Analysis/Utils/Local.h" 23bdd1243dSDimitry Andric #include "llvm/Analysis/VectorUtils.h" 240b57cec5SDimitry Andric #include "llvm/IR/ConstantRange.h" 250b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 26*0fca6ea1SDimitry Andric #include "llvm/IR/InstrTypes.h" 270b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 280b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h" 290b57cec5SDimitry Andric #include "llvm/Support/KnownBits.h" 30e8d8bef9SDimitry Andric #include "llvm/Transforms/InstCombine/InstCombiner.h" 315f757f3fSDimitry Andric #include <bitset> 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric using namespace llvm; 340b57cec5SDimitry Andric using namespace PatternMatch; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric #define DEBUG_TYPE "instcombine" 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric // How many times is a select replaced by one of its operands? 390b57cec5SDimitry Andric STATISTIC(NumSel, "Number of select opts"); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric /// Compute Result = In1+In2, returning true if the result overflowed for this 430b57cec5SDimitry Andric /// type. 440b57cec5SDimitry Andric static bool addWithOverflow(APInt &Result, const APInt &In1, 450b57cec5SDimitry Andric const APInt &In2, bool IsSigned = false) { 460b57cec5SDimitry Andric bool Overflow; 470b57cec5SDimitry Andric if (IsSigned) 480b57cec5SDimitry Andric Result = In1.sadd_ov(In2, Overflow); 490b57cec5SDimitry Andric else 500b57cec5SDimitry Andric Result = In1.uadd_ov(In2, Overflow); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric return Overflow; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric /// Compute Result = In1-In2, returning true if the result overflowed for this 560b57cec5SDimitry Andric /// type. 570b57cec5SDimitry Andric static bool subWithOverflow(APInt &Result, const APInt &In1, 580b57cec5SDimitry Andric const APInt &In2, bool IsSigned = false) { 590b57cec5SDimitry Andric bool Overflow; 600b57cec5SDimitry Andric if (IsSigned) 610b57cec5SDimitry Andric Result = In1.ssub_ov(In2, Overflow); 620b57cec5SDimitry Andric else 630b57cec5SDimitry Andric Result = In1.usub_ov(In2, Overflow); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric return Overflow; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// Given an icmp instruction, return true if any use of this comparison is a 690b57cec5SDimitry Andric /// branch on sign bit comparison. 700b57cec5SDimitry Andric static bool hasBranchUse(ICmpInst &I) { 710b57cec5SDimitry Andric for (auto *U : I.users()) 720b57cec5SDimitry Andric if (isa<BranchInst>(U)) 730b57cec5SDimitry Andric return true; 740b57cec5SDimitry Andric return false; 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric /// Returns true if the exploded icmp can be expressed as a signed comparison 780b57cec5SDimitry Andric /// to zero and updates the predicate accordingly. 790b57cec5SDimitry Andric /// The signedness of the comparison is preserved. 800b57cec5SDimitry Andric /// TODO: Refactor with decomposeBitTestICmp()? 810b57cec5SDimitry Andric static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) { 820b57cec5SDimitry Andric if (!ICmpInst::isSigned(Pred)) 830b57cec5SDimitry Andric return false; 840b57cec5SDimitry Andric 85349cc55cSDimitry Andric if (C.isZero()) 860b57cec5SDimitry Andric return ICmpInst::isRelational(Pred); 870b57cec5SDimitry Andric 88349cc55cSDimitry Andric if (C.isOne()) { 890b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SLT) { 900b57cec5SDimitry Andric Pred = ICmpInst::ICMP_SLE; 910b57cec5SDimitry Andric return true; 920b57cec5SDimitry Andric } 93349cc55cSDimitry Andric } else if (C.isAllOnes()) { 940b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SGT) { 950b57cec5SDimitry Andric Pred = ICmpInst::ICMP_SGE; 960b57cec5SDimitry Andric return true; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric return false; 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// This is called when we see this pattern: 1040b57cec5SDimitry Andric /// cmp pred (load (gep GV, ...)), cmpcst 1050b57cec5SDimitry Andric /// where GV is a global variable with a constant initializer. Try to simplify 1060b57cec5SDimitry Andric /// this into some simple computation that does not need the load. For example 1070b57cec5SDimitry Andric /// we can optimize "icmp eq (load (gep "foo", 0, i)), 0" into "icmp eq i, 3". 1080b57cec5SDimitry Andric /// 1090b57cec5SDimitry Andric /// If AndCst is non-null, then the loaded value is masked with that constant 1100b57cec5SDimitry Andric /// before doing the comparison. This handles cases like "A[i]&4 == 0". 11181ad6265SDimitry Andric Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal( 11281ad6265SDimitry Andric LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI, 1130b57cec5SDimitry Andric ConstantInt *AndCst) { 11481ad6265SDimitry Andric if (LI->isVolatile() || LI->getType() != GEP->getResultElementType() || 115647cbc5dSDimitry Andric GV->getValueType() != GEP->getSourceElementType() || !GV->isConstant() || 116647cbc5dSDimitry Andric !GV->hasDefinitiveInitializer()) 11781ad6265SDimitry Andric return nullptr; 11881ad6265SDimitry Andric 1190b57cec5SDimitry Andric Constant *Init = GV->getInitializer(); 1200b57cec5SDimitry Andric if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init)) 1210b57cec5SDimitry Andric return nullptr; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric uint64_t ArrayElementCount = Init->getType()->getArrayNumElements(); 1240b57cec5SDimitry Andric // Don't blow up on huge arrays. 1250b57cec5SDimitry Andric if (ArrayElementCount > MaxArraySizeForCombine) 1260b57cec5SDimitry Andric return nullptr; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric // There are many forms of this optimization we can handle, for now, just do 1290b57cec5SDimitry Andric // the simple index into a single-dimensional array. 1300b57cec5SDimitry Andric // 1310b57cec5SDimitry Andric // Require: GEP GV, 0, i {{, constant indices}} 132647cbc5dSDimitry Andric if (GEP->getNumOperands() < 3 || !isa<ConstantInt>(GEP->getOperand(1)) || 1330b57cec5SDimitry Andric !cast<ConstantInt>(GEP->getOperand(1))->isZero() || 1340b57cec5SDimitry Andric isa<Constant>(GEP->getOperand(2))) 1350b57cec5SDimitry Andric return nullptr; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric // Check that indices after the variable are constants and in-range for the 1380b57cec5SDimitry Andric // type they index. Collect the indices. This is typically for arrays of 1390b57cec5SDimitry Andric // structs. 1400b57cec5SDimitry Andric SmallVector<unsigned, 4> LaterIndices; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric Type *EltTy = Init->getType()->getArrayElementType(); 1430b57cec5SDimitry Andric for (unsigned i = 3, e = GEP->getNumOperands(); i != e; ++i) { 1440b57cec5SDimitry Andric ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(i)); 145647cbc5dSDimitry Andric if (!Idx) 146647cbc5dSDimitry Andric return nullptr; // Variable index. 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric uint64_t IdxVal = Idx->getZExtValue(); 149647cbc5dSDimitry Andric if ((unsigned)IdxVal != IdxVal) 150647cbc5dSDimitry Andric return nullptr; // Too large array index. 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric if (StructType *STy = dyn_cast<StructType>(EltTy)) 1530b57cec5SDimitry Andric EltTy = STy->getElementType(IdxVal); 1540b57cec5SDimitry Andric else if (ArrayType *ATy = dyn_cast<ArrayType>(EltTy)) { 155647cbc5dSDimitry Andric if (IdxVal >= ATy->getNumElements()) 156647cbc5dSDimitry Andric return nullptr; 1570b57cec5SDimitry Andric EltTy = ATy->getElementType(); 1580b57cec5SDimitry Andric } else { 1590b57cec5SDimitry Andric return nullptr; // Unknown type. 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric LaterIndices.push_back(IdxVal); 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric enum { Overdefined = -3, Undefined = -2 }; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric // Variables for our state machines. 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric // FirstTrueElement/SecondTrueElement - Used to emit a comparison of the form 1700b57cec5SDimitry Andric // "i == 47 | i == 87", where 47 is the first index the condition is true for, 1710b57cec5SDimitry Andric // and 87 is the second (and last) index. FirstTrueElement is -2 when 1720b57cec5SDimitry Andric // undefined, otherwise set to the first true element. SecondTrueElement is 1730b57cec5SDimitry Andric // -2 when undefined, -3 when overdefined and >= 0 when that index is true. 1740b57cec5SDimitry Andric int FirstTrueElement = Undefined, SecondTrueElement = Undefined; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric // FirstFalseElement/SecondFalseElement - Used to emit a comparison of the 1770b57cec5SDimitry Andric // form "i != 47 & i != 87". Same state transitions as for true elements. 1780b57cec5SDimitry Andric int FirstFalseElement = Undefined, SecondFalseElement = Undefined; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// TrueRangeEnd/FalseRangeEnd - In conjunction with First*Element, these 1810b57cec5SDimitry Andric /// define a state machine that triggers for ranges of values that the index 1820b57cec5SDimitry Andric /// is true or false for. This triggers on things like "abbbbc"[i] == 'b'. 1830b57cec5SDimitry Andric /// This is -2 when undefined, -3 when overdefined, and otherwise the last 1840b57cec5SDimitry Andric /// index in the range (inclusive). We use -2 for undefined here because we 1850b57cec5SDimitry Andric /// use relative comparisons and don't want 0-1 to match -1. 1860b57cec5SDimitry Andric int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric // MagicBitvector - This is a magic bitvector where we set a bit if the 1890b57cec5SDimitry Andric // comparison is true for element 'i'. If there are 64 elements or less in 1900b57cec5SDimitry Andric // the array, this will fully represent all the comparison results. 1910b57cec5SDimitry Andric uint64_t MagicBitvector = 0; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric // Scan the array and see if one of our patterns matches. 1940b57cec5SDimitry Andric Constant *CompareRHS = cast<Constant>(ICI.getOperand(1)); 1950b57cec5SDimitry Andric for (unsigned i = 0, e = ArrayElementCount; i != e; ++i) { 1960b57cec5SDimitry Andric Constant *Elt = Init->getAggregateElement(i); 197647cbc5dSDimitry Andric if (!Elt) 198647cbc5dSDimitry Andric return nullptr; 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric // If this is indexing an array of structures, get the structure element. 20181ad6265SDimitry Andric if (!LaterIndices.empty()) { 20281ad6265SDimitry Andric Elt = ConstantFoldExtractValueInstruction(Elt, LaterIndices); 20381ad6265SDimitry Andric if (!Elt) 20481ad6265SDimitry Andric return nullptr; 20581ad6265SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric // If the element is masked, handle it. 20806c3fb27SDimitry Andric if (AndCst) { 20906c3fb27SDimitry Andric Elt = ConstantFoldBinaryOpOperands(Instruction::And, Elt, AndCst, DL); 21006c3fb27SDimitry Andric if (!Elt) 21106c3fb27SDimitry Andric return nullptr; 21206c3fb27SDimitry Andric } 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric // Find out if the comparison would be true or false for the i'th element. 2150b57cec5SDimitry Andric Constant *C = ConstantFoldCompareInstOperands(ICI.getPredicate(), Elt, 2160b57cec5SDimitry Andric CompareRHS, DL, &TLI); 217*0fca6ea1SDimitry Andric if (!C) 218*0fca6ea1SDimitry Andric return nullptr; 219*0fca6ea1SDimitry Andric 2200b57cec5SDimitry Andric // If the result is undef for this element, ignore it. 2210b57cec5SDimitry Andric if (isa<UndefValue>(C)) { 2220b57cec5SDimitry Andric // Extend range state machines to cover this element in case there is an 2230b57cec5SDimitry Andric // undef in the middle of the range. 2240b57cec5SDimitry Andric if (TrueRangeEnd == (int)i - 1) 2250b57cec5SDimitry Andric TrueRangeEnd = i; 2260b57cec5SDimitry Andric if (FalseRangeEnd == (int)i - 1) 2270b57cec5SDimitry Andric FalseRangeEnd = i; 2280b57cec5SDimitry Andric continue; 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric // If we can't compute the result for any of the elements, we have to give 2320b57cec5SDimitry Andric // up evaluating the entire conditional. 233647cbc5dSDimitry Andric if (!isa<ConstantInt>(C)) 234647cbc5dSDimitry Andric return nullptr; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Otherwise, we know if the comparison is true or false for this element, 2370b57cec5SDimitry Andric // update our state machines. 2380b57cec5SDimitry Andric bool IsTrueForElt = !cast<ConstantInt>(C)->isZero(); 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric // State machine for single/double/range index comparison. 2410b57cec5SDimitry Andric if (IsTrueForElt) { 2420b57cec5SDimitry Andric // Update the TrueElement state machine. 2430b57cec5SDimitry Andric if (FirstTrueElement == Undefined) 2440b57cec5SDimitry Andric FirstTrueElement = TrueRangeEnd = i; // First true element. 2450b57cec5SDimitry Andric else { 2460b57cec5SDimitry Andric // Update double-compare state machine. 2470b57cec5SDimitry Andric if (SecondTrueElement == Undefined) 2480b57cec5SDimitry Andric SecondTrueElement = i; 2490b57cec5SDimitry Andric else 2500b57cec5SDimitry Andric SecondTrueElement = Overdefined; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric // Update range state machine. 2530b57cec5SDimitry Andric if (TrueRangeEnd == (int)i - 1) 2540b57cec5SDimitry Andric TrueRangeEnd = i; 2550b57cec5SDimitry Andric else 2560b57cec5SDimitry Andric TrueRangeEnd = Overdefined; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric } else { 2590b57cec5SDimitry Andric // Update the FalseElement state machine. 2600b57cec5SDimitry Andric if (FirstFalseElement == Undefined) 2610b57cec5SDimitry Andric FirstFalseElement = FalseRangeEnd = i; // First false element. 2620b57cec5SDimitry Andric else { 2630b57cec5SDimitry Andric // Update double-compare state machine. 2640b57cec5SDimitry Andric if (SecondFalseElement == Undefined) 2650b57cec5SDimitry Andric SecondFalseElement = i; 2660b57cec5SDimitry Andric else 2670b57cec5SDimitry Andric SecondFalseElement = Overdefined; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric // Update range state machine. 2700b57cec5SDimitry Andric if (FalseRangeEnd == (int)i - 1) 2710b57cec5SDimitry Andric FalseRangeEnd = i; 2720b57cec5SDimitry Andric else 2730b57cec5SDimitry Andric FalseRangeEnd = Overdefined; 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // If this element is in range, update our magic bitvector. 2780b57cec5SDimitry Andric if (i < 64 && IsTrueForElt) 2790b57cec5SDimitry Andric MagicBitvector |= 1ULL << i; 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric // If all of our states become overdefined, bail out early. Since the 2820b57cec5SDimitry Andric // predicate is expensive, only check it every 8 elements. This is only 2830b57cec5SDimitry Andric // really useful for really huge arrays. 2840b57cec5SDimitry Andric if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined && 2850b57cec5SDimitry Andric SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined && 2860b57cec5SDimitry Andric FalseRangeEnd == Overdefined) 2870b57cec5SDimitry Andric return nullptr; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric // Now that we've scanned the entire array, emit our new comparison(s). We 2910b57cec5SDimitry Andric // order the state machines in complexity of the generated code. 2920b57cec5SDimitry Andric Value *Idx = GEP->getOperand(2); 2930b57cec5SDimitry Andric 29406c3fb27SDimitry Andric // If the index is larger than the pointer offset size of the target, truncate 29506c3fb27SDimitry Andric // the index down like the GEP would do implicitly. We don't have to do this 29606c3fb27SDimitry Andric // for an inbounds GEP because the index can't be out of range. 2970b57cec5SDimitry Andric if (!GEP->isInBounds()) { 29806c3fb27SDimitry Andric Type *PtrIdxTy = DL.getIndexType(GEP->getType()); 29906c3fb27SDimitry Andric unsigned OffsetSize = PtrIdxTy->getIntegerBitWidth(); 30006c3fb27SDimitry Andric if (Idx->getType()->getPrimitiveSizeInBits().getFixedValue() > OffsetSize) 30106c3fb27SDimitry Andric Idx = Builder.CreateTrunc(Idx, PtrIdxTy); 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 304fe6060f1SDimitry Andric // If inbounds keyword is not present, Idx * ElementSize can overflow. 305fe6060f1SDimitry Andric // Let's assume that ElementSize is 2 and the wanted value is at offset 0. 306fe6060f1SDimitry Andric // Then, there are two possible values for Idx to match offset 0: 307fe6060f1SDimitry Andric // 0x00..00, 0x80..00. 308fe6060f1SDimitry Andric // Emitting 'icmp eq Idx, 0' isn't correct in this case because the 309fe6060f1SDimitry Andric // comparison is false if Idx was 0x80..00. 310fe6060f1SDimitry Andric // We need to erase the highest countTrailingZeros(ElementSize) bits of Idx. 311fe6060f1SDimitry Andric unsigned ElementSize = 312fe6060f1SDimitry Andric DL.getTypeAllocSize(Init->getType()->getArrayElementType()); 313fe6060f1SDimitry Andric auto MaskIdx = [&](Value *Idx) { 31406c3fb27SDimitry Andric if (!GEP->isInBounds() && llvm::countr_zero(ElementSize) != 0) { 315fe6060f1SDimitry Andric Value *Mask = ConstantInt::get(Idx->getType(), -1); 31606c3fb27SDimitry Andric Mask = Builder.CreateLShr(Mask, llvm::countr_zero(ElementSize)); 317fe6060f1SDimitry Andric Idx = Builder.CreateAnd(Idx, Mask); 318fe6060f1SDimitry Andric } 319fe6060f1SDimitry Andric return Idx; 320fe6060f1SDimitry Andric }; 321fe6060f1SDimitry Andric 3220b57cec5SDimitry Andric // If the comparison is only true for one or two elements, emit direct 3230b57cec5SDimitry Andric // comparisons. 3240b57cec5SDimitry Andric if (SecondTrueElement != Overdefined) { 325fe6060f1SDimitry Andric Idx = MaskIdx(Idx); 3260b57cec5SDimitry Andric // None true -> false. 3270b57cec5SDimitry Andric if (FirstTrueElement == Undefined) 3280b57cec5SDimitry Andric return replaceInstUsesWith(ICI, Builder.getFalse()); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric Value *FirstTrueIdx = ConstantInt::get(Idx->getType(), FirstTrueElement); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric // True for one element -> 'i == 47'. 3330b57cec5SDimitry Andric if (SecondTrueElement == Undefined) 3340b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Idx, FirstTrueIdx); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric // True for two elements -> 'i == 47 | i == 72'. 3370b57cec5SDimitry Andric Value *C1 = Builder.CreateICmpEQ(Idx, FirstTrueIdx); 3380b57cec5SDimitry Andric Value *SecondTrueIdx = ConstantInt::get(Idx->getType(), SecondTrueElement); 3390b57cec5SDimitry Andric Value *C2 = Builder.CreateICmpEQ(Idx, SecondTrueIdx); 3400b57cec5SDimitry Andric return BinaryOperator::CreateOr(C1, C2); 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric // If the comparison is only false for one or two elements, emit direct 3440b57cec5SDimitry Andric // comparisons. 3450b57cec5SDimitry Andric if (SecondFalseElement != Overdefined) { 346fe6060f1SDimitry Andric Idx = MaskIdx(Idx); 3470b57cec5SDimitry Andric // None false -> true. 3480b57cec5SDimitry Andric if (FirstFalseElement == Undefined) 3490b57cec5SDimitry Andric return replaceInstUsesWith(ICI, Builder.getTrue()); 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric Value *FirstFalseIdx = ConstantInt::get(Idx->getType(), FirstFalseElement); 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric // False for one element -> 'i != 47'. 3540b57cec5SDimitry Andric if (SecondFalseElement == Undefined) 3550b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Idx, FirstFalseIdx); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric // False for two elements -> 'i != 47 & i != 72'. 3580b57cec5SDimitry Andric Value *C1 = Builder.CreateICmpNE(Idx, FirstFalseIdx); 359647cbc5dSDimitry Andric Value *SecondFalseIdx = 360647cbc5dSDimitry Andric ConstantInt::get(Idx->getType(), SecondFalseElement); 3610b57cec5SDimitry Andric Value *C2 = Builder.CreateICmpNE(Idx, SecondFalseIdx); 3620b57cec5SDimitry Andric return BinaryOperator::CreateAnd(C1, C2); 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric // If the comparison can be replaced with a range comparison for the elements 3660b57cec5SDimitry Andric // where it is true, emit the range check. 3670b57cec5SDimitry Andric if (TrueRangeEnd != Overdefined) { 3680b57cec5SDimitry Andric assert(TrueRangeEnd != FirstTrueElement && "Should emit single compare"); 369fe6060f1SDimitry Andric Idx = MaskIdx(Idx); 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric // Generate (i-FirstTrue) <u (TrueRangeEnd-FirstTrue+1). 3720b57cec5SDimitry Andric if (FirstTrueElement) { 3730b57cec5SDimitry Andric Value *Offs = ConstantInt::get(Idx->getType(), -FirstTrueElement); 3740b57cec5SDimitry Andric Idx = Builder.CreateAdd(Idx, Offs); 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 377647cbc5dSDimitry Andric Value *End = 378647cbc5dSDimitry Andric ConstantInt::get(Idx->getType(), TrueRangeEnd - FirstTrueElement + 1); 3790b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULT, Idx, End); 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric // False range check. 3830b57cec5SDimitry Andric if (FalseRangeEnd != Overdefined) { 3840b57cec5SDimitry Andric assert(FalseRangeEnd != FirstFalseElement && "Should emit single compare"); 385fe6060f1SDimitry Andric Idx = MaskIdx(Idx); 3860b57cec5SDimitry Andric // Generate (i-FirstFalse) >u (FalseRangeEnd-FirstFalse). 3870b57cec5SDimitry Andric if (FirstFalseElement) { 3880b57cec5SDimitry Andric Value *Offs = ConstantInt::get(Idx->getType(), -FirstFalseElement); 3890b57cec5SDimitry Andric Idx = Builder.CreateAdd(Idx, Offs); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 392647cbc5dSDimitry Andric Value *End = 393647cbc5dSDimitry Andric ConstantInt::get(Idx->getType(), FalseRangeEnd - FirstFalseElement); 3940b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, Idx, End); 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric // If a magic bitvector captures the entire comparison state 3980b57cec5SDimitry Andric // of this load, replace it with computation that does: 3990b57cec5SDimitry Andric // ((magic_cst >> i) & 1) != 0 4000b57cec5SDimitry Andric { 4010b57cec5SDimitry Andric Type *Ty = nullptr; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric // Look for an appropriate type: 4040b57cec5SDimitry Andric // - The type of Idx if the magic fits 4050b57cec5SDimitry Andric // - The smallest fitting legal type 4060b57cec5SDimitry Andric if (ArrayElementCount <= Idx->getType()->getIntegerBitWidth()) 4070b57cec5SDimitry Andric Ty = Idx->getType(); 4080b57cec5SDimitry Andric else 4090b57cec5SDimitry Andric Ty = DL.getSmallestLegalIntType(Init->getContext(), ArrayElementCount); 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric if (Ty) { 412fe6060f1SDimitry Andric Idx = MaskIdx(Idx); 4130b57cec5SDimitry Andric Value *V = Builder.CreateIntCast(Idx, Ty, false); 4140b57cec5SDimitry Andric V = Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V); 4150b57cec5SDimitry Andric V = Builder.CreateAnd(ConstantInt::get(Ty, 1), V); 4160b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, V, ConstantInt::get(Ty, 0)); 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric return nullptr; 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric /// Returns true if we can rewrite Start as a GEP with pointer Base 4240b57cec5SDimitry Andric /// and some integer offset. The nodes that need to be re-written 4250b57cec5SDimitry Andric /// for this transformation will be added to Explored. 4265f757f3fSDimitry Andric static bool canRewriteGEPAsOffset(Value *Start, Value *Base, 4270b57cec5SDimitry Andric const DataLayout &DL, 4280b57cec5SDimitry Andric SetVector<Value *> &Explored) { 4290b57cec5SDimitry Andric SmallVector<Value *, 16> WorkList(1, Start); 4300b57cec5SDimitry Andric Explored.insert(Base); 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric // The following traversal gives us an order which can be used 4330b57cec5SDimitry Andric // when doing the final transformation. Since in the final 4340b57cec5SDimitry Andric // transformation we create the PHI replacement instructions first, 4350b57cec5SDimitry Andric // we don't have to get them in any particular order. 4360b57cec5SDimitry Andric // 4370b57cec5SDimitry Andric // However, for other instructions we will have to traverse the 4380b57cec5SDimitry Andric // operands of an instruction first, which means that we have to 4390b57cec5SDimitry Andric // do a post-order traversal. 4400b57cec5SDimitry Andric while (!WorkList.empty()) { 4410b57cec5SDimitry Andric SetVector<PHINode *> PHIs; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric while (!WorkList.empty()) { 4440b57cec5SDimitry Andric if (Explored.size() >= 100) 4450b57cec5SDimitry Andric return false; 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric Value *V = WorkList.back(); 4480b57cec5SDimitry Andric 449e8d8bef9SDimitry Andric if (Explored.contains(V)) { 4500b57cec5SDimitry Andric WorkList.pop_back(); 4510b57cec5SDimitry Andric continue; 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4545f757f3fSDimitry Andric if (!isa<GetElementPtrInst>(V) && !isa<PHINode>(V)) 4550b57cec5SDimitry Andric // We've found some value that we can't explore which is different from 4560b57cec5SDimitry Andric // the base. Therefore we can't do this transformation. 4570b57cec5SDimitry Andric return false; 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric if (auto *GEP = dyn_cast<GEPOperator>(V)) { 4605f757f3fSDimitry Andric // Only allow inbounds GEPs with at most one variable offset. 4615f757f3fSDimitry Andric auto IsNonConst = [](Value *V) { return !isa<ConstantInt>(V); }; 4625f757f3fSDimitry Andric if (!GEP->isInBounds() || count_if(GEP->indices(), IsNonConst) > 1) 4630b57cec5SDimitry Andric return false; 4640b57cec5SDimitry Andric 465349cc55cSDimitry Andric if (!Explored.contains(GEP->getOperand(0))) 4660b57cec5SDimitry Andric WorkList.push_back(GEP->getOperand(0)); 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric if (WorkList.back() == V) { 4700b57cec5SDimitry Andric WorkList.pop_back(); 4710b57cec5SDimitry Andric // We've finished visiting this node, mark it as such. 4720b57cec5SDimitry Andric Explored.insert(V); 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric if (auto *PN = dyn_cast<PHINode>(V)) { 4760b57cec5SDimitry Andric // We cannot transform PHIs on unsplittable basic blocks. 4770b57cec5SDimitry Andric if (isa<CatchSwitchInst>(PN->getParent()->getTerminator())) 4780b57cec5SDimitry Andric return false; 4790b57cec5SDimitry Andric Explored.insert(PN); 4800b57cec5SDimitry Andric PHIs.insert(PN); 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric // Explore the PHI nodes further. 4850b57cec5SDimitry Andric for (auto *PN : PHIs) 4860b57cec5SDimitry Andric for (Value *Op : PN->incoming_values()) 487349cc55cSDimitry Andric if (!Explored.contains(Op)) 4880b57cec5SDimitry Andric WorkList.push_back(Op); 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric // Make sure that we can do this. Since we can't insert GEPs in a basic 4920b57cec5SDimitry Andric // block before a PHI node, we can't easily do this transformation if 4930b57cec5SDimitry Andric // we have PHI node users of transformed instructions. 4940b57cec5SDimitry Andric for (Value *Val : Explored) { 4950b57cec5SDimitry Andric for (Value *Use : Val->uses()) { 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric auto *PHI = dyn_cast<PHINode>(Use); 4980b57cec5SDimitry Andric auto *Inst = dyn_cast<Instruction>(Val); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric if (Inst == Base || Inst == PHI || !Inst || !PHI || 501349cc55cSDimitry Andric !Explored.contains(PHI)) 5020b57cec5SDimitry Andric continue; 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric if (PHI->getParent() == Inst->getParent()) 5050b57cec5SDimitry Andric return false; 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric } 5080b57cec5SDimitry Andric return true; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric // Sets the appropriate insert point on Builder where we can add 5120b57cec5SDimitry Andric // a replacement Instruction for V (if that is possible). 5130b57cec5SDimitry Andric static void setInsertionPoint(IRBuilder<> &Builder, Value *V, 5140b57cec5SDimitry Andric bool Before = true) { 5150b57cec5SDimitry Andric if (auto *PHI = dyn_cast<PHINode>(V)) { 5165f757f3fSDimitry Andric BasicBlock *Parent = PHI->getParent(); 5175f757f3fSDimitry Andric Builder.SetInsertPoint(Parent, Parent->getFirstInsertionPt()); 5180b57cec5SDimitry Andric return; 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric if (auto *I = dyn_cast<Instruction>(V)) { 5210b57cec5SDimitry Andric if (!Before) 5220b57cec5SDimitry Andric I = &*std::next(I->getIterator()); 5230b57cec5SDimitry Andric Builder.SetInsertPoint(I); 5240b57cec5SDimitry Andric return; 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric if (auto *A = dyn_cast<Argument>(V)) { 5270b57cec5SDimitry Andric // Set the insertion point in the entry block. 5280b57cec5SDimitry Andric BasicBlock &Entry = A->getParent()->getEntryBlock(); 5295f757f3fSDimitry Andric Builder.SetInsertPoint(&Entry, Entry.getFirstInsertionPt()); 5300b57cec5SDimitry Andric return; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric // Otherwise, this is a constant and we don't need to set a new 5330b57cec5SDimitry Andric // insertion point. 5340b57cec5SDimitry Andric assert(isa<Constant>(V) && "Setting insertion point for unknown value!"); 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric /// Returns a re-written value of Start as an indexed GEP using Base as a 5380b57cec5SDimitry Andric /// pointer. 5395f757f3fSDimitry Andric static Value *rewriteGEPAsOffset(Value *Start, Value *Base, 5400b57cec5SDimitry Andric const DataLayout &DL, 54106c3fb27SDimitry Andric SetVector<Value *> &Explored, 54206c3fb27SDimitry Andric InstCombiner &IC) { 5430b57cec5SDimitry Andric // Perform all the substitutions. This is a bit tricky because we can 5440b57cec5SDimitry Andric // have cycles in our use-def chains. 5450b57cec5SDimitry Andric // 1. Create the PHI nodes without any incoming values. 5460b57cec5SDimitry Andric // 2. Create all the other values. 5470b57cec5SDimitry Andric // 3. Add the edges for the PHI nodes. 5480b57cec5SDimitry Andric // 4. Emit GEPs to get the original pointers. 5490b57cec5SDimitry Andric // 5. Remove the original instructions. 5500b57cec5SDimitry Andric Type *IndexType = IntegerType::get( 5510b57cec5SDimitry Andric Base->getContext(), DL.getIndexTypeSizeInBits(Start->getType())); 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric DenseMap<Value *, Value *> NewInsts; 5540b57cec5SDimitry Andric NewInsts[Base] = ConstantInt::getNullValue(IndexType); 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric // Create the new PHI nodes, without adding any incoming values. 5570b57cec5SDimitry Andric for (Value *Val : Explored) { 5580b57cec5SDimitry Andric if (Val == Base) 5590b57cec5SDimitry Andric continue; 5600b57cec5SDimitry Andric // Create empty phi nodes. This avoids cyclic dependencies when creating 5610b57cec5SDimitry Andric // the remaining instructions. 5620b57cec5SDimitry Andric if (auto *PHI = dyn_cast<PHINode>(Val)) 563*0fca6ea1SDimitry Andric NewInsts[PHI] = 564*0fca6ea1SDimitry Andric PHINode::Create(IndexType, PHI->getNumIncomingValues(), 565*0fca6ea1SDimitry Andric PHI->getName() + ".idx", PHI->getIterator()); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric IRBuilder<> Builder(Base->getContext()); 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric // Create all the other instructions. 5700b57cec5SDimitry Andric for (Value *Val : Explored) { 57106c3fb27SDimitry Andric if (NewInsts.contains(Val)) 5720b57cec5SDimitry Andric continue; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric if (auto *GEP = dyn_cast<GEPOperator>(Val)) { 5750b57cec5SDimitry Andric setInsertionPoint(Builder, GEP); 5765f757f3fSDimitry Andric Value *Op = NewInsts[GEP->getOperand(0)]; 5775f757f3fSDimitry Andric Value *OffsetV = emitGEPOffset(&Builder, DL, GEP); 5780b57cec5SDimitry Andric if (isa<ConstantInt>(Op) && cast<ConstantInt>(Op)->isZero()) 5795f757f3fSDimitry Andric NewInsts[GEP] = OffsetV; 5800b57cec5SDimitry Andric else 5810b57cec5SDimitry Andric NewInsts[GEP] = Builder.CreateNSWAdd( 5825f757f3fSDimitry Andric Op, OffsetV, GEP->getOperand(0)->getName() + ".add"); 5830b57cec5SDimitry Andric continue; 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric if (isa<PHINode>(Val)) 5860b57cec5SDimitry Andric continue; 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric llvm_unreachable("Unexpected instruction type"); 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric // Add the incoming values to the PHI nodes. 5920b57cec5SDimitry Andric for (Value *Val : Explored) { 5930b57cec5SDimitry Andric if (Val == Base) 5940b57cec5SDimitry Andric continue; 5950b57cec5SDimitry Andric // All the instructions have been created, we can now add edges to the 5960b57cec5SDimitry Andric // phi nodes. 5970b57cec5SDimitry Andric if (auto *PHI = dyn_cast<PHINode>(Val)) { 5980b57cec5SDimitry Andric PHINode *NewPhi = static_cast<PHINode *>(NewInsts[PHI]); 5990b57cec5SDimitry Andric for (unsigned I = 0, E = PHI->getNumIncomingValues(); I < E; ++I) { 6000b57cec5SDimitry Andric Value *NewIncoming = PHI->getIncomingValue(I); 6010b57cec5SDimitry Andric 60206c3fb27SDimitry Andric if (NewInsts.contains(NewIncoming)) 6030b57cec5SDimitry Andric NewIncoming = NewInsts[NewIncoming]; 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric NewPhi->addIncoming(NewIncoming, PHI->getIncomingBlock(I)); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric } 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric for (Value *Val : Explored) { 6110b57cec5SDimitry Andric if (Val == Base) 6120b57cec5SDimitry Andric continue; 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric setInsertionPoint(Builder, Val, false); 6155f757f3fSDimitry Andric // Create GEP for external users. 6165f757f3fSDimitry Andric Value *NewVal = Builder.CreateInBoundsGEP( 6175f757f3fSDimitry Andric Builder.getInt8Ty(), Base, NewInsts[Val], Val->getName() + ".ptr"); 61806c3fb27SDimitry Andric IC.replaceInstUsesWith(*cast<Instruction>(Val), NewVal); 61906c3fb27SDimitry Andric // Add old instruction to worklist for DCE. We don't directly remove it 62006c3fb27SDimitry Andric // here because the original compare is one of the users. 62106c3fb27SDimitry Andric IC.addToWorklist(cast<Instruction>(Val)); 6220b57cec5SDimitry Andric } 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric return NewInsts[Start]; 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric /// Converts (CMP GEPLHS, RHS) if this change would make RHS a constant. 6280b57cec5SDimitry Andric /// We can look through PHIs, GEPs and casts in order to determine a common base 6290b57cec5SDimitry Andric /// between GEPLHS and RHS. 6300b57cec5SDimitry Andric static Instruction *transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, 6310b57cec5SDimitry Andric ICmpInst::Predicate Cond, 63206c3fb27SDimitry Andric const DataLayout &DL, 63306c3fb27SDimitry Andric InstCombiner &IC) { 6340b57cec5SDimitry Andric // FIXME: Support vector of pointers. 6350b57cec5SDimitry Andric if (GEPLHS->getType()->isVectorTy()) 6360b57cec5SDimitry Andric return nullptr; 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric if (!GEPLHS->hasAllConstantIndices()) 6390b57cec5SDimitry Andric return nullptr; 6400b57cec5SDimitry Andric 6415f757f3fSDimitry Andric APInt Offset(DL.getIndexTypeSizeInBits(GEPLHS->getType()), 0); 6425f757f3fSDimitry Andric Value *PtrBase = 6435f757f3fSDimitry Andric GEPLHS->stripAndAccumulateConstantOffsets(DL, Offset, 6445f757f3fSDimitry Andric /*AllowNonInbounds*/ false); 6455f757f3fSDimitry Andric 6465f757f3fSDimitry Andric // Bail if we looked through addrspacecast. 6475f757f3fSDimitry Andric if (PtrBase->getType() != GEPLHS->getType()) 6485f757f3fSDimitry Andric return nullptr; 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric // The set of nodes that will take part in this transformation. 6510b57cec5SDimitry Andric SetVector<Value *> Nodes; 6520b57cec5SDimitry Andric 6535f757f3fSDimitry Andric if (!canRewriteGEPAsOffset(RHS, PtrBase, DL, Nodes)) 6540b57cec5SDimitry Andric return nullptr; 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric // We know we can re-write this as 6570b57cec5SDimitry Andric // ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) 6580b57cec5SDimitry Andric // Since we've only looked through inbouds GEPs we know that we 6590b57cec5SDimitry Andric // can't have overflow on either side. We can therefore re-write 6600b57cec5SDimitry Andric // this as: 6610b57cec5SDimitry Andric // OFFSET1 cmp OFFSET2 6625f757f3fSDimitry Andric Value *NewRHS = rewriteGEPAsOffset(RHS, PtrBase, DL, Nodes, IC); 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric // RewriteGEPAsOffset has replaced RHS and all of its uses with a re-written 6650b57cec5SDimitry Andric // GEP having PtrBase as the pointer base, and has returned in NewRHS the 6660b57cec5SDimitry Andric // offset. Since Index is the offset of LHS to the base pointer, we will now 6670b57cec5SDimitry Andric // compare the offsets instead of comparing the pointers. 6685f757f3fSDimitry Andric return new ICmpInst(ICmpInst::getSignedPredicate(Cond), 6695f757f3fSDimitry Andric IC.Builder.getInt(Offset), NewRHS); 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric /// Fold comparisons between a GEP instruction and something else. At this point 6730b57cec5SDimitry Andric /// we know that the GEP is on the LHS of the comparison. 674e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, 6750b57cec5SDimitry Andric ICmpInst::Predicate Cond, 6760b57cec5SDimitry Andric Instruction &I) { 6770b57cec5SDimitry Andric // Don't transform signed compares of GEPs into index compares. Even if the 6780b57cec5SDimitry Andric // GEP is inbounds, the final add of the base pointer can have signed overflow 6790b57cec5SDimitry Andric // and would change the result of the icmp. 6800b57cec5SDimitry Andric // e.g. "&foo[0] <s &foo[1]" can't be folded to "true" because "foo" could be 6810b57cec5SDimitry Andric // the maximum signed value for the pointer type. 6820b57cec5SDimitry Andric if (ICmpInst::isSigned(Cond)) 6830b57cec5SDimitry Andric return nullptr; 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric // Look through bitcasts and addrspacecasts. We do not however want to remove 6860b57cec5SDimitry Andric // 0 GEPs. 6870b57cec5SDimitry Andric if (!isa<GetElementPtrInst>(RHS)) 6880b57cec5SDimitry Andric RHS = RHS->stripPointerCasts(); 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric Value *PtrBase = GEPLHS->getOperand(0); 69106c3fb27SDimitry Andric if (PtrBase == RHS && (GEPLHS->isInBounds() || ICmpInst::isEquality(Cond))) { 6920b57cec5SDimitry Andric // ((gep Ptr, OFFSET) cmp Ptr) ---> (OFFSET cmp 0). 693bdd1243dSDimitry Andric Value *Offset = EmitGEPOffset(GEPLHS); 6940b57cec5SDimitry Andric return new ICmpInst(ICmpInst::getSignedPredicate(Cond), Offset, 6950b57cec5SDimitry Andric Constant::getNullValue(Offset->getType())); 6968bcb0991SDimitry Andric } 6978bcb0991SDimitry Andric 6988bcb0991SDimitry Andric if (GEPLHS->isInBounds() && ICmpInst::isEquality(Cond) && 6998bcb0991SDimitry Andric isa<Constant>(RHS) && cast<Constant>(RHS)->isNullValue() && 7008bcb0991SDimitry Andric !NullPointerIsDefined(I.getFunction(), 7018bcb0991SDimitry Andric RHS->getType()->getPointerAddressSpace())) { 7028bcb0991SDimitry Andric // For most address spaces, an allocation can't be placed at null, but null 7038bcb0991SDimitry Andric // itself is treated as a 0 size allocation in the in bounds rules. Thus, 7048bcb0991SDimitry Andric // the only valid inbounds address derived from null, is null itself. 7058bcb0991SDimitry Andric // Thus, we have four cases to consider: 7068bcb0991SDimitry Andric // 1) Base == nullptr, Offset == 0 -> inbounds, null 7078bcb0991SDimitry Andric // 2) Base == nullptr, Offset != 0 -> poison as the result is out of bounds 7088bcb0991SDimitry Andric // 3) Base != nullptr, Offset == (-base) -> poison (crossing allocations) 7098bcb0991SDimitry Andric // 4) Base != nullptr, Offset != (-base) -> nonnull (and possibly poison) 7108bcb0991SDimitry Andric // 7118bcb0991SDimitry Andric // (Note if we're indexing a type of size 0, that simply collapses into one 7128bcb0991SDimitry Andric // of the buckets above.) 7138bcb0991SDimitry Andric // 7148bcb0991SDimitry Andric // In general, we're allowed to make values less poison (i.e. remove 7158bcb0991SDimitry Andric // sources of full UB), so in this case, we just select between the two 7168bcb0991SDimitry Andric // non-poison cases (1 and 4 above). 7178bcb0991SDimitry Andric // 7188bcb0991SDimitry Andric // For vectors, we apply the same reasoning on a per-lane basis. 7198bcb0991SDimitry Andric auto *Base = GEPLHS->getPointerOperand(); 7208bcb0991SDimitry Andric if (GEPLHS->getType()->isVectorTy() && Base->getType()->isPointerTy()) { 721e8d8bef9SDimitry Andric auto EC = cast<VectorType>(GEPLHS->getType())->getElementCount(); 722e8d8bef9SDimitry Andric Base = Builder.CreateVectorSplat(EC, Base); 7238bcb0991SDimitry Andric } 7248bcb0991SDimitry Andric return new ICmpInst(Cond, Base, 7258bcb0991SDimitry Andric ConstantExpr::getPointerBitCastOrAddrSpaceCast( 7268bcb0991SDimitry Andric cast<Constant>(RHS), Base->getType())); 7270b57cec5SDimitry Andric } else if (GEPOperator *GEPRHS = dyn_cast<GEPOperator>(RHS)) { 7280b57cec5SDimitry Andric // If the base pointers are different, but the indices are the same, just 7290b57cec5SDimitry Andric // compare the base pointer. 7300b57cec5SDimitry Andric if (PtrBase != GEPRHS->getOperand(0)) { 73104eeddc0SDimitry Andric bool IndicesTheSame = 73204eeddc0SDimitry Andric GEPLHS->getNumOperands() == GEPRHS->getNumOperands() && 73381ad6265SDimitry Andric GEPLHS->getPointerOperand()->getType() == 73481ad6265SDimitry Andric GEPRHS->getPointerOperand()->getType() && 73504eeddc0SDimitry Andric GEPLHS->getSourceElementType() == GEPRHS->getSourceElementType(); 7360b57cec5SDimitry Andric if (IndicesTheSame) 7370b57cec5SDimitry Andric for (unsigned i = 1, e = GEPLHS->getNumOperands(); i != e; ++i) 7380b57cec5SDimitry Andric if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) { 7390b57cec5SDimitry Andric IndicesTheSame = false; 7400b57cec5SDimitry Andric break; 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric // If all indices are the same, just compare the base pointers. 7440b57cec5SDimitry Andric Type *BaseType = GEPLHS->getOperand(0)->getType(); 7450b57cec5SDimitry Andric if (IndicesTheSame && CmpInst::makeCmpResultType(BaseType) == I.getType()) 7460b57cec5SDimitry Andric return new ICmpInst(Cond, GEPLHS->getOperand(0), GEPRHS->getOperand(0)); 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric // If we're comparing GEPs with two base pointers that only differ in type 7490b57cec5SDimitry Andric // and both GEPs have only constant indices or just one use, then fold 7500b57cec5SDimitry Andric // the compare with the adjusted indices. 7510b57cec5SDimitry Andric // FIXME: Support vector of pointers. 7520b57cec5SDimitry Andric if (GEPLHS->isInBounds() && GEPRHS->isInBounds() && 7530b57cec5SDimitry Andric (GEPLHS->hasAllConstantIndices() || GEPLHS->hasOneUse()) && 7540b57cec5SDimitry Andric (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) && 7550b57cec5SDimitry Andric PtrBase->stripPointerCasts() == 7560b57cec5SDimitry Andric GEPRHS->getOperand(0)->stripPointerCasts() && 7570b57cec5SDimitry Andric !GEPLHS->getType()->isVectorTy()) { 7580b57cec5SDimitry Andric Value *LOffset = EmitGEPOffset(GEPLHS); 7590b57cec5SDimitry Andric Value *ROffset = EmitGEPOffset(GEPRHS); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric // If we looked through an addrspacecast between different sized address 7620b57cec5SDimitry Andric // spaces, the LHS and RHS pointers are different sized 7630b57cec5SDimitry Andric // integers. Truncate to the smaller one. 7640b57cec5SDimitry Andric Type *LHSIndexTy = LOffset->getType(); 7650b57cec5SDimitry Andric Type *RHSIndexTy = ROffset->getType(); 7660b57cec5SDimitry Andric if (LHSIndexTy != RHSIndexTy) { 767bdd1243dSDimitry Andric if (LHSIndexTy->getPrimitiveSizeInBits().getFixedValue() < 768bdd1243dSDimitry Andric RHSIndexTy->getPrimitiveSizeInBits().getFixedValue()) { 7690b57cec5SDimitry Andric ROffset = Builder.CreateTrunc(ROffset, LHSIndexTy); 7700b57cec5SDimitry Andric } else 7710b57cec5SDimitry Andric LOffset = Builder.CreateTrunc(LOffset, RHSIndexTy); 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric Value *Cmp = Builder.CreateICmp(ICmpInst::getSignedPredicate(Cond), 7750b57cec5SDimitry Andric LOffset, ROffset); 7760b57cec5SDimitry Andric return replaceInstUsesWith(I, Cmp); 7770b57cec5SDimitry Andric } 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric // Otherwise, the base pointers are different and the indices are 7800b57cec5SDimitry Andric // different. Try convert this to an indexed compare by looking through 7810b57cec5SDimitry Andric // PHIs/casts. 78206c3fb27SDimitry Andric return transformToIndexedCompare(GEPLHS, RHS, Cond, DL, *this); 7830b57cec5SDimitry Andric } 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric bool GEPsInBounds = GEPLHS->isInBounds() && GEPRHS->isInBounds(); 78681ad6265SDimitry Andric if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands() && 78781ad6265SDimitry Andric GEPLHS->getSourceElementType() == GEPRHS->getSourceElementType()) { 7880b57cec5SDimitry Andric // If the GEPs only differ by one index, compare it. 7890b57cec5SDimitry Andric unsigned NumDifferences = 0; // Keep track of # differences. 7900b57cec5SDimitry Andric unsigned DiffOperand = 0; // The operand that differs. 7910b57cec5SDimitry Andric for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i) 7920b57cec5SDimitry Andric if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) { 7930b57cec5SDimitry Andric Type *LHSType = GEPLHS->getOperand(i)->getType(); 7940b57cec5SDimitry Andric Type *RHSType = GEPRHS->getOperand(i)->getType(); 7950b57cec5SDimitry Andric // FIXME: Better support for vector of pointers. 7960b57cec5SDimitry Andric if (LHSType->getPrimitiveSizeInBits() != 7970b57cec5SDimitry Andric RHSType->getPrimitiveSizeInBits() || 7980b57cec5SDimitry Andric (GEPLHS->getType()->isVectorTy() && 7990b57cec5SDimitry Andric (!LHSType->isVectorTy() || !RHSType->isVectorTy()))) { 8000b57cec5SDimitry Andric // Irreconcilable differences. 8010b57cec5SDimitry Andric NumDifferences = 2; 8020b57cec5SDimitry Andric break; 8030b57cec5SDimitry Andric } 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric if (NumDifferences++) break; 8060b57cec5SDimitry Andric DiffOperand = i; 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric if (NumDifferences == 0) // SAME GEP? 8100b57cec5SDimitry Andric return replaceInstUsesWith(I, // No comparison is needed here. 8110b57cec5SDimitry Andric ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond))); 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric else if (NumDifferences == 1 && GEPsInBounds) { 8140b57cec5SDimitry Andric Value *LHSV = GEPLHS->getOperand(DiffOperand); 8150b57cec5SDimitry Andric Value *RHSV = GEPRHS->getOperand(DiffOperand); 8160b57cec5SDimitry Andric // Make sure we do a signed comparison here. 8170b57cec5SDimitry Andric return new ICmpInst(ICmpInst::getSignedPredicate(Cond), LHSV, RHSV); 8180b57cec5SDimitry Andric } 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric 821*0fca6ea1SDimitry Andric if (GEPsInBounds || CmpInst::isEquality(Cond)) { 8220b57cec5SDimitry Andric // ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) ---> (OFFSET1 cmp OFFSET2) 823*0fca6ea1SDimitry Andric Value *L = EmitGEPOffset(GEPLHS, /*RewriteGEP=*/true); 824*0fca6ea1SDimitry Andric Value *R = EmitGEPOffset(GEPRHS, /*RewriteGEP=*/true); 8250b57cec5SDimitry Andric return new ICmpInst(ICmpInst::getSignedPredicate(Cond), L, R); 8260b57cec5SDimitry Andric } 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric // Try convert this to an indexed compare by looking through PHIs/casts as a 8300b57cec5SDimitry Andric // last resort. 83106c3fb27SDimitry Andric return transformToIndexedCompare(GEPLHS, RHS, Cond, DL, *this); 8320b57cec5SDimitry Andric } 8330b57cec5SDimitry Andric 83406c3fb27SDimitry Andric bool InstCombinerImpl::foldAllocaCmp(AllocaInst *Alloca) { 8350b57cec5SDimitry Andric // It would be tempting to fold away comparisons between allocas and any 8360b57cec5SDimitry Andric // pointer not based on that alloca (e.g. an argument). However, even 8370b57cec5SDimitry Andric // though such pointers cannot alias, they can still compare equal. 8380b57cec5SDimitry Andric // 8390b57cec5SDimitry Andric // But LLVM doesn't specify where allocas get their memory, so if the alloca 8400b57cec5SDimitry Andric // doesn't escape we can argue that it's impossible to guess its value, and we 8410b57cec5SDimitry Andric // can therefore act as if any such guesses are wrong. 8420b57cec5SDimitry Andric // 84306c3fb27SDimitry Andric // However, we need to ensure that this folding is consistent: We can't fold 84406c3fb27SDimitry Andric // one comparison to false, and then leave a different comparison against the 84506c3fb27SDimitry Andric // same value alone (as it might evaluate to true at runtime, leading to a 84606c3fb27SDimitry Andric // contradiction). As such, this code ensures that all comparisons are folded 84706c3fb27SDimitry Andric // at the same time, and there are no other escapes. 8480b57cec5SDimitry Andric 84906c3fb27SDimitry Andric struct CmpCaptureTracker : public CaptureTracker { 85006c3fb27SDimitry Andric AllocaInst *Alloca; 85106c3fb27SDimitry Andric bool Captured = false; 85206c3fb27SDimitry Andric /// The value of the map is a bit mask of which icmp operands the alloca is 85306c3fb27SDimitry Andric /// used in. 85406c3fb27SDimitry Andric SmallMapVector<ICmpInst *, unsigned, 4> ICmps; 8550b57cec5SDimitry Andric 85606c3fb27SDimitry Andric CmpCaptureTracker(AllocaInst *Alloca) : Alloca(Alloca) {} 85706c3fb27SDimitry Andric 85806c3fb27SDimitry Andric void tooManyUses() override { Captured = true; } 85906c3fb27SDimitry Andric 86006c3fb27SDimitry Andric bool captured(const Use *U) override { 86106c3fb27SDimitry Andric auto *ICmp = dyn_cast<ICmpInst>(U->getUser()); 86206c3fb27SDimitry Andric // We need to check that U is based *only* on the alloca, and doesn't 86306c3fb27SDimitry Andric // have other contributions from a select/phi operand. 86406c3fb27SDimitry Andric // TODO: We could check whether getUnderlyingObjects() reduces to one 86506c3fb27SDimitry Andric // object, which would allow looking through phi nodes. 86606c3fb27SDimitry Andric if (ICmp && ICmp->isEquality() && getUnderlyingObject(*U) == Alloca) { 86706c3fb27SDimitry Andric // Collect equality icmps of the alloca, and don't treat them as 86806c3fb27SDimitry Andric // captures. 86906c3fb27SDimitry Andric auto Res = ICmps.insert({ICmp, 0}); 87006c3fb27SDimitry Andric Res.first->second |= 1u << U->getOperandNo(); 87106c3fb27SDimitry Andric return false; 8720b57cec5SDimitry Andric } 8730b57cec5SDimitry Andric 87406c3fb27SDimitry Andric Captured = true; 87506c3fb27SDimitry Andric return true; 87606c3fb27SDimitry Andric } 87706c3fb27SDimitry Andric }; 8780b57cec5SDimitry Andric 87906c3fb27SDimitry Andric CmpCaptureTracker Tracker(Alloca); 88006c3fb27SDimitry Andric PointerMayBeCaptured(Alloca, &Tracker); 88106c3fb27SDimitry Andric if (Tracker.Captured) 88206c3fb27SDimitry Andric return false; 88306c3fb27SDimitry Andric 88406c3fb27SDimitry Andric bool Changed = false; 88506c3fb27SDimitry Andric for (auto [ICmp, Operands] : Tracker.ICmps) { 88606c3fb27SDimitry Andric switch (Operands) { 88706c3fb27SDimitry Andric case 1: 88806c3fb27SDimitry Andric case 2: { 88906c3fb27SDimitry Andric // The alloca is only used in one icmp operand. Assume that the 89006c3fb27SDimitry Andric // equality is false. 89106c3fb27SDimitry Andric auto *Res = ConstantInt::get( 89206c3fb27SDimitry Andric ICmp->getType(), ICmp->getPredicate() == ICmpInst::ICMP_NE); 89306c3fb27SDimitry Andric replaceInstUsesWith(*ICmp, Res); 89406c3fb27SDimitry Andric eraseInstFromFunction(*ICmp); 89506c3fb27SDimitry Andric Changed = true; 89606c3fb27SDimitry Andric break; 89706c3fb27SDimitry Andric } 89806c3fb27SDimitry Andric case 3: 89906c3fb27SDimitry Andric // Both icmp operands are based on the alloca, so this is comparing 90006c3fb27SDimitry Andric // pointer offsets, without leaking any information about the address 90106c3fb27SDimitry Andric // of the alloca. Ignore such comparisons. 90206c3fb27SDimitry Andric break; 9030b57cec5SDimitry Andric default: 90406c3fb27SDimitry Andric llvm_unreachable("Cannot happen"); 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 90806c3fb27SDimitry Andric return Changed; 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric /// Fold "icmp pred (X+C), X". 912e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpAddOpConst(Value *X, const APInt &C, 9130b57cec5SDimitry Andric ICmpInst::Predicate Pred) { 9140b57cec5SDimitry Andric // From this point on, we know that (X+C <= X) --> (X+C < X) because C != 0, 9150b57cec5SDimitry Andric // so the values can never be equal. Similarly for all other "or equals" 9160b57cec5SDimitry Andric // operators. 9170b57cec5SDimitry Andric assert(!!C && "C should not be zero!"); 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric // (X+1) <u X --> X >u (MAXUINT-1) --> X == 255 9200b57cec5SDimitry Andric // (X+2) <u X --> X >u (MAXUINT-2) --> X > 253 9210b57cec5SDimitry Andric // (X+MAXUINT) <u X --> X >u (MAXUINT-MAXUINT) --> X != 0 9220b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) { 9230b57cec5SDimitry Andric Constant *R = ConstantInt::get(X->getType(), 9240b57cec5SDimitry Andric APInt::getMaxValue(C.getBitWidth()) - C); 9250b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, X, R); 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric // (X+1) >u X --> X <u (0-1) --> X != 255 9290b57cec5SDimitry Andric // (X+2) >u X --> X <u (0-2) --> X <u 254 9300b57cec5SDimitry Andric // (X+MAXUINT) >u X --> X <u (0-MAXUINT) --> X <u 1 --> X == 0 9310b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) 9320b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULT, X, 9330b57cec5SDimitry Andric ConstantInt::get(X->getType(), -C)); 9340b57cec5SDimitry Andric 9350b57cec5SDimitry Andric APInt SMax = APInt::getSignedMaxValue(C.getBitWidth()); 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric // (X+ 1) <s X --> X >s (MAXSINT-1) --> X == 127 9380b57cec5SDimitry Andric // (X+ 2) <s X --> X >s (MAXSINT-2) --> X >s 125 9390b57cec5SDimitry Andric // (X+MAXSINT) <s X --> X >s (MAXSINT-MAXSINT) --> X >s 0 9400b57cec5SDimitry Andric // (X+MINSINT) <s X --> X >s (MAXSINT-MINSINT) --> X >s -1 9410b57cec5SDimitry Andric // (X+ -2) <s X --> X >s (MAXSINT- -2) --> X >s 126 9420b57cec5SDimitry Andric // (X+ -1) <s X --> X >s (MAXSINT- -1) --> X != 127 9430b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SLE) 9440b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, X, 9450b57cec5SDimitry Andric ConstantInt::get(X->getType(), SMax - C)); 9460b57cec5SDimitry Andric 9470b57cec5SDimitry Andric // (X+ 1) >s X --> X <s (MAXSINT-(1-1)) --> X != 127 9480b57cec5SDimitry Andric // (X+ 2) >s X --> X <s (MAXSINT-(2-1)) --> X <s 126 9490b57cec5SDimitry Andric // (X+MAXSINT) >s X --> X <s (MAXSINT-(MAXSINT-1)) --> X <s 1 9500b57cec5SDimitry Andric // (X+MINSINT) >s X --> X <s (MAXSINT-(MINSINT-1)) --> X <s -2 9510b57cec5SDimitry Andric // (X+ -2) >s X --> X <s (MAXSINT-(-2-1)) --> X <s -126 9520b57cec5SDimitry Andric // (X+ -1) >s X --> X <s (MAXSINT-(-1-1)) --> X == -128 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric assert(Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SGE); 9550b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, X, 9560b57cec5SDimitry Andric ConstantInt::get(X->getType(), SMax - (C - 1))); 9570b57cec5SDimitry Andric } 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric /// Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> 9600b57cec5SDimitry Andric /// (icmp eq/ne A, Log2(AP2/AP1)) -> 9610b57cec5SDimitry Andric /// (icmp eq/ne A, Log2(AP2) - Log2(AP1)). 962e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpShrConstConst(ICmpInst &I, Value *A, 9630b57cec5SDimitry Andric const APInt &AP1, 9640b57cec5SDimitry Andric const APInt &AP2) { 9650b57cec5SDimitry Andric assert(I.isEquality() && "Cannot fold icmp gt/lt"); 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) { 9680b57cec5SDimitry Andric if (I.getPredicate() == I.ICMP_NE) 9690b57cec5SDimitry Andric Pred = CmpInst::getInversePredicate(Pred); 9700b57cec5SDimitry Andric return new ICmpInst(Pred, LHS, RHS); 9710b57cec5SDimitry Andric }; 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric // Don't bother doing any work for cases which InstSimplify handles. 974349cc55cSDimitry Andric if (AP2.isZero()) 9750b57cec5SDimitry Andric return nullptr; 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric bool IsAShr = isa<AShrOperator>(I.getOperand(0)); 9780b57cec5SDimitry Andric if (IsAShr) { 979349cc55cSDimitry Andric if (AP2.isAllOnes()) 9800b57cec5SDimitry Andric return nullptr; 9810b57cec5SDimitry Andric if (AP2.isNegative() != AP1.isNegative()) 9820b57cec5SDimitry Andric return nullptr; 9830b57cec5SDimitry Andric if (AP2.sgt(AP1)) 9840b57cec5SDimitry Andric return nullptr; 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric if (!AP1) 9880b57cec5SDimitry Andric // 'A' must be large enough to shift out the highest set bit. 9890b57cec5SDimitry Andric return getICmp(I.ICMP_UGT, A, 9900b57cec5SDimitry Andric ConstantInt::get(A->getType(), AP2.logBase2())); 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric if (AP1 == AP2) 9930b57cec5SDimitry Andric return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType())); 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric int Shift; 9960b57cec5SDimitry Andric if (IsAShr && AP1.isNegative()) 99706c3fb27SDimitry Andric Shift = AP1.countl_one() - AP2.countl_one(); 9980b57cec5SDimitry Andric else 99906c3fb27SDimitry Andric Shift = AP1.countl_zero() - AP2.countl_zero(); 10000b57cec5SDimitry Andric 10010b57cec5SDimitry Andric if (Shift > 0) { 10020b57cec5SDimitry Andric if (IsAShr && AP1 == AP2.ashr(Shift)) { 10030b57cec5SDimitry Andric // There are multiple solutions if we are comparing against -1 and the LHS 10040b57cec5SDimitry Andric // of the ashr is not a power of two. 1005349cc55cSDimitry Andric if (AP1.isAllOnes() && !AP2.isPowerOf2()) 10060b57cec5SDimitry Andric return getICmp(I.ICMP_UGE, A, ConstantInt::get(A->getType(), Shift)); 10070b57cec5SDimitry Andric return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift)); 10080b57cec5SDimitry Andric } else if (AP1 == AP2.lshr(Shift)) { 10090b57cec5SDimitry Andric return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift)); 10100b57cec5SDimitry Andric } 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric // Shifting const2 will never be equal to const1. 10140b57cec5SDimitry Andric // FIXME: This should always be handled by InstSimplify? 10150b57cec5SDimitry Andric auto *TorF = ConstantInt::get(I.getType(), I.getPredicate() == I.ICMP_NE); 10160b57cec5SDimitry Andric return replaceInstUsesWith(I, TorF); 10170b57cec5SDimitry Andric } 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric /// Handle "(icmp eq/ne (shl AP2, A), AP1)" -> 10200b57cec5SDimitry Andric /// (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)). 1021e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpShlConstConst(ICmpInst &I, Value *A, 10220b57cec5SDimitry Andric const APInt &AP1, 10230b57cec5SDimitry Andric const APInt &AP2) { 10240b57cec5SDimitry Andric assert(I.isEquality() && "Cannot fold icmp gt/lt"); 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) { 10270b57cec5SDimitry Andric if (I.getPredicate() == I.ICMP_NE) 10280b57cec5SDimitry Andric Pred = CmpInst::getInversePredicate(Pred); 10290b57cec5SDimitry Andric return new ICmpInst(Pred, LHS, RHS); 10300b57cec5SDimitry Andric }; 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric // Don't bother doing any work for cases which InstSimplify handles. 1033349cc55cSDimitry Andric if (AP2.isZero()) 10340b57cec5SDimitry Andric return nullptr; 10350b57cec5SDimitry Andric 103606c3fb27SDimitry Andric unsigned AP2TrailingZeros = AP2.countr_zero(); 10370b57cec5SDimitry Andric 10380b57cec5SDimitry Andric if (!AP1 && AP2TrailingZeros != 0) 10390b57cec5SDimitry Andric return getICmp( 10400b57cec5SDimitry Andric I.ICMP_UGE, A, 10410b57cec5SDimitry Andric ConstantInt::get(A->getType(), AP2.getBitWidth() - AP2TrailingZeros)); 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric if (AP1 == AP2) 10440b57cec5SDimitry Andric return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType())); 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric // Get the distance between the lowest bits that are set. 104706c3fb27SDimitry Andric int Shift = AP1.countr_zero() - AP2TrailingZeros; 10480b57cec5SDimitry Andric 10490b57cec5SDimitry Andric if (Shift > 0 && AP2.shl(Shift) == AP1) 10500b57cec5SDimitry Andric return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift)); 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric // Shifting const2 will never be equal to const1. 10530b57cec5SDimitry Andric // FIXME: This should always be handled by InstSimplify? 10540b57cec5SDimitry Andric auto *TorF = ConstantInt::get(I.getType(), I.getPredicate() == I.ICMP_NE); 10550b57cec5SDimitry Andric return replaceInstUsesWith(I, TorF); 10560b57cec5SDimitry Andric } 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric /// The caller has matched a pattern of the form: 10590b57cec5SDimitry Andric /// I = icmp ugt (add (add A, B), CI2), CI1 10600b57cec5SDimitry Andric /// If this is of the form: 10610b57cec5SDimitry Andric /// sum = a + b 10620b57cec5SDimitry Andric /// if (sum+128 >u 255) 10630b57cec5SDimitry Andric /// Then replace it with llvm.sadd.with.overflow.i8. 10640b57cec5SDimitry Andric /// 10650b57cec5SDimitry Andric static Instruction *processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B, 10660b57cec5SDimitry Andric ConstantInt *CI2, ConstantInt *CI1, 1067e8d8bef9SDimitry Andric InstCombinerImpl &IC) { 10680b57cec5SDimitry Andric // The transformation we're trying to do here is to transform this into an 10690b57cec5SDimitry Andric // llvm.sadd.with.overflow. To do this, we have to replace the original add 10700b57cec5SDimitry Andric // with a narrower add, and discard the add-with-constant that is part of the 10710b57cec5SDimitry Andric // range check (if we can't eliminate it, this isn't profitable). 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric // In order to eliminate the add-with-constant, the compare can be its only 10740b57cec5SDimitry Andric // use. 10750b57cec5SDimitry Andric Instruction *AddWithCst = cast<Instruction>(I.getOperand(0)); 10760b57cec5SDimitry Andric if (!AddWithCst->hasOneUse()) 10770b57cec5SDimitry Andric return nullptr; 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric // If CI2 is 2^7, 2^15, 2^31, then it might be an sadd.with.overflow. 10800b57cec5SDimitry Andric if (!CI2->getValue().isPowerOf2()) 10810b57cec5SDimitry Andric return nullptr; 108206c3fb27SDimitry Andric unsigned NewWidth = CI2->getValue().countr_zero(); 10830b57cec5SDimitry Andric if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31) 10840b57cec5SDimitry Andric return nullptr; 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric // The width of the new add formed is 1 more than the bias. 10870b57cec5SDimitry Andric ++NewWidth; 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric // Check to see that CI1 is an all-ones value with NewWidth bits. 10900b57cec5SDimitry Andric if (CI1->getBitWidth() == NewWidth || 10910b57cec5SDimitry Andric CI1->getValue() != APInt::getLowBitsSet(CI1->getBitWidth(), NewWidth)) 10920b57cec5SDimitry Andric return nullptr; 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric // This is only really a signed overflow check if the inputs have been 10950b57cec5SDimitry Andric // sign-extended; check for that condition. For example, if CI2 is 2^31 and 10960b57cec5SDimitry Andric // the operands of the add are 64 bits wide, we need at least 33 sign bits. 109704eeddc0SDimitry Andric if (IC.ComputeMaxSignificantBits(A, 0, &I) > NewWidth || 109804eeddc0SDimitry Andric IC.ComputeMaxSignificantBits(B, 0, &I) > NewWidth) 10990b57cec5SDimitry Andric return nullptr; 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric // In order to replace the original add with a narrower 11020b57cec5SDimitry Andric // llvm.sadd.with.overflow, the only uses allowed are the add-with-constant 11030b57cec5SDimitry Andric // and truncates that discard the high bits of the add. Verify that this is 11040b57cec5SDimitry Andric // the case. 11050b57cec5SDimitry Andric Instruction *OrigAdd = cast<Instruction>(AddWithCst->getOperand(0)); 11060b57cec5SDimitry Andric for (User *U : OrigAdd->users()) { 11070b57cec5SDimitry Andric if (U == AddWithCst) 11080b57cec5SDimitry Andric continue; 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric // Only accept truncates for now. We would really like a nice recursive 11110b57cec5SDimitry Andric // predicate like SimplifyDemandedBits, but which goes downwards the use-def 11120b57cec5SDimitry Andric // chain to see which bits of a value are actually demanded. If the 11130b57cec5SDimitry Andric // original add had another add which was then immediately truncated, we 11140b57cec5SDimitry Andric // could still do the transformation. 11150b57cec5SDimitry Andric TruncInst *TI = dyn_cast<TruncInst>(U); 11160b57cec5SDimitry Andric if (!TI || TI->getType()->getPrimitiveSizeInBits() > NewWidth) 11170b57cec5SDimitry Andric return nullptr; 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric // If the pattern matches, truncate the inputs to the narrower type and 11210b57cec5SDimitry Andric // use the sadd_with_overflow intrinsic to efficiently compute both the 11220b57cec5SDimitry Andric // result and the overflow bit. 11230b57cec5SDimitry Andric Type *NewType = IntegerType::get(OrigAdd->getContext(), NewWidth); 11240b57cec5SDimitry Andric Function *F = Intrinsic::getDeclaration( 11250b57cec5SDimitry Andric I.getModule(), Intrinsic::sadd_with_overflow, NewType); 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder = IC.Builder; 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric // Put the new code above the original add, in case there are any uses of the 11300b57cec5SDimitry Andric // add between the add and the compare. 11310b57cec5SDimitry Andric Builder.SetInsertPoint(OrigAdd); 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric Value *TruncA = Builder.CreateTrunc(A, NewType, A->getName() + ".trunc"); 11340b57cec5SDimitry Andric Value *TruncB = Builder.CreateTrunc(B, NewType, B->getName() + ".trunc"); 11350b57cec5SDimitry Andric CallInst *Call = Builder.CreateCall(F, {TruncA, TruncB}, "sadd"); 11360b57cec5SDimitry Andric Value *Add = Builder.CreateExtractValue(Call, 0, "sadd.result"); 11370b57cec5SDimitry Andric Value *ZExt = Builder.CreateZExt(Add, OrigAdd->getType()); 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andric // The inner add was the result of the narrow add, zero extended to the 11400b57cec5SDimitry Andric // wider type. Replace it with the result computed by the intrinsic. 11410b57cec5SDimitry Andric IC.replaceInstUsesWith(*OrigAdd, ZExt); 11425ffd83dbSDimitry Andric IC.eraseInstFromFunction(*OrigAdd); 11430b57cec5SDimitry Andric 11440b57cec5SDimitry Andric // The original icmp gets replaced with the overflow value. 11450b57cec5SDimitry Andric return ExtractValueInst::Create(Call, 1, "sadd.overflow"); 11460b57cec5SDimitry Andric } 11470b57cec5SDimitry Andric 11488bcb0991SDimitry Andric /// If we have: 11498bcb0991SDimitry Andric /// icmp eq/ne (urem/srem %x, %y), 0 11508bcb0991SDimitry Andric /// iff %y is a power-of-two, we can replace this with a bit test: 11518bcb0991SDimitry Andric /// icmp eq/ne (and %x, (add %y, -1)), 0 1152e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldIRemByPowerOfTwoToBitTest(ICmpInst &I) { 11538bcb0991SDimitry Andric // This fold is only valid for equality predicates. 11548bcb0991SDimitry Andric if (!I.isEquality()) 11558bcb0991SDimitry Andric return nullptr; 11568bcb0991SDimitry Andric ICmpInst::Predicate Pred; 11578bcb0991SDimitry Andric Value *X, *Y, *Zero; 11588bcb0991SDimitry Andric if (!match(&I, m_ICmp(Pred, m_OneUse(m_IRem(m_Value(X), m_Value(Y))), 11598bcb0991SDimitry Andric m_CombineAnd(m_Zero(), m_Value(Zero))))) 11608bcb0991SDimitry Andric return nullptr; 11618bcb0991SDimitry Andric if (!isKnownToBeAPowerOfTwo(Y, /*OrZero*/ true, 0, &I)) 11628bcb0991SDimitry Andric return nullptr; 11638bcb0991SDimitry Andric // This may increase instruction count, we don't enforce that Y is a constant. 11648bcb0991SDimitry Andric Value *Mask = Builder.CreateAdd(Y, Constant::getAllOnesValue(Y->getType())); 11658bcb0991SDimitry Andric Value *Masked = Builder.CreateAnd(X, Mask); 11668bcb0991SDimitry Andric return ICmpInst::Create(Instruction::ICmp, Pred, Masked, Zero); 11678bcb0991SDimitry Andric } 11688bcb0991SDimitry Andric 11698bcb0991SDimitry Andric /// Fold equality-comparison between zero and any (maybe truncated) right-shift 11708bcb0991SDimitry Andric /// by one-less-than-bitwidth into a sign test on the original value. 1171e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldSignBitTest(ICmpInst &I) { 11728bcb0991SDimitry Andric Instruction *Val; 11738bcb0991SDimitry Andric ICmpInst::Predicate Pred; 11748bcb0991SDimitry Andric if (!I.isEquality() || !match(&I, m_ICmp(Pred, m_Instruction(Val), m_Zero()))) 11758bcb0991SDimitry Andric return nullptr; 11768bcb0991SDimitry Andric 11778bcb0991SDimitry Andric Value *X; 11788bcb0991SDimitry Andric Type *XTy; 11798bcb0991SDimitry Andric 11808bcb0991SDimitry Andric Constant *C; 11818bcb0991SDimitry Andric if (match(Val, m_TruncOrSelf(m_Shr(m_Value(X), m_Constant(C))))) { 11828bcb0991SDimitry Andric XTy = X->getType(); 11838bcb0991SDimitry Andric unsigned XBitWidth = XTy->getScalarSizeInBits(); 11848bcb0991SDimitry Andric if (!match(C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, 11858bcb0991SDimitry Andric APInt(XBitWidth, XBitWidth - 1)))) 11868bcb0991SDimitry Andric return nullptr; 11878bcb0991SDimitry Andric } else if (isa<BinaryOperator>(Val) && 11888bcb0991SDimitry Andric (X = reassociateShiftAmtsOfTwoSameDirectionShifts( 11898bcb0991SDimitry Andric cast<BinaryOperator>(Val), SQ.getWithInstruction(Val), 11908bcb0991SDimitry Andric /*AnalyzeForSignBitExtraction=*/true))) { 11918bcb0991SDimitry Andric XTy = X->getType(); 11928bcb0991SDimitry Andric } else 11938bcb0991SDimitry Andric return nullptr; 11948bcb0991SDimitry Andric 11958bcb0991SDimitry Andric return ICmpInst::Create(Instruction::ICmp, 11968bcb0991SDimitry Andric Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_SGE 11978bcb0991SDimitry Andric : ICmpInst::ICMP_SLT, 11988bcb0991SDimitry Andric X, ConstantInt::getNullValue(XTy)); 11998bcb0991SDimitry Andric } 12008bcb0991SDimitry Andric 12010b57cec5SDimitry Andric // Handle icmp pred X, 0 1202e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) { 12030b57cec5SDimitry Andric CmpInst::Predicate Pred = Cmp.getPredicate(); 12040b57cec5SDimitry Andric if (!match(Cmp.getOperand(1), m_Zero())) 12050b57cec5SDimitry Andric return nullptr; 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric // (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0) 12080b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SGT) { 12090b57cec5SDimitry Andric Value *A, *B; 121081ad6265SDimitry Andric if (match(Cmp.getOperand(0), m_SMin(m_Value(A), m_Value(B)))) { 12115f757f3fSDimitry Andric if (isKnownPositive(A, SQ.getWithInstruction(&Cmp))) 12120b57cec5SDimitry Andric return new ICmpInst(Pred, B, Cmp.getOperand(1)); 12135f757f3fSDimitry Andric if (isKnownPositive(B, SQ.getWithInstruction(&Cmp))) 12140b57cec5SDimitry Andric return new ICmpInst(Pred, A, Cmp.getOperand(1)); 12150b57cec5SDimitry Andric } 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12188bcb0991SDimitry Andric if (Instruction *New = foldIRemByPowerOfTwoToBitTest(Cmp)) 12198bcb0991SDimitry Andric return New; 12208bcb0991SDimitry Andric 12210b57cec5SDimitry Andric // Given: 12220b57cec5SDimitry Andric // icmp eq/ne (urem %x, %y), 0 12230b57cec5SDimitry Andric // Iff %x has 0 or 1 bits set, and %y has at least 2 bits set, omit 'urem': 12240b57cec5SDimitry Andric // icmp eq/ne %x, 0 12250b57cec5SDimitry Andric Value *X, *Y; 12260b57cec5SDimitry Andric if (match(Cmp.getOperand(0), m_URem(m_Value(X), m_Value(Y))) && 12270b57cec5SDimitry Andric ICmpInst::isEquality(Pred)) { 12280b57cec5SDimitry Andric KnownBits XKnown = computeKnownBits(X, 0, &Cmp); 12290b57cec5SDimitry Andric KnownBits YKnown = computeKnownBits(Y, 0, &Cmp); 12300b57cec5SDimitry Andric if (XKnown.countMaxPopulation() == 1 && YKnown.countMinPopulation() >= 2) 12310b57cec5SDimitry Andric return new ICmpInst(Pred, X, Cmp.getOperand(1)); 12320b57cec5SDimitry Andric } 12330b57cec5SDimitry Andric 123406c3fb27SDimitry Andric // (icmp eq/ne (mul X Y)) -> (icmp eq/ne X/Y) if we know about whether X/Y are 123506c3fb27SDimitry Andric // odd/non-zero/there is no overflow. 123606c3fb27SDimitry Andric if (match(Cmp.getOperand(0), m_Mul(m_Value(X), m_Value(Y))) && 123706c3fb27SDimitry Andric ICmpInst::isEquality(Pred)) { 123806c3fb27SDimitry Andric 123906c3fb27SDimitry Andric KnownBits XKnown = computeKnownBits(X, 0, &Cmp); 124006c3fb27SDimitry Andric // if X % 2 != 0 124106c3fb27SDimitry Andric // (icmp eq/ne Y) 124206c3fb27SDimitry Andric if (XKnown.countMaxTrailingZeros() == 0) 124306c3fb27SDimitry Andric return new ICmpInst(Pred, Y, Cmp.getOperand(1)); 124406c3fb27SDimitry Andric 124506c3fb27SDimitry Andric KnownBits YKnown = computeKnownBits(Y, 0, &Cmp); 124606c3fb27SDimitry Andric // if Y % 2 != 0 124706c3fb27SDimitry Andric // (icmp eq/ne X) 124806c3fb27SDimitry Andric if (YKnown.countMaxTrailingZeros() == 0) 124906c3fb27SDimitry Andric return new ICmpInst(Pred, X, Cmp.getOperand(1)); 125006c3fb27SDimitry Andric 125106c3fb27SDimitry Andric auto *BO0 = cast<OverflowingBinaryOperator>(Cmp.getOperand(0)); 125206c3fb27SDimitry Andric if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) { 125306c3fb27SDimitry Andric const SimplifyQuery Q = SQ.getWithInstruction(&Cmp); 125406c3fb27SDimitry Andric // `isKnownNonZero` does more analysis than just `!KnownBits.One.isZero()` 125506c3fb27SDimitry Andric // but to avoid unnecessary work, first just if this is an obvious case. 125606c3fb27SDimitry Andric 125706c3fb27SDimitry Andric // if X non-zero and NoOverflow(X * Y) 125806c3fb27SDimitry Andric // (icmp eq/ne Y) 1259*0fca6ea1SDimitry Andric if (!XKnown.One.isZero() || isKnownNonZero(X, Q)) 126006c3fb27SDimitry Andric return new ICmpInst(Pred, Y, Cmp.getOperand(1)); 126106c3fb27SDimitry Andric 126206c3fb27SDimitry Andric // if Y non-zero and NoOverflow(X * Y) 126306c3fb27SDimitry Andric // (icmp eq/ne X) 1264*0fca6ea1SDimitry Andric if (!YKnown.One.isZero() || isKnownNonZero(Y, Q)) 126506c3fb27SDimitry Andric return new ICmpInst(Pred, X, Cmp.getOperand(1)); 126606c3fb27SDimitry Andric } 126706c3fb27SDimitry Andric // Note, we are skipping cases: 126806c3fb27SDimitry Andric // if Y % 2 != 0 AND X % 2 != 0 126906c3fb27SDimitry Andric // (false/true) 127006c3fb27SDimitry Andric // if X non-zero and Y non-zero and NoOverflow(X * Y) 127106c3fb27SDimitry Andric // (false/true) 127206c3fb27SDimitry Andric // Those can be simplified later as we would have already replaced the (icmp 127306c3fb27SDimitry Andric // eq/ne (mul X, Y)) with (icmp eq/ne X/Y) and if X/Y is known non-zero that 127406c3fb27SDimitry Andric // will fold to a constant elsewhere. 127506c3fb27SDimitry Andric } 12760b57cec5SDimitry Andric return nullptr; 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric /// Fold icmp Pred X, C. 12800b57cec5SDimitry Andric /// TODO: This code structure does not make sense. The saturating add fold 12810b57cec5SDimitry Andric /// should be moved to some other helper and extended as noted below (it is also 12820b57cec5SDimitry Andric /// possible that code has been made unnecessary - do we canonicalize IR to 12830b57cec5SDimitry Andric /// overflow/saturating intrinsics or not?). 1284e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpWithConstant(ICmpInst &Cmp) { 12850b57cec5SDimitry Andric // Match the following pattern, which is a common idiom when writing 12860b57cec5SDimitry Andric // overflow-safe integer arithmetic functions. The source performs an addition 12870b57cec5SDimitry Andric // in wider type and explicitly checks for overflow using comparisons against 12880b57cec5SDimitry Andric // INT_MIN and INT_MAX. Simplify by using the sadd_with_overflow intrinsic. 12890b57cec5SDimitry Andric // 12900b57cec5SDimitry Andric // TODO: This could probably be generalized to handle other overflow-safe 12910b57cec5SDimitry Andric // operations if we worked out the formulas to compute the appropriate magic 12920b57cec5SDimitry Andric // constants. 12930b57cec5SDimitry Andric // 12940b57cec5SDimitry Andric // sum = a + b 12950b57cec5SDimitry Andric // if (sum+128 >u 255) ... -> llvm.sadd.with.overflow.i8 12960b57cec5SDimitry Andric CmpInst::Predicate Pred = Cmp.getPredicate(); 12970b57cec5SDimitry Andric Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1); 12980b57cec5SDimitry Andric Value *A, *B; 12990b57cec5SDimitry Andric ConstantInt *CI, *CI2; // I = icmp ugt (add (add A, B), CI2), CI 13000b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT && match(Op1, m_ConstantInt(CI)) && 13010b57cec5SDimitry Andric match(Op0, m_Add(m_Add(m_Value(A), m_Value(B)), m_ConstantInt(CI2)))) 13020b57cec5SDimitry Andric if (Instruction *Res = processUGT_ADDCST_ADD(Cmp, A, B, CI2, CI, *this)) 13030b57cec5SDimitry Andric return Res; 13040b57cec5SDimitry Andric 13055ffd83dbSDimitry Andric // icmp(phi(C1, C2, ...), C) -> phi(icmp(C1, C), icmp(C2, C), ...). 13065ffd83dbSDimitry Andric Constant *C = dyn_cast<Constant>(Op1); 1307753f127fSDimitry Andric if (!C) 13085ffd83dbSDimitry Andric return nullptr; 13095ffd83dbSDimitry Andric 13105ffd83dbSDimitry Andric if (auto *Phi = dyn_cast<PHINode>(Op0)) 13115ffd83dbSDimitry Andric if (all_of(Phi->operands(), [](Value *V) { return isa<Constant>(V); })) { 131206c3fb27SDimitry Andric SmallVector<Constant *> Ops; 131306c3fb27SDimitry Andric for (Value *V : Phi->incoming_values()) { 131406c3fb27SDimitry Andric Constant *Res = 131506c3fb27SDimitry Andric ConstantFoldCompareInstOperands(Pred, cast<Constant>(V), C, DL); 131606c3fb27SDimitry Andric if (!Res) 131706c3fb27SDimitry Andric return nullptr; 131806c3fb27SDimitry Andric Ops.push_back(Res); 13195ffd83dbSDimitry Andric } 132006c3fb27SDimitry Andric Builder.SetInsertPoint(Phi); 132106c3fb27SDimitry Andric PHINode *NewPhi = Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands()); 132206c3fb27SDimitry Andric for (auto [V, Pred] : zip(Ops, Phi->blocks())) 132306c3fb27SDimitry Andric NewPhi->addIncoming(V, Pred); 13245ffd83dbSDimitry Andric return replaceInstUsesWith(Cmp, NewPhi); 13255ffd83dbSDimitry Andric } 13265ffd83dbSDimitry Andric 13277a6dacacSDimitry Andric if (Instruction *R = tryFoldInstWithCtpopWithNot(&Cmp)) 13287a6dacacSDimitry Andric return R; 13297a6dacacSDimitry Andric 13300b57cec5SDimitry Andric return nullptr; 13310b57cec5SDimitry Andric } 13320b57cec5SDimitry Andric 13330b57cec5SDimitry Andric /// Canonicalize icmp instructions based on dominating conditions. 1334e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) { 133506c3fb27SDimitry Andric // We already checked simple implication in InstSimplify, only handle complex 133606c3fb27SDimitry Andric // cases here. 13370b57cec5SDimitry Andric Value *X = Cmp.getOperand(0), *Y = Cmp.getOperand(1); 13385f757f3fSDimitry Andric const APInt *C; 13395f757f3fSDimitry Andric if (!match(Y, m_APInt(C))) 13405f757f3fSDimitry Andric return nullptr; 13415f757f3fSDimitry Andric 13425f757f3fSDimitry Andric CmpInst::Predicate Pred = Cmp.getPredicate(); 13435f757f3fSDimitry Andric ConstantRange CR = ConstantRange::makeExactICmpRegion(Pred, *C); 13445f757f3fSDimitry Andric 1345*0fca6ea1SDimitry Andric auto handleDomCond = [&](ICmpInst::Predicate DomPred, 1346*0fca6ea1SDimitry Andric const APInt *DomC) -> Instruction * { 13470b57cec5SDimitry Andric // We have 2 compares of a variable with constants. Calculate the constant 13480b57cec5SDimitry Andric // ranges of those compares to see if we can transform the 2nd compare: 13490b57cec5SDimitry Andric // DomBB: 13500b57cec5SDimitry Andric // DomCond = icmp DomPred X, DomC 13510b57cec5SDimitry Andric // br DomCond, CmpBB, FalseBB 13520b57cec5SDimitry Andric // CmpBB: 13530b57cec5SDimitry Andric // Cmp = icmp Pred X, C 13540b57cec5SDimitry Andric ConstantRange DominatingCR = 13555f757f3fSDimitry Andric ConstantRange::makeExactICmpRegion(DomPred, *DomC); 13560b57cec5SDimitry Andric ConstantRange Intersection = DominatingCR.intersectWith(CR); 13570b57cec5SDimitry Andric ConstantRange Difference = DominatingCR.difference(CR); 13580b57cec5SDimitry Andric if (Intersection.isEmptySet()) 13590b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getFalse()); 13600b57cec5SDimitry Andric if (Difference.isEmptySet()) 13610b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getTrue()); 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric // Canonicalizing a sign bit comparison that gets used in a branch, 13640b57cec5SDimitry Andric // pessimizes codegen by generating branch on zero instruction instead 13650b57cec5SDimitry Andric // of a test and branch. So we avoid canonicalizing in such situations 13660b57cec5SDimitry Andric // because test and branch instruction has better branch displacement 13670b57cec5SDimitry Andric // than compare and branch instruction. 13680b57cec5SDimitry Andric bool UnusedBit; 13690b57cec5SDimitry Andric bool IsSignBit = isSignBitCheck(Pred, *C, UnusedBit); 13700b57cec5SDimitry Andric if (Cmp.isEquality() || (IsSignBit && hasBranchUse(Cmp))) 13710b57cec5SDimitry Andric return nullptr; 13720b57cec5SDimitry Andric 1373fe6060f1SDimitry Andric // Avoid an infinite loop with min/max canonicalization. 1374fe6060f1SDimitry Andric // TODO: This will be unnecessary if we canonicalize to min/max intrinsics. 1375fe6060f1SDimitry Andric if (Cmp.hasOneUse() && 1376fe6060f1SDimitry Andric match(Cmp.user_back(), m_MaxOrMin(m_Value(), m_Value()))) 1377fe6060f1SDimitry Andric return nullptr; 1378fe6060f1SDimitry Andric 13790b57cec5SDimitry Andric if (const APInt *EqC = Intersection.getSingleElement()) 13800b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, X, Builder.getInt(*EqC)); 13810b57cec5SDimitry Andric if (const APInt *NeC = Difference.getSingleElement()) 13820b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, X, Builder.getInt(*NeC)); 13835f757f3fSDimitry Andric return nullptr; 13845f757f3fSDimitry Andric }; 13855f757f3fSDimitry Andric 13865f757f3fSDimitry Andric for (BranchInst *BI : DC.conditionsFor(X)) { 1387*0fca6ea1SDimitry Andric ICmpInst::Predicate DomPred; 1388*0fca6ea1SDimitry Andric const APInt *DomC; 1389*0fca6ea1SDimitry Andric if (!match(BI->getCondition(), 1390*0fca6ea1SDimitry Andric m_ICmp(DomPred, m_Specific(X), m_APInt(DomC)))) 1391*0fca6ea1SDimitry Andric continue; 1392*0fca6ea1SDimitry Andric 13935f757f3fSDimitry Andric BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0)); 13945f757f3fSDimitry Andric if (DT.dominates(Edge0, Cmp.getParent())) { 1395*0fca6ea1SDimitry Andric if (auto *V = handleDomCond(DomPred, DomC)) 13965f757f3fSDimitry Andric return V; 13975f757f3fSDimitry Andric } else { 13985f757f3fSDimitry Andric BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1)); 13995f757f3fSDimitry Andric if (DT.dominates(Edge1, Cmp.getParent())) 1400*0fca6ea1SDimitry Andric if (auto *V = 1401*0fca6ea1SDimitry Andric handleDomCond(CmpInst::getInversePredicate(DomPred), DomC)) 14025f757f3fSDimitry Andric return V; 14035f757f3fSDimitry Andric } 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric return nullptr; 14070b57cec5SDimitry Andric } 14080b57cec5SDimitry Andric 140981ad6265SDimitry Andric /// Fold icmp (trunc X), C. 1410e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp, 14110b57cec5SDimitry Andric TruncInst *Trunc, 14120b57cec5SDimitry Andric const APInt &C) { 14130b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 14140b57cec5SDimitry Andric Value *X = Trunc->getOperand(0); 1415*0fca6ea1SDimitry Andric Type *SrcTy = X->getType(); 1416*0fca6ea1SDimitry Andric unsigned DstBits = Trunc->getType()->getScalarSizeInBits(), 1417*0fca6ea1SDimitry Andric SrcBits = SrcTy->getScalarSizeInBits(); 1418*0fca6ea1SDimitry Andric 1419*0fca6ea1SDimitry Andric // Match (icmp pred (trunc nuw/nsw X), C) 1420*0fca6ea1SDimitry Andric // Which we can convert to (icmp pred X, (sext/zext C)) 1421*0fca6ea1SDimitry Andric if (shouldChangeType(Trunc->getType(), SrcTy)) { 1422*0fca6ea1SDimitry Andric if (Trunc->hasNoSignedWrap()) 1423*0fca6ea1SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, C.sext(SrcBits))); 1424*0fca6ea1SDimitry Andric if (!Cmp.isSigned() && Trunc->hasNoUnsignedWrap()) 1425*0fca6ea1SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, C.zext(SrcBits))); 1426*0fca6ea1SDimitry Andric } 1427*0fca6ea1SDimitry Andric 1428349cc55cSDimitry Andric if (C.isOne() && C.getBitWidth() > 1) { 14290b57cec5SDimitry Andric // icmp slt trunc(signum(V)) 1 --> icmp slt V, 1 14300b57cec5SDimitry Andric Value *V = nullptr; 14310b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SLT && match(X, m_Signum(m_Value(V)))) 14320b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, V, 14330b57cec5SDimitry Andric ConstantInt::get(V->getType(), 1)); 14340b57cec5SDimitry Andric } 14350b57cec5SDimitry Andric 1436bdd1243dSDimitry Andric // TODO: Handle any shifted constant by subtracting trailing zeros. 1437bdd1243dSDimitry Andric // TODO: Handle non-equality predicates. 1438bdd1243dSDimitry Andric Value *Y; 1439bdd1243dSDimitry Andric if (Cmp.isEquality() && match(X, m_Shl(m_One(), m_Value(Y)))) { 1440bdd1243dSDimitry Andric // (trunc (1 << Y) to iN) == 0 --> Y u>= N 1441bdd1243dSDimitry Andric // (trunc (1 << Y) to iN) != 0 --> Y u< N 1442bdd1243dSDimitry Andric if (C.isZero()) { 1443bdd1243dSDimitry Andric auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT; 1444bdd1243dSDimitry Andric return new ICmpInst(NewPred, Y, ConstantInt::get(SrcTy, DstBits)); 1445bdd1243dSDimitry Andric } 1446bdd1243dSDimitry Andric // (trunc (1 << Y) to iN) == 2**C --> Y == C 1447bdd1243dSDimitry Andric // (trunc (1 << Y) to iN) != 2**C --> Y != C 1448bdd1243dSDimitry Andric if (C.isPowerOf2()) 1449bdd1243dSDimitry Andric return new ICmpInst(Pred, Y, ConstantInt::get(SrcTy, C.logBase2())); 1450bdd1243dSDimitry Andric } 1451bdd1243dSDimitry Andric 14520b57cec5SDimitry Andric if (Cmp.isEquality() && Trunc->hasOneUse()) { 145381ad6265SDimitry Andric // Canonicalize to a mask and wider compare if the wide type is suitable: 145481ad6265SDimitry Andric // (trunc X to i8) == C --> (X & 0xff) == (zext C) 1455bdd1243dSDimitry Andric if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) { 1456bdd1243dSDimitry Andric Constant *Mask = 1457bdd1243dSDimitry Andric ConstantInt::get(SrcTy, APInt::getLowBitsSet(SrcBits, DstBits)); 145881ad6265SDimitry Andric Value *And = Builder.CreateAnd(X, Mask); 1459bdd1243dSDimitry Andric Constant *WideC = ConstantInt::get(SrcTy, C.zext(SrcBits)); 146081ad6265SDimitry Andric return new ICmpInst(Pred, And, WideC); 146181ad6265SDimitry Andric } 146281ad6265SDimitry Andric 14630b57cec5SDimitry Andric // Simplify icmp eq (trunc x to i8), 42 -> icmp eq x, 42|highbits if all 14640b57cec5SDimitry Andric // of the high bits truncated out of x are known. 14650b57cec5SDimitry Andric KnownBits Known = computeKnownBits(X, 0, &Cmp); 14660b57cec5SDimitry Andric 14670b57cec5SDimitry Andric // If all the high bits are known, we can do this xform. 146806c3fb27SDimitry Andric if ((Known.Zero | Known.One).countl_one() >= SrcBits - DstBits) { 14690b57cec5SDimitry Andric // Pull in the high bits from known-ones set. 14700b57cec5SDimitry Andric APInt NewRHS = C.zext(SrcBits); 14710b57cec5SDimitry Andric NewRHS |= Known.One & APInt::getHighBitsSet(SrcBits, SrcBits - DstBits); 1472bdd1243dSDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, NewRHS)); 14730b57cec5SDimitry Andric } 14740b57cec5SDimitry Andric } 14750b57cec5SDimitry Andric 1476fe6060f1SDimitry Andric // Look through truncated right-shift of the sign-bit for a sign-bit check: 1477fe6060f1SDimitry Andric // trunc iN (ShOp >> ShAmtC) to i[N - ShAmtC] < 0 --> ShOp < 0 1478fe6060f1SDimitry Andric // trunc iN (ShOp >> ShAmtC) to i[N - ShAmtC] > -1 --> ShOp > -1 1479fe6060f1SDimitry Andric Value *ShOp; 1480fe6060f1SDimitry Andric const APInt *ShAmtC; 1481fe6060f1SDimitry Andric bool TrueIfSigned; 1482fe6060f1SDimitry Andric if (isSignBitCheck(Pred, C, TrueIfSigned) && 1483fe6060f1SDimitry Andric match(X, m_Shr(m_Value(ShOp), m_APInt(ShAmtC))) && 1484fe6060f1SDimitry Andric DstBits == SrcBits - ShAmtC->getZExtValue()) { 1485bdd1243dSDimitry Andric return TrueIfSigned ? new ICmpInst(ICmpInst::ICMP_SLT, ShOp, 1486bdd1243dSDimitry Andric ConstantInt::getNullValue(SrcTy)) 1487fe6060f1SDimitry Andric : new ICmpInst(ICmpInst::ICMP_SGT, ShOp, 1488bdd1243dSDimitry Andric ConstantInt::getAllOnesValue(SrcTy)); 1489fe6060f1SDimitry Andric } 1490fe6060f1SDimitry Andric 14910b57cec5SDimitry Andric return nullptr; 14920b57cec5SDimitry Andric } 14930b57cec5SDimitry Andric 1494*0fca6ea1SDimitry Andric /// Fold icmp (trunc nuw/nsw X), (trunc nuw/nsw Y). 1495*0fca6ea1SDimitry Andric /// Fold icmp (trunc nuw/nsw X), (zext/sext Y). 14965f757f3fSDimitry Andric Instruction * 14975f757f3fSDimitry Andric InstCombinerImpl::foldICmpTruncWithTruncOrExt(ICmpInst &Cmp, 14985f757f3fSDimitry Andric const SimplifyQuery &Q) { 14995f757f3fSDimitry Andric Value *X, *Y; 15005f757f3fSDimitry Andric ICmpInst::Predicate Pred; 1501*0fca6ea1SDimitry Andric bool YIsSExt = false; 15025f757f3fSDimitry Andric // Try to match icmp (trunc X), (trunc Y) 15035f757f3fSDimitry Andric if (match(&Cmp, m_ICmp(Pred, m_Trunc(m_Value(X)), m_Trunc(m_Value(Y))))) { 1504*0fca6ea1SDimitry Andric unsigned NoWrapFlags = cast<TruncInst>(Cmp.getOperand(0))->getNoWrapKind() & 1505*0fca6ea1SDimitry Andric cast<TruncInst>(Cmp.getOperand(1))->getNoWrapKind(); 1506*0fca6ea1SDimitry Andric if (Cmp.isSigned()) { 1507*0fca6ea1SDimitry Andric // For signed comparisons, both truncs must be nsw. 1508*0fca6ea1SDimitry Andric if (!(NoWrapFlags & TruncInst::NoSignedWrap)) 1509*0fca6ea1SDimitry Andric return nullptr; 1510*0fca6ea1SDimitry Andric } else { 1511*0fca6ea1SDimitry Andric // For unsigned and equality comparisons, either both must be nuw or 1512*0fca6ea1SDimitry Andric // both must be nsw, we don't care which. 1513*0fca6ea1SDimitry Andric if (!NoWrapFlags) 1514*0fca6ea1SDimitry Andric return nullptr; 1515*0fca6ea1SDimitry Andric } 1516*0fca6ea1SDimitry Andric 15175f757f3fSDimitry Andric if (X->getType() != Y->getType() && 15185f757f3fSDimitry Andric (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse())) 15195f757f3fSDimitry Andric return nullptr; 15205f757f3fSDimitry Andric if (!isDesirableIntType(X->getType()->getScalarSizeInBits()) && 15215f757f3fSDimitry Andric isDesirableIntType(Y->getType()->getScalarSizeInBits())) { 15225f757f3fSDimitry Andric std::swap(X, Y); 15235f757f3fSDimitry Andric Pred = Cmp.getSwappedPredicate(Pred); 15245f757f3fSDimitry Andric } 1525*0fca6ea1SDimitry Andric YIsSExt = !(NoWrapFlags & TruncInst::NoUnsignedWrap); 15265f757f3fSDimitry Andric } 1527*0fca6ea1SDimitry Andric // Try to match icmp (trunc nuw X), (zext Y) 1528*0fca6ea1SDimitry Andric else if (!Cmp.isSigned() && 1529*0fca6ea1SDimitry Andric match(&Cmp, m_c_ICmp(Pred, m_NUWTrunc(m_Value(X)), 1530*0fca6ea1SDimitry Andric m_OneUse(m_ZExt(m_Value(Y)))))) { 1531*0fca6ea1SDimitry Andric // Can fold trunc nuw + zext for unsigned and equality predicates. 1532*0fca6ea1SDimitry Andric } 1533*0fca6ea1SDimitry Andric // Try to match icmp (trunc nsw X), (sext Y) 1534*0fca6ea1SDimitry Andric else if (match(&Cmp, m_c_ICmp(Pred, m_NSWTrunc(m_Value(X)), 1535*0fca6ea1SDimitry Andric m_OneUse(m_ZExtOrSExt(m_Value(Y)))))) { 1536*0fca6ea1SDimitry Andric // Can fold trunc nsw + zext/sext for all predicates. 1537*0fca6ea1SDimitry Andric YIsSExt = 1538*0fca6ea1SDimitry Andric isa<SExtInst>(Cmp.getOperand(0)) || isa<SExtInst>(Cmp.getOperand(1)); 1539*0fca6ea1SDimitry Andric } else 15405f757f3fSDimitry Andric return nullptr; 15415f757f3fSDimitry Andric 15425f757f3fSDimitry Andric Type *TruncTy = Cmp.getOperand(0)->getType(); 15435f757f3fSDimitry Andric unsigned TruncBits = TruncTy->getScalarSizeInBits(); 15445f757f3fSDimitry Andric 15455f757f3fSDimitry Andric // If this transform will end up changing from desirable types -> undesirable 15465f757f3fSDimitry Andric // types skip it. 15475f757f3fSDimitry Andric if (isDesirableIntType(TruncBits) && 15485f757f3fSDimitry Andric !isDesirableIntType(X->getType()->getScalarSizeInBits())) 15495f757f3fSDimitry Andric return nullptr; 15505f757f3fSDimitry Andric 1551*0fca6ea1SDimitry Andric Value *NewY = Builder.CreateIntCast(Y, X->getType(), YIsSExt); 15525f757f3fSDimitry Andric return new ICmpInst(Pred, X, NewY); 15535f757f3fSDimitry Andric } 15545f757f3fSDimitry Andric 15550b57cec5SDimitry Andric /// Fold icmp (xor X, Y), C. 1556e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpXorConstant(ICmpInst &Cmp, 15570b57cec5SDimitry Andric BinaryOperator *Xor, 15580b57cec5SDimitry Andric const APInt &C) { 1559bdd1243dSDimitry Andric if (Instruction *I = foldICmpXorShiftConst(Cmp, Xor, C)) 1560bdd1243dSDimitry Andric return I; 1561bdd1243dSDimitry Andric 15620b57cec5SDimitry Andric Value *X = Xor->getOperand(0); 15630b57cec5SDimitry Andric Value *Y = Xor->getOperand(1); 15640b57cec5SDimitry Andric const APInt *XorC; 15650b57cec5SDimitry Andric if (!match(Y, m_APInt(XorC))) 15660b57cec5SDimitry Andric return nullptr; 15670b57cec5SDimitry Andric 15680b57cec5SDimitry Andric // If this is a comparison that tests the signbit (X < 0) or (x > -1), 15690b57cec5SDimitry Andric // fold the xor. 15700b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 15710b57cec5SDimitry Andric bool TrueIfSigned = false; 15720b57cec5SDimitry Andric if (isSignBitCheck(Cmp.getPredicate(), C, TrueIfSigned)) { 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric // If the sign bit of the XorCst is not set, there is no change to 15750b57cec5SDimitry Andric // the operation, just stop using the Xor. 15765ffd83dbSDimitry Andric if (!XorC->isNegative()) 15775ffd83dbSDimitry Andric return replaceOperand(Cmp, 0, X); 15780b57cec5SDimitry Andric 15790b57cec5SDimitry Andric // Emit the opposite comparison. 15800b57cec5SDimitry Andric if (TrueIfSigned) 15810b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, X, 15820b57cec5SDimitry Andric ConstantInt::getAllOnesValue(X->getType())); 15830b57cec5SDimitry Andric else 15840b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, X, 15850b57cec5SDimitry Andric ConstantInt::getNullValue(X->getType())); 15860b57cec5SDimitry Andric } 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric if (Xor->hasOneUse()) { 15890b57cec5SDimitry Andric // (icmp u/s (xor X SignMask), C) -> (icmp s/u X, (xor C SignMask)) 15900b57cec5SDimitry Andric if (!Cmp.isEquality() && XorC->isSignMask()) { 1591e8d8bef9SDimitry Andric Pred = Cmp.getFlippedSignednessPredicate(); 15920b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC)); 15930b57cec5SDimitry Andric } 15940b57cec5SDimitry Andric 15950b57cec5SDimitry Andric // (icmp u/s (xor X ~SignMask), C) -> (icmp s/u X, (xor C ~SignMask)) 15960b57cec5SDimitry Andric if (!Cmp.isEquality() && XorC->isMaxSignedValue()) { 1597e8d8bef9SDimitry Andric Pred = Cmp.getFlippedSignednessPredicate(); 15980b57cec5SDimitry Andric Pred = Cmp.getSwappedPredicate(Pred); 15990b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC)); 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric } 16020b57cec5SDimitry Andric 16030b57cec5SDimitry Andric // Mask constant magic can eliminate an 'xor' with unsigned compares. 16040b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT) { 16050b57cec5SDimitry Andric // (xor X, ~C) >u C --> X <u ~C (when C+1 is a power of 2) 16060b57cec5SDimitry Andric if (*XorC == ~C && (C + 1).isPowerOf2()) 16070b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULT, X, Y); 16080b57cec5SDimitry Andric // (xor X, C) >u C --> X >u C (when C+1 is a power of 2) 16090b57cec5SDimitry Andric if (*XorC == C && (C + 1).isPowerOf2()) 16100b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, X, Y); 16110b57cec5SDimitry Andric } 16120b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT) { 16130b57cec5SDimitry Andric // (xor X, -C) <u C --> X >u ~C (when C is a power of 2) 16140b57cec5SDimitry Andric if (*XorC == -C && C.isPowerOf2()) 16150b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, X, 16160b57cec5SDimitry Andric ConstantInt::get(X->getType(), ~C)); 16170b57cec5SDimitry Andric // (xor X, C) <u C --> X >u ~C (when -C is a power of 2) 16180b57cec5SDimitry Andric if (*XorC == C && (-C).isPowerOf2()) 16190b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, X, 16200b57cec5SDimitry Andric ConstantInt::get(X->getType(), ~C)); 16210b57cec5SDimitry Andric } 16220b57cec5SDimitry Andric return nullptr; 16230b57cec5SDimitry Andric } 16240b57cec5SDimitry Andric 1625bdd1243dSDimitry Andric /// For power-of-2 C: 1626bdd1243dSDimitry Andric /// ((X s>> ShiftC) ^ X) u< C --> (X + C) u< (C << 1) 1627bdd1243dSDimitry Andric /// ((X s>> ShiftC) ^ X) u> (C - 1) --> (X + C) u> ((C << 1) - 1) 1628bdd1243dSDimitry Andric Instruction *InstCombinerImpl::foldICmpXorShiftConst(ICmpInst &Cmp, 1629bdd1243dSDimitry Andric BinaryOperator *Xor, 1630bdd1243dSDimitry Andric const APInt &C) { 1631bdd1243dSDimitry Andric CmpInst::Predicate Pred = Cmp.getPredicate(); 1632bdd1243dSDimitry Andric APInt PowerOf2; 1633bdd1243dSDimitry Andric if (Pred == ICmpInst::ICMP_ULT) 1634bdd1243dSDimitry Andric PowerOf2 = C; 1635bdd1243dSDimitry Andric else if (Pred == ICmpInst::ICMP_UGT && !C.isMaxValue()) 1636bdd1243dSDimitry Andric PowerOf2 = C + 1; 1637bdd1243dSDimitry Andric else 1638bdd1243dSDimitry Andric return nullptr; 1639bdd1243dSDimitry Andric if (!PowerOf2.isPowerOf2()) 1640bdd1243dSDimitry Andric return nullptr; 1641bdd1243dSDimitry Andric Value *X; 1642bdd1243dSDimitry Andric const APInt *ShiftC; 1643bdd1243dSDimitry Andric if (!match(Xor, m_OneUse(m_c_Xor(m_Value(X), 1644bdd1243dSDimitry Andric m_AShr(m_Deferred(X), m_APInt(ShiftC)))))) 1645bdd1243dSDimitry Andric return nullptr; 1646bdd1243dSDimitry Andric uint64_t Shift = ShiftC->getLimitedValue(); 1647bdd1243dSDimitry Andric Type *XType = X->getType(); 1648bdd1243dSDimitry Andric if (Shift == 0 || PowerOf2.isMinSignedValue()) 1649bdd1243dSDimitry Andric return nullptr; 1650bdd1243dSDimitry Andric Value *Add = Builder.CreateAdd(X, ConstantInt::get(XType, PowerOf2)); 1651bdd1243dSDimitry Andric APInt Bound = 1652bdd1243dSDimitry Andric Pred == ICmpInst::ICMP_ULT ? PowerOf2 << 1 : ((PowerOf2 << 1) - 1); 1653bdd1243dSDimitry Andric return new ICmpInst(Pred, Add, ConstantInt::get(XType, Bound)); 1654bdd1243dSDimitry Andric } 1655bdd1243dSDimitry Andric 16560b57cec5SDimitry Andric /// Fold icmp (and (sh X, Y), C2), C1. 1657e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpAndShift(ICmpInst &Cmp, 1658e8d8bef9SDimitry Andric BinaryOperator *And, 1659e8d8bef9SDimitry Andric const APInt &C1, 1660e8d8bef9SDimitry Andric const APInt &C2) { 16610b57cec5SDimitry Andric BinaryOperator *Shift = dyn_cast<BinaryOperator>(And->getOperand(0)); 16620b57cec5SDimitry Andric if (!Shift || !Shift->isShift()) 16630b57cec5SDimitry Andric return nullptr; 16640b57cec5SDimitry Andric 16650b57cec5SDimitry Andric // If this is: (X >> C3) & C2 != C1 (where any shift and any compare could 16660b57cec5SDimitry Andric // exist), turn it into (X & (C2 << C3)) != (C1 << C3). This happens a LOT in 16670b57cec5SDimitry Andric // code produced by the clang front-end, for bitfield access. 16680b57cec5SDimitry Andric // This seemingly simple opportunity to fold away a shift turns out to be 16690b57cec5SDimitry Andric // rather complicated. See PR17827 for details. 16700b57cec5SDimitry Andric unsigned ShiftOpcode = Shift->getOpcode(); 16710b57cec5SDimitry Andric bool IsShl = ShiftOpcode == Instruction::Shl; 16720b57cec5SDimitry Andric const APInt *C3; 16730b57cec5SDimitry Andric if (match(Shift->getOperand(1), m_APInt(C3))) { 16745ffd83dbSDimitry Andric APInt NewAndCst, NewCmpCst; 16755ffd83dbSDimitry Andric bool AnyCmpCstBitsShiftedOut; 16760b57cec5SDimitry Andric if (ShiftOpcode == Instruction::Shl) { 16770b57cec5SDimitry Andric // For a left shift, we can fold if the comparison is not signed. We can 16780b57cec5SDimitry Andric // also fold a signed comparison if the mask value and comparison value 16790b57cec5SDimitry Andric // are not negative. These constraints may not be obvious, but we can 16800b57cec5SDimitry Andric // prove that they are correct using an SMT solver. 16815ffd83dbSDimitry Andric if (Cmp.isSigned() && (C2.isNegative() || C1.isNegative())) 16825ffd83dbSDimitry Andric return nullptr; 16835ffd83dbSDimitry Andric 16845ffd83dbSDimitry Andric NewCmpCst = C1.lshr(*C3); 16855ffd83dbSDimitry Andric NewAndCst = C2.lshr(*C3); 16865ffd83dbSDimitry Andric AnyCmpCstBitsShiftedOut = NewCmpCst.shl(*C3) != C1; 16875ffd83dbSDimitry Andric } else if (ShiftOpcode == Instruction::LShr) { 16880b57cec5SDimitry Andric // For a logical right shift, we can fold if the comparison is not signed. 16890b57cec5SDimitry Andric // We can also fold a signed comparison if the shifted mask value and the 16900b57cec5SDimitry Andric // shifted comparison value are not negative. These constraints may not be 16910b57cec5SDimitry Andric // obvious, but we can prove that they are correct using an SMT solver. 16925ffd83dbSDimitry Andric NewCmpCst = C1.shl(*C3); 16935ffd83dbSDimitry Andric NewAndCst = C2.shl(*C3); 16945ffd83dbSDimitry Andric AnyCmpCstBitsShiftedOut = NewCmpCst.lshr(*C3) != C1; 16955ffd83dbSDimitry Andric if (Cmp.isSigned() && (NewAndCst.isNegative() || NewCmpCst.isNegative())) 16965ffd83dbSDimitry Andric return nullptr; 16975ffd83dbSDimitry Andric } else { 16985ffd83dbSDimitry Andric // For an arithmetic shift, check that both constants don't use (in a 16995ffd83dbSDimitry Andric // signed sense) the top bits being shifted out. 17005ffd83dbSDimitry Andric assert(ShiftOpcode == Instruction::AShr && "Unknown shift opcode"); 17015ffd83dbSDimitry Andric NewCmpCst = C1.shl(*C3); 17025ffd83dbSDimitry Andric NewAndCst = C2.shl(*C3); 17035ffd83dbSDimitry Andric AnyCmpCstBitsShiftedOut = NewCmpCst.ashr(*C3) != C1; 17045ffd83dbSDimitry Andric if (NewAndCst.ashr(*C3) != C2) 17055ffd83dbSDimitry Andric return nullptr; 17060b57cec5SDimitry Andric } 17070b57cec5SDimitry Andric 17085ffd83dbSDimitry Andric if (AnyCmpCstBitsShiftedOut) { 17090b57cec5SDimitry Andric // If we shifted bits out, the fold is not going to work out. As a 17100b57cec5SDimitry Andric // special case, check to see if this means that the result is always 17110b57cec5SDimitry Andric // true or false now. 17120b57cec5SDimitry Andric if (Cmp.getPredicate() == ICmpInst::ICMP_EQ) 17130b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, ConstantInt::getFalse(Cmp.getType())); 17140b57cec5SDimitry Andric if (Cmp.getPredicate() == ICmpInst::ICMP_NE) 17150b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, ConstantInt::getTrue(Cmp.getType())); 17160b57cec5SDimitry Andric } else { 17175ffd83dbSDimitry Andric Value *NewAnd = Builder.CreateAnd( 17185ffd83dbSDimitry Andric Shift->getOperand(0), ConstantInt::get(And->getType(), NewAndCst)); 17195ffd83dbSDimitry Andric return new ICmpInst(Cmp.getPredicate(), 17205ffd83dbSDimitry Andric NewAnd, ConstantInt::get(And->getType(), NewCmpCst)); 17210b57cec5SDimitry Andric } 17220b57cec5SDimitry Andric } 17230b57cec5SDimitry Andric 17240b57cec5SDimitry Andric // Turn ((X >> Y) & C2) == 0 into (X & (C2 << Y)) == 0. The latter is 17250b57cec5SDimitry Andric // preferable because it allows the C2 << Y expression to be hoisted out of a 17260b57cec5SDimitry Andric // loop if Y is invariant and X is not. 1727349cc55cSDimitry Andric if (Shift->hasOneUse() && C1.isZero() && Cmp.isEquality() && 17280b57cec5SDimitry Andric !Shift->isArithmeticShift() && !isa<Constant>(Shift->getOperand(0))) { 17290b57cec5SDimitry Andric // Compute C2 << Y. 17300b57cec5SDimitry Andric Value *NewShift = 17310b57cec5SDimitry Andric IsShl ? Builder.CreateLShr(And->getOperand(1), Shift->getOperand(1)) 17320b57cec5SDimitry Andric : Builder.CreateShl(And->getOperand(1), Shift->getOperand(1)); 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andric // Compute X & (C2 << Y). 17350b57cec5SDimitry Andric Value *NewAnd = Builder.CreateAnd(Shift->getOperand(0), NewShift); 17365ffd83dbSDimitry Andric return replaceOperand(Cmp, 0, NewAnd); 17370b57cec5SDimitry Andric } 17380b57cec5SDimitry Andric 17390b57cec5SDimitry Andric return nullptr; 17400b57cec5SDimitry Andric } 17410b57cec5SDimitry Andric 17420b57cec5SDimitry Andric /// Fold icmp (and X, C2), C1. 1743e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp, 17440b57cec5SDimitry Andric BinaryOperator *And, 17450b57cec5SDimitry Andric const APInt &C1) { 17460b57cec5SDimitry Andric bool isICMP_NE = Cmp.getPredicate() == ICmpInst::ICMP_NE; 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric // For vectors: icmp ne (and X, 1), 0 --> trunc X to N x i1 17490b57cec5SDimitry Andric // TODO: We canonicalize to the longer form for scalars because we have 17500b57cec5SDimitry Andric // better analysis/folds for icmp, and codegen may be better with icmp. 1751349cc55cSDimitry Andric if (isICMP_NE && Cmp.getType()->isVectorTy() && C1.isZero() && 17520b57cec5SDimitry Andric match(And->getOperand(1), m_One())) 17530b57cec5SDimitry Andric return new TruncInst(And->getOperand(0), Cmp.getType()); 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric const APInt *C2; 17560b57cec5SDimitry Andric Value *X; 17570b57cec5SDimitry Andric if (!match(And, m_And(m_Value(X), m_APInt(C2)))) 17580b57cec5SDimitry Andric return nullptr; 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric // Don't perform the following transforms if the AND has multiple uses 17610b57cec5SDimitry Andric if (!And->hasOneUse()) 17620b57cec5SDimitry Andric return nullptr; 17630b57cec5SDimitry Andric 1764349cc55cSDimitry Andric if (Cmp.isEquality() && C1.isZero()) { 17650b57cec5SDimitry Andric // Restrict this fold to single-use 'and' (PR10267). 17660b57cec5SDimitry Andric // Replace (and X, (1 << size(X)-1) != 0) with X s< 0 17670b57cec5SDimitry Andric if (C2->isSignMask()) { 17680b57cec5SDimitry Andric Constant *Zero = Constant::getNullValue(X->getType()); 17690b57cec5SDimitry Andric auto NewPred = isICMP_NE ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE; 17700b57cec5SDimitry Andric return new ICmpInst(NewPred, X, Zero); 17710b57cec5SDimitry Andric } 17720b57cec5SDimitry Andric 1773753f127fSDimitry Andric APInt NewC2 = *C2; 1774753f127fSDimitry Andric KnownBits Know = computeKnownBits(And->getOperand(0), 0, And); 1775753f127fSDimitry Andric // Set high zeros of C2 to allow matching negated power-of-2. 1776bdd1243dSDimitry Andric NewC2 = *C2 | APInt::getHighBitsSet(C2->getBitWidth(), 1777753f127fSDimitry Andric Know.countMinLeadingZeros()); 1778753f127fSDimitry Andric 17790b57cec5SDimitry Andric // Restrict this fold only for single-use 'and' (PR10267). 17800b57cec5SDimitry Andric // ((%x & C) == 0) --> %x u< (-C) iff (-C) is power of two. 1781753f127fSDimitry Andric if (NewC2.isNegatedPowerOf2()) { 1782753f127fSDimitry Andric Constant *NegBOC = ConstantInt::get(And->getType(), -NewC2); 17830b57cec5SDimitry Andric auto NewPred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; 17840b57cec5SDimitry Andric return new ICmpInst(NewPred, X, NegBOC); 17850b57cec5SDimitry Andric } 17860b57cec5SDimitry Andric } 17870b57cec5SDimitry Andric 17880b57cec5SDimitry Andric // If the LHS is an 'and' of a truncate and we can widen the and/compare to 17890b57cec5SDimitry Andric // the input width without changing the value produced, eliminate the cast: 17900b57cec5SDimitry Andric // 17910b57cec5SDimitry Andric // icmp (and (trunc W), C2), C1 -> icmp (and W, C2'), C1' 17920b57cec5SDimitry Andric // 17930b57cec5SDimitry Andric // We can do this transformation if the constants do not have their sign bits 17940b57cec5SDimitry Andric // set or if it is an equality comparison. Extending a relational comparison 17950b57cec5SDimitry Andric // when we're checking the sign bit would not work. 17960b57cec5SDimitry Andric Value *W; 17970b57cec5SDimitry Andric if (match(And->getOperand(0), m_OneUse(m_Trunc(m_Value(W)))) && 17980b57cec5SDimitry Andric (Cmp.isEquality() || (!C1.isNegative() && !C2->isNegative()))) { 17990b57cec5SDimitry Andric // TODO: Is this a good transform for vectors? Wider types may reduce 18000b57cec5SDimitry Andric // throughput. Should this transform be limited (even for scalars) by using 18010b57cec5SDimitry Andric // shouldChangeType()? 18020b57cec5SDimitry Andric if (!Cmp.getType()->isVectorTy()) { 18030b57cec5SDimitry Andric Type *WideType = W->getType(); 18040b57cec5SDimitry Andric unsigned WideScalarBits = WideType->getScalarSizeInBits(); 18050b57cec5SDimitry Andric Constant *ZextC1 = ConstantInt::get(WideType, C1.zext(WideScalarBits)); 18060b57cec5SDimitry Andric Constant *ZextC2 = ConstantInt::get(WideType, C2->zext(WideScalarBits)); 18070b57cec5SDimitry Andric Value *NewAnd = Builder.CreateAnd(W, ZextC2, And->getName()); 18080b57cec5SDimitry Andric return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1); 18090b57cec5SDimitry Andric } 18100b57cec5SDimitry Andric } 18110b57cec5SDimitry Andric 18120b57cec5SDimitry Andric if (Instruction *I = foldICmpAndShift(Cmp, And, C1, *C2)) 18130b57cec5SDimitry Andric return I; 18140b57cec5SDimitry Andric 18150b57cec5SDimitry Andric // (icmp pred (and (or (lshr A, B), A), 1), 0) --> 18160b57cec5SDimitry Andric // (icmp pred (and A, (or (shl 1, B), 1), 0)) 18170b57cec5SDimitry Andric // 18180b57cec5SDimitry Andric // iff pred isn't signed 1819349cc55cSDimitry Andric if (!Cmp.isSigned() && C1.isZero() && And->getOperand(0)->hasOneUse() && 18200b57cec5SDimitry Andric match(And->getOperand(1), m_One())) { 18210b57cec5SDimitry Andric Constant *One = cast<Constant>(And->getOperand(1)); 18220b57cec5SDimitry Andric Value *Or = And->getOperand(0); 18230b57cec5SDimitry Andric Value *A, *B, *LShr; 18240b57cec5SDimitry Andric if (match(Or, m_Or(m_Value(LShr), m_Value(A))) && 18250b57cec5SDimitry Andric match(LShr, m_LShr(m_Specific(A), m_Value(B)))) { 18260b57cec5SDimitry Andric unsigned UsesRemoved = 0; 18270b57cec5SDimitry Andric if (And->hasOneUse()) 18280b57cec5SDimitry Andric ++UsesRemoved; 18290b57cec5SDimitry Andric if (Or->hasOneUse()) 18300b57cec5SDimitry Andric ++UsesRemoved; 18310b57cec5SDimitry Andric if (LShr->hasOneUse()) 18320b57cec5SDimitry Andric ++UsesRemoved; 18330b57cec5SDimitry Andric 18340b57cec5SDimitry Andric // Compute A & ((1 << B) | 1) 183506c3fb27SDimitry Andric unsigned RequireUsesRemoved = match(B, m_ImmConstant()) ? 1 : 3; 183606c3fb27SDimitry Andric if (UsesRemoved >= RequireUsesRemoved) { 183706c3fb27SDimitry Andric Value *NewOr = 183806c3fb27SDimitry Andric Builder.CreateOr(Builder.CreateShl(One, B, LShr->getName(), 18390b57cec5SDimitry Andric /*HasNUW=*/true), 18400b57cec5SDimitry Andric One, Or->getName()); 18410b57cec5SDimitry Andric Value *NewAnd = Builder.CreateAnd(A, NewOr, And->getName()); 18425ffd83dbSDimitry Andric return replaceOperand(Cmp, 0, NewAnd); 18430b57cec5SDimitry Andric } 18440b57cec5SDimitry Andric } 18450b57cec5SDimitry Andric } 18460b57cec5SDimitry Andric 1847*0fca6ea1SDimitry Andric // (icmp eq (and (bitcast X to int), ExponentMask), ExponentMask) --> 1848*0fca6ea1SDimitry Andric // llvm.is.fpclass(X, fcInf|fcNan) 1849*0fca6ea1SDimitry Andric // (icmp ne (and (bitcast X to int), ExponentMask), ExponentMask) --> 1850*0fca6ea1SDimitry Andric // llvm.is.fpclass(X, ~(fcInf|fcNan)) 1851*0fca6ea1SDimitry Andric Value *V; 1852*0fca6ea1SDimitry Andric if (!Cmp.getParent()->getParent()->hasFnAttribute( 1853*0fca6ea1SDimitry Andric Attribute::NoImplicitFloat) && 1854*0fca6ea1SDimitry Andric Cmp.isEquality() && 1855*0fca6ea1SDimitry Andric match(X, m_OneUse(m_ElementWiseBitCast(m_Value(V))))) { 1856*0fca6ea1SDimitry Andric Type *FPType = V->getType()->getScalarType(); 1857*0fca6ea1SDimitry Andric if (FPType->isIEEELikeFPTy() && C1 == *C2) { 1858*0fca6ea1SDimitry Andric APInt ExponentMask = 1859*0fca6ea1SDimitry Andric APFloat::getInf(FPType->getFltSemantics()).bitcastToAPInt(); 1860*0fca6ea1SDimitry Andric if (C1 == ExponentMask) { 1861*0fca6ea1SDimitry Andric unsigned Mask = FPClassTest::fcNan | FPClassTest::fcInf; 1862*0fca6ea1SDimitry Andric if (isICMP_NE) 1863*0fca6ea1SDimitry Andric Mask = ~Mask & fcAllFlags; 1864*0fca6ea1SDimitry Andric return replaceInstUsesWith(Cmp, Builder.createIsFPClass(V, Mask)); 1865*0fca6ea1SDimitry Andric } 1866*0fca6ea1SDimitry Andric } 1867*0fca6ea1SDimitry Andric } 1868*0fca6ea1SDimitry Andric 18690b57cec5SDimitry Andric return nullptr; 18700b57cec5SDimitry Andric } 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andric /// Fold icmp (and X, Y), C. 1873e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp, 18740b57cec5SDimitry Andric BinaryOperator *And, 18750b57cec5SDimitry Andric const APInt &C) { 18760b57cec5SDimitry Andric if (Instruction *I = foldICmpAndConstConst(Cmp, And, C)) 18770b57cec5SDimitry Andric return I; 18780b57cec5SDimitry Andric 1879fe6060f1SDimitry Andric const ICmpInst::Predicate Pred = Cmp.getPredicate(); 1880fe6060f1SDimitry Andric bool TrueIfNeg; 1881fe6060f1SDimitry Andric if (isSignBitCheck(Pred, C, TrueIfNeg)) { 1882fe6060f1SDimitry Andric // ((X - 1) & ~X) < 0 --> X == 0 1883fe6060f1SDimitry Andric // ((X - 1) & ~X) >= 0 --> X != 0 1884fe6060f1SDimitry Andric Value *X; 1885fe6060f1SDimitry Andric if (match(And->getOperand(0), m_Add(m_Value(X), m_AllOnes())) && 1886fe6060f1SDimitry Andric match(And->getOperand(1), m_Not(m_Specific(X)))) { 1887fe6060f1SDimitry Andric auto NewPred = TrueIfNeg ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE; 1888fe6060f1SDimitry Andric return new ICmpInst(NewPred, X, ConstantInt::getNullValue(X->getType())); 1889fe6060f1SDimitry Andric } 1890*0fca6ea1SDimitry Andric // (X & -X) < 0 --> X == MinSignedC 1891*0fca6ea1SDimitry Andric // (X & -X) > -1 --> X != MinSignedC 189206c3fb27SDimitry Andric if (match(And, m_c_And(m_Neg(m_Value(X)), m_Deferred(X)))) { 189306c3fb27SDimitry Andric Constant *MinSignedC = ConstantInt::get( 189406c3fb27SDimitry Andric X->getType(), 189506c3fb27SDimitry Andric APInt::getSignedMinValue(X->getType()->getScalarSizeInBits())); 189606c3fb27SDimitry Andric auto NewPred = TrueIfNeg ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE; 189706c3fb27SDimitry Andric return new ICmpInst(NewPred, X, MinSignedC); 189806c3fb27SDimitry Andric } 1899fe6060f1SDimitry Andric } 1900fe6060f1SDimitry Andric 19010b57cec5SDimitry Andric // TODO: These all require that Y is constant too, so refactor with the above. 19020b57cec5SDimitry Andric 19030b57cec5SDimitry Andric // Try to optimize things like "A[i] & 42 == 0" to index computations. 19040b57cec5SDimitry Andric Value *X = And->getOperand(0); 19050b57cec5SDimitry Andric Value *Y = And->getOperand(1); 190681ad6265SDimitry Andric if (auto *C2 = dyn_cast<ConstantInt>(Y)) 19070b57cec5SDimitry Andric if (auto *LI = dyn_cast<LoadInst>(X)) 19080b57cec5SDimitry Andric if (auto *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0))) 19090b57cec5SDimitry Andric if (auto *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0))) 191081ad6265SDimitry Andric if (Instruction *Res = 191181ad6265SDimitry Andric foldCmpLoadFromIndexedGlobal(LI, GEP, GV, Cmp, C2)) 19120b57cec5SDimitry Andric return Res; 19130b57cec5SDimitry Andric 19140b57cec5SDimitry Andric if (!Cmp.isEquality()) 19150b57cec5SDimitry Andric return nullptr; 19160b57cec5SDimitry Andric 19170b57cec5SDimitry Andric // X & -C == -C -> X > u ~C 19180b57cec5SDimitry Andric // X & -C != -C -> X <= u ~C 19190b57cec5SDimitry Andric // iff C is a power of 2 1920349cc55cSDimitry Andric if (Cmp.getOperand(1) == Y && C.isNegatedPowerOf2()) { 1921fe6060f1SDimitry Andric auto NewPred = 1922fe6060f1SDimitry Andric Pred == CmpInst::ICMP_EQ ? CmpInst::ICMP_UGT : CmpInst::ICMP_ULE; 19230b57cec5SDimitry Andric return new ICmpInst(NewPred, X, SubOne(cast<Constant>(Cmp.getOperand(1)))); 19240b57cec5SDimitry Andric } 19250b57cec5SDimitry Andric 192606c3fb27SDimitry Andric // If we are testing the intersection of 2 select-of-nonzero-constants with no 192706c3fb27SDimitry Andric // common bits set, it's the same as checking if exactly one select condition 192806c3fb27SDimitry Andric // is set: 192906c3fb27SDimitry Andric // ((A ? TC : FC) & (B ? TC : FC)) == 0 --> xor A, B 193006c3fb27SDimitry Andric // ((A ? TC : FC) & (B ? TC : FC)) != 0 --> not(xor A, B) 193106c3fb27SDimitry Andric // TODO: Generalize for non-constant values. 193206c3fb27SDimitry Andric // TODO: Handle signed/unsigned predicates. 193306c3fb27SDimitry Andric // TODO: Handle other bitwise logic connectors. 193406c3fb27SDimitry Andric // TODO: Extend to handle a non-zero compare constant. 193506c3fb27SDimitry Andric if (C.isZero() && (Pred == CmpInst::ICMP_EQ || And->hasOneUse())) { 193606c3fb27SDimitry Andric assert(Cmp.isEquality() && "Not expecting non-equality predicates"); 193706c3fb27SDimitry Andric Value *A, *B; 193806c3fb27SDimitry Andric const APInt *TC, *FC; 193906c3fb27SDimitry Andric if (match(X, m_Select(m_Value(A), m_APInt(TC), m_APInt(FC))) && 194006c3fb27SDimitry Andric match(Y, 194106c3fb27SDimitry Andric m_Select(m_Value(B), m_SpecificInt(*TC), m_SpecificInt(*FC))) && 194206c3fb27SDimitry Andric !TC->isZero() && !FC->isZero() && !TC->intersects(*FC)) { 194306c3fb27SDimitry Andric Value *R = Builder.CreateXor(A, B); 194406c3fb27SDimitry Andric if (Pred == CmpInst::ICMP_NE) 194506c3fb27SDimitry Andric R = Builder.CreateNot(R); 194606c3fb27SDimitry Andric return replaceInstUsesWith(Cmp, R); 194706c3fb27SDimitry Andric } 194806c3fb27SDimitry Andric } 194906c3fb27SDimitry Andric 1950bdd1243dSDimitry Andric // ((zext i1 X) & Y) == 0 --> !((trunc Y) & X) 1951bdd1243dSDimitry Andric // ((zext i1 X) & Y) != 0 --> ((trunc Y) & X) 1952bdd1243dSDimitry Andric // ((zext i1 X) & Y) == 1 --> ((trunc Y) & X) 1953bdd1243dSDimitry Andric // ((zext i1 X) & Y) != 1 --> !((trunc Y) & X) 1954bdd1243dSDimitry Andric if (match(And, m_OneUse(m_c_And(m_OneUse(m_ZExt(m_Value(X))), m_Value(Y)))) && 1955bdd1243dSDimitry Andric X->getType()->isIntOrIntVectorTy(1) && (C.isZero() || C.isOne())) { 1956bdd1243dSDimitry Andric Value *TruncY = Builder.CreateTrunc(Y, X->getType()); 1957bdd1243dSDimitry Andric if (C.isZero() ^ (Pred == CmpInst::ICMP_NE)) { 1958bdd1243dSDimitry Andric Value *And = Builder.CreateAnd(TruncY, X); 1959bdd1243dSDimitry Andric return BinaryOperator::CreateNot(And); 1960bdd1243dSDimitry Andric } 1961bdd1243dSDimitry Andric return BinaryOperator::CreateAnd(TruncY, X); 1962bdd1243dSDimitry Andric } 1963bdd1243dSDimitry Andric 1964*0fca6ea1SDimitry Andric // (icmp eq/ne (and (shl -1, X), Y), 0) 1965*0fca6ea1SDimitry Andric // -> (icmp eq/ne (lshr Y, X), 0) 1966*0fca6ea1SDimitry Andric // We could technically handle any C == 0 or (C < 0 && isOdd(C)) but it seems 1967*0fca6ea1SDimitry Andric // highly unlikely the non-zero case will ever show up in code. 1968*0fca6ea1SDimitry Andric if (C.isZero() && 1969*0fca6ea1SDimitry Andric match(And, m_OneUse(m_c_And(m_OneUse(m_Shl(m_AllOnes(), m_Value(X))), 1970*0fca6ea1SDimitry Andric m_Value(Y))))) { 1971*0fca6ea1SDimitry Andric Value *LShr = Builder.CreateLShr(Y, X); 1972*0fca6ea1SDimitry Andric return new ICmpInst(Pred, LShr, Constant::getNullValue(LShr->getType())); 1973*0fca6ea1SDimitry Andric } 1974*0fca6ea1SDimitry Andric 19750b57cec5SDimitry Andric return nullptr; 19760b57cec5SDimitry Andric } 19770b57cec5SDimitry Andric 19785f757f3fSDimitry Andric /// Fold icmp eq/ne (or (xor/sub (X1, X2), xor/sub (X3, X4))), 0. 19795f757f3fSDimitry Andric static Value *foldICmpOrXorSubChain(ICmpInst &Cmp, BinaryOperator *Or, 198006c3fb27SDimitry Andric InstCombiner::BuilderTy &Builder) { 19815f757f3fSDimitry Andric // Are we using xors or subs to bitwise check for a pair or pairs of 19825f757f3fSDimitry Andric // (in)equalities? Convert to a shorter form that has more potential to be 19835f757f3fSDimitry Andric // folded even further. 19845f757f3fSDimitry Andric // ((X1 ^/- X2) || (X3 ^/- X4)) == 0 --> (X1 == X2) && (X3 == X4) 19855f757f3fSDimitry Andric // ((X1 ^/- X2) || (X3 ^/- X4)) != 0 --> (X1 != X2) || (X3 != X4) 19865f757f3fSDimitry Andric // ((X1 ^/- X2) || (X3 ^/- X4) || (X5 ^/- X6)) == 0 --> 198706c3fb27SDimitry Andric // (X1 == X2) && (X3 == X4) && (X5 == X6) 19885f757f3fSDimitry Andric // ((X1 ^/- X2) || (X3 ^/- X4) || (X5 ^/- X6)) != 0 --> 198906c3fb27SDimitry Andric // (X1 != X2) || (X3 != X4) || (X5 != X6) 199006c3fb27SDimitry Andric SmallVector<std::pair<Value *, Value *>, 2> CmpValues; 199106c3fb27SDimitry Andric SmallVector<Value *, 16> WorkList(1, Or); 199206c3fb27SDimitry Andric 199306c3fb27SDimitry Andric while (!WorkList.empty()) { 199406c3fb27SDimitry Andric auto MatchOrOperatorArgument = [&](Value *OrOperatorArgument) { 199506c3fb27SDimitry Andric Value *Lhs, *Rhs; 199606c3fb27SDimitry Andric 199706c3fb27SDimitry Andric if (match(OrOperatorArgument, 199806c3fb27SDimitry Andric m_OneUse(m_Xor(m_Value(Lhs), m_Value(Rhs))))) { 199906c3fb27SDimitry Andric CmpValues.emplace_back(Lhs, Rhs); 20005f757f3fSDimitry Andric return; 200106c3fb27SDimitry Andric } 20025f757f3fSDimitry Andric 20035f757f3fSDimitry Andric if (match(OrOperatorArgument, 20045f757f3fSDimitry Andric m_OneUse(m_Sub(m_Value(Lhs), m_Value(Rhs))))) { 20055f757f3fSDimitry Andric CmpValues.emplace_back(Lhs, Rhs); 20065f757f3fSDimitry Andric return; 20075f757f3fSDimitry Andric } 20085f757f3fSDimitry Andric 20095f757f3fSDimitry Andric WorkList.push_back(OrOperatorArgument); 201006c3fb27SDimitry Andric }; 201106c3fb27SDimitry Andric 201206c3fb27SDimitry Andric Value *CurrentValue = WorkList.pop_back_val(); 201306c3fb27SDimitry Andric Value *OrOperatorLhs, *OrOperatorRhs; 201406c3fb27SDimitry Andric 201506c3fb27SDimitry Andric if (!match(CurrentValue, 201606c3fb27SDimitry Andric m_Or(m_Value(OrOperatorLhs), m_Value(OrOperatorRhs)))) { 201706c3fb27SDimitry Andric return nullptr; 201806c3fb27SDimitry Andric } 201906c3fb27SDimitry Andric 202006c3fb27SDimitry Andric MatchOrOperatorArgument(OrOperatorRhs); 202106c3fb27SDimitry Andric MatchOrOperatorArgument(OrOperatorLhs); 202206c3fb27SDimitry Andric } 202306c3fb27SDimitry Andric 202406c3fb27SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 202506c3fb27SDimitry Andric auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or; 202606c3fb27SDimitry Andric Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.rbegin()->first, 202706c3fb27SDimitry Andric CmpValues.rbegin()->second); 202806c3fb27SDimitry Andric 202906c3fb27SDimitry Andric for (auto It = CmpValues.rbegin() + 1; It != CmpValues.rend(); ++It) { 203006c3fb27SDimitry Andric Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second); 203106c3fb27SDimitry Andric LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp); 203206c3fb27SDimitry Andric } 203306c3fb27SDimitry Andric 203406c3fb27SDimitry Andric return LhsCmp; 203506c3fb27SDimitry Andric } 203606c3fb27SDimitry Andric 20370b57cec5SDimitry Andric /// Fold icmp (or X, Y), C. 2038e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp, 2039e8d8bef9SDimitry Andric BinaryOperator *Or, 20400b57cec5SDimitry Andric const APInt &C) { 20410b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 2042349cc55cSDimitry Andric if (C.isOne()) { 20430b57cec5SDimitry Andric // icmp slt signum(V) 1 --> icmp slt V, 1 20440b57cec5SDimitry Andric Value *V = nullptr; 20450b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SLT && match(Or, m_Signum(m_Value(V)))) 20460b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, V, 20470b57cec5SDimitry Andric ConstantInt::get(V->getType(), 1)); 20480b57cec5SDimitry Andric } 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andric Value *OrOp0 = Or->getOperand(0), *OrOp1 = Or->getOperand(1); 2051*0fca6ea1SDimitry Andric 2052*0fca6ea1SDimitry Andric // (icmp eq/ne (or disjoint x, C0), C1) 2053*0fca6ea1SDimitry Andric // -> (icmp eq/ne x, C0^C1) 2054*0fca6ea1SDimitry Andric if (Cmp.isEquality() && match(OrOp1, m_ImmConstant()) && 2055*0fca6ea1SDimitry Andric cast<PossiblyDisjointInst>(Or)->isDisjoint()) { 2056*0fca6ea1SDimitry Andric Value *NewC = 2057*0fca6ea1SDimitry Andric Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(), C)); 2058*0fca6ea1SDimitry Andric return new ICmpInst(Pred, OrOp0, NewC); 2059*0fca6ea1SDimitry Andric } 2060*0fca6ea1SDimitry Andric 20615ffd83dbSDimitry Andric const APInt *MaskC; 20625ffd83dbSDimitry Andric if (match(OrOp1, m_APInt(MaskC)) && Cmp.isEquality()) { 20635ffd83dbSDimitry Andric if (*MaskC == C && (C + 1).isPowerOf2()) { 20640b57cec5SDimitry Andric // X | C == C --> X <=u C 20650b57cec5SDimitry Andric // X | C != C --> X >u C 20660b57cec5SDimitry Andric // iff C+1 is a power of 2 (C is a bitmask of the low bits) 20670b57cec5SDimitry Andric Pred = (Pred == CmpInst::ICMP_EQ) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT; 20680b57cec5SDimitry Andric return new ICmpInst(Pred, OrOp0, OrOp1); 20690b57cec5SDimitry Andric } 20705ffd83dbSDimitry Andric 20715ffd83dbSDimitry Andric // More general: canonicalize 'equality with set bits mask' to 20725ffd83dbSDimitry Andric // 'equality with clear bits mask'. 20735ffd83dbSDimitry Andric // (X | MaskC) == C --> (X & ~MaskC) == C ^ MaskC 20745ffd83dbSDimitry Andric // (X | MaskC) != C --> (X & ~MaskC) != C ^ MaskC 20750b57cec5SDimitry Andric if (Or->hasOneUse()) { 20765ffd83dbSDimitry Andric Value *And = Builder.CreateAnd(OrOp0, ~(*MaskC)); 20775ffd83dbSDimitry Andric Constant *NewC = ConstantInt::get(Or->getType(), C ^ (*MaskC)); 20785ffd83dbSDimitry Andric return new ICmpInst(Pred, And, NewC); 20790b57cec5SDimitry Andric } 20800b57cec5SDimitry Andric } 20810b57cec5SDimitry Andric 2082349cc55cSDimitry Andric // (X | (X-1)) s< 0 --> X s< 1 2083349cc55cSDimitry Andric // (X | (X-1)) s> -1 --> X s> 0 2084349cc55cSDimitry Andric Value *X; 2085349cc55cSDimitry Andric bool TrueIfSigned; 2086349cc55cSDimitry Andric if (isSignBitCheck(Pred, C, TrueIfSigned) && 2087349cc55cSDimitry Andric match(Or, m_c_Or(m_Add(m_Value(X), m_AllOnes()), m_Deferred(X)))) { 2088349cc55cSDimitry Andric auto NewPred = TrueIfSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGT; 2089349cc55cSDimitry Andric Constant *NewC = ConstantInt::get(X->getType(), TrueIfSigned ? 1 : 0); 2090349cc55cSDimitry Andric return new ICmpInst(NewPred, X, NewC); 2091349cc55cSDimitry Andric } 2092349cc55cSDimitry Andric 209306c3fb27SDimitry Andric const APInt *OrC; 209406c3fb27SDimitry Andric // icmp(X | OrC, C) --> icmp(X, 0) 209506c3fb27SDimitry Andric if (C.isNonNegative() && match(Or, m_Or(m_Value(X), m_APInt(OrC)))) { 209606c3fb27SDimitry Andric switch (Pred) { 209706c3fb27SDimitry Andric // X | OrC s< C --> X s< 0 iff OrC s>= C s>= 0 209806c3fb27SDimitry Andric case ICmpInst::ICMP_SLT: 209906c3fb27SDimitry Andric // X | OrC s>= C --> X s>= 0 iff OrC s>= C s>= 0 210006c3fb27SDimitry Andric case ICmpInst::ICMP_SGE: 210106c3fb27SDimitry Andric if (OrC->sge(C)) 210206c3fb27SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); 210306c3fb27SDimitry Andric break; 210406c3fb27SDimitry Andric // X | OrC s<= C --> X s< 0 iff OrC s> C s>= 0 210506c3fb27SDimitry Andric case ICmpInst::ICMP_SLE: 210606c3fb27SDimitry Andric // X | OrC s> C --> X s>= 0 iff OrC s> C s>= 0 210706c3fb27SDimitry Andric case ICmpInst::ICMP_SGT: 210806c3fb27SDimitry Andric if (OrC->sgt(C)) 210906c3fb27SDimitry Andric return new ICmpInst(ICmpInst::getFlippedStrictnessPredicate(Pred), X, 211006c3fb27SDimitry Andric ConstantInt::getNullValue(X->getType())); 211106c3fb27SDimitry Andric break; 211206c3fb27SDimitry Andric default: 211306c3fb27SDimitry Andric break; 211406c3fb27SDimitry Andric } 211506c3fb27SDimitry Andric } 211606c3fb27SDimitry Andric 2117349cc55cSDimitry Andric if (!Cmp.isEquality() || !C.isZero() || !Or->hasOneUse()) 21180b57cec5SDimitry Andric return nullptr; 21190b57cec5SDimitry Andric 21200b57cec5SDimitry Andric Value *P, *Q; 21210b57cec5SDimitry Andric if (match(Or, m_Or(m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(Q))))) { 21220b57cec5SDimitry Andric // Simplify icmp eq (or (ptrtoint P), (ptrtoint Q)), 0 21230b57cec5SDimitry Andric // -> and (icmp eq P, null), (icmp eq Q, null). 21240b57cec5SDimitry Andric Value *CmpP = 21250b57cec5SDimitry Andric Builder.CreateICmp(Pred, P, ConstantInt::getNullValue(P->getType())); 21260b57cec5SDimitry Andric Value *CmpQ = 21270b57cec5SDimitry Andric Builder.CreateICmp(Pred, Q, ConstantInt::getNullValue(Q->getType())); 21280b57cec5SDimitry Andric auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or; 21290b57cec5SDimitry Andric return BinaryOperator::Create(BOpc, CmpP, CmpQ); 21300b57cec5SDimitry Andric } 21310b57cec5SDimitry Andric 21325f757f3fSDimitry Andric if (Value *V = foldICmpOrXorSubChain(Cmp, Or, Builder)) 213306c3fb27SDimitry Andric return replaceInstUsesWith(Cmp, V); 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric return nullptr; 21360b57cec5SDimitry Andric } 21370b57cec5SDimitry Andric 21380b57cec5SDimitry Andric /// Fold icmp (mul X, Y), C. 2139e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpMulConstant(ICmpInst &Cmp, 21400b57cec5SDimitry Andric BinaryOperator *Mul, 21410b57cec5SDimitry Andric const APInt &C) { 2142bdd1243dSDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 2143bdd1243dSDimitry Andric Type *MulTy = Mul->getType(); 2144bdd1243dSDimitry Andric Value *X = Mul->getOperand(0); 2145bdd1243dSDimitry Andric 2146bdd1243dSDimitry Andric // If there's no overflow: 2147bdd1243dSDimitry Andric // X * X == 0 --> X == 0 2148bdd1243dSDimitry Andric // X * X != 0 --> X != 0 2149bdd1243dSDimitry Andric if (Cmp.isEquality() && C.isZero() && X == Mul->getOperand(1) && 2150bdd1243dSDimitry Andric (Mul->hasNoUnsignedWrap() || Mul->hasNoSignedWrap())) 2151bdd1243dSDimitry Andric return new ICmpInst(Pred, X, ConstantInt::getNullValue(MulTy)); 2152bdd1243dSDimitry Andric 21530b57cec5SDimitry Andric const APInt *MulC; 21540b57cec5SDimitry Andric if (!match(Mul->getOperand(1), m_APInt(MulC))) 21550b57cec5SDimitry Andric return nullptr; 21560b57cec5SDimitry Andric 21570b57cec5SDimitry Andric // If this is a test of the sign bit and the multiply is sign-preserving with 2158bdd1243dSDimitry Andric // a constant operand, use the multiply LHS operand instead: 2159bdd1243dSDimitry Andric // (X * +MulC) < 0 --> X < 0 2160bdd1243dSDimitry Andric // (X * -MulC) < 0 --> X > 0 21610b57cec5SDimitry Andric if (isSignTest(Pred, C) && Mul->hasNoSignedWrap()) { 21620b57cec5SDimitry Andric if (MulC->isNegative()) 21630b57cec5SDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 2164bdd1243dSDimitry Andric return new ICmpInst(Pred, X, ConstantInt::getNullValue(MulTy)); 21650b57cec5SDimitry Andric } 21660b57cec5SDimitry Andric 216706c3fb27SDimitry Andric if (MulC->isZero()) 2168fcaf7f86SDimitry Andric return nullptr; 2169fcaf7f86SDimitry Andric 217006c3fb27SDimitry Andric // If the multiply does not wrap or the constant is odd, try to divide the 217106c3fb27SDimitry Andric // compare constant by the multiplication factor. 2172fcaf7f86SDimitry Andric if (Cmp.isEquality()) { 217306c3fb27SDimitry Andric // (mul nsw X, MulC) eq/ne C --> X eq/ne C /s MulC 2174349cc55cSDimitry Andric if (Mul->hasNoSignedWrap() && C.srem(*MulC).isZero()) { 2175bdd1243dSDimitry Andric Constant *NewC = ConstantInt::get(MulTy, C.sdiv(*MulC)); 2176bdd1243dSDimitry Andric return new ICmpInst(Pred, X, NewC); 2177e8d8bef9SDimitry Andric } 217806c3fb27SDimitry Andric 217906c3fb27SDimitry Andric // C % MulC == 0 is weaker than we could use if MulC is odd because it 218006c3fb27SDimitry Andric // correct to transform if MulC * N == C including overflow. I.e with i8 218106c3fb27SDimitry Andric // (icmp eq (mul X, 5), 101) -> (icmp eq X, 225) but since 101 % 5 != 0, we 218206c3fb27SDimitry Andric // miss that case. 218306c3fb27SDimitry Andric if (C.urem(*MulC).isZero()) { 218406c3fb27SDimitry Andric // (mul nuw X, MulC) eq/ne C --> X eq/ne C /u MulC 218506c3fb27SDimitry Andric // (mul X, OddC) eq/ne N * C --> X eq/ne N 218606c3fb27SDimitry Andric if ((*MulC & 1).isOne() || Mul->hasNoUnsignedWrap()) { 2187bdd1243dSDimitry Andric Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC)); 2188bdd1243dSDimitry Andric return new ICmpInst(Pred, X, NewC); 2189e8d8bef9SDimitry Andric } 2190e8d8bef9SDimitry Andric } 219106c3fb27SDimitry Andric } 2192e8d8bef9SDimitry Andric 2193bdd1243dSDimitry Andric // With a matching no-overflow guarantee, fold the constants: 2194bdd1243dSDimitry Andric // (X * MulC) < C --> X < (C / MulC) 2195bdd1243dSDimitry Andric // (X * MulC) > C --> X > (C / MulC) 2196bdd1243dSDimitry Andric // TODO: Assert that Pred is not equal to SGE, SLE, UGE, ULE? 2197fcaf7f86SDimitry Andric Constant *NewC = nullptr; 219806c3fb27SDimitry Andric if (Mul->hasNoSignedWrap() && ICmpInst::isSigned(Pred)) { 2199fcaf7f86SDimitry Andric // MININT / -1 --> overflow. 2200fcaf7f86SDimitry Andric if (C.isMinSignedValue() && MulC->isAllOnes()) 22010b57cec5SDimitry Andric return nullptr; 2202bdd1243dSDimitry Andric if (MulC->isNegative()) 2203fcaf7f86SDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 2204bdd1243dSDimitry Andric 220506c3fb27SDimitry Andric if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) { 2206fcaf7f86SDimitry Andric NewC = ConstantInt::get( 2207bdd1243dSDimitry Andric MulTy, APIntOps::RoundingSDiv(C, *MulC, APInt::Rounding::UP)); 220806c3fb27SDimitry Andric } else { 220906c3fb27SDimitry Andric assert((Pred == ICmpInst::ICMP_SLE || Pred == ICmpInst::ICMP_SGT) && 221006c3fb27SDimitry Andric "Unexpected predicate"); 2211fcaf7f86SDimitry Andric NewC = ConstantInt::get( 2212bdd1243dSDimitry Andric MulTy, APIntOps::RoundingSDiv(C, *MulC, APInt::Rounding::DOWN)); 221306c3fb27SDimitry Andric } 221406c3fb27SDimitry Andric } else if (Mul->hasNoUnsignedWrap() && ICmpInst::isUnsigned(Pred)) { 221506c3fb27SDimitry Andric if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE) { 2216fcaf7f86SDimitry Andric NewC = ConstantInt::get( 2217bdd1243dSDimitry Andric MulTy, APIntOps::RoundingUDiv(C, *MulC, APInt::Rounding::UP)); 221806c3fb27SDimitry Andric } else { 221906c3fb27SDimitry Andric assert((Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_UGT) && 222006c3fb27SDimitry Andric "Unexpected predicate"); 2221fcaf7f86SDimitry Andric NewC = ConstantInt::get( 2222bdd1243dSDimitry Andric MulTy, APIntOps::RoundingUDiv(C, *MulC, APInt::Rounding::DOWN)); 2223fcaf7f86SDimitry Andric } 222406c3fb27SDimitry Andric } 2225fcaf7f86SDimitry Andric 2226bdd1243dSDimitry Andric return NewC ? new ICmpInst(Pred, X, NewC) : nullptr; 22270b57cec5SDimitry Andric } 22280b57cec5SDimitry Andric 22290b57cec5SDimitry Andric /// Fold icmp (shl 1, Y), C. 22300b57cec5SDimitry Andric static Instruction *foldICmpShlOne(ICmpInst &Cmp, Instruction *Shl, 22310b57cec5SDimitry Andric const APInt &C) { 22320b57cec5SDimitry Andric Value *Y; 22330b57cec5SDimitry Andric if (!match(Shl, m_Shl(m_One(), m_Value(Y)))) 22340b57cec5SDimitry Andric return nullptr; 22350b57cec5SDimitry Andric 22360b57cec5SDimitry Andric Type *ShiftType = Shl->getType(); 22370b57cec5SDimitry Andric unsigned TypeBits = C.getBitWidth(); 22380b57cec5SDimitry Andric bool CIsPowerOf2 = C.isPowerOf2(); 22390b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 22400b57cec5SDimitry Andric if (Cmp.isUnsigned()) { 22410b57cec5SDimitry Andric // (1 << Y) pred C -> Y pred Log2(C) 22420b57cec5SDimitry Andric if (!CIsPowerOf2) { 22430b57cec5SDimitry Andric // (1 << Y) < 30 -> Y <= 4 22440b57cec5SDimitry Andric // (1 << Y) <= 30 -> Y <= 4 22450b57cec5SDimitry Andric // (1 << Y) >= 30 -> Y > 4 22460b57cec5SDimitry Andric // (1 << Y) > 30 -> Y > 4 22470b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT) 22480b57cec5SDimitry Andric Pred = ICmpInst::ICMP_ULE; 22490b57cec5SDimitry Andric else if (Pred == ICmpInst::ICMP_UGE) 22500b57cec5SDimitry Andric Pred = ICmpInst::ICMP_UGT; 22510b57cec5SDimitry Andric } 22520b57cec5SDimitry Andric 22530b57cec5SDimitry Andric unsigned CLog2 = C.logBase2(); 22540b57cec5SDimitry Andric return new ICmpInst(Pred, Y, ConstantInt::get(ShiftType, CLog2)); 22550b57cec5SDimitry Andric } else if (Cmp.isSigned()) { 22560b57cec5SDimitry Andric Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1); 22570b57cec5SDimitry Andric // (1 << Y) > 0 -> Y != 31 2258bdd1243dSDimitry Andric // (1 << Y) > C -> Y != 31 if C is negative. 2259bdd1243dSDimitry Andric if (Pred == ICmpInst::ICMP_SGT && C.sle(0)) 22600b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Y, BitWidthMinusOne); 2261bdd1243dSDimitry Andric 2262bdd1243dSDimitry Andric // (1 << Y) < 0 -> Y == 31 2263bdd1243dSDimitry Andric // (1 << Y) < 1 -> Y == 31 2264bdd1243dSDimitry Andric // (1 << Y) < C -> Y == 31 if C is negative and not signed min. 2265bdd1243dSDimitry Andric // Exclude signed min by subtracting 1 and lower the upper bound to 0. 2266bdd1243dSDimitry Andric if (Pred == ICmpInst::ICMP_SLT && (C-1).sle(0)) 2267bdd1243dSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Y, BitWidthMinusOne); 22680b57cec5SDimitry Andric } 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric return nullptr; 22710b57cec5SDimitry Andric } 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric /// Fold icmp (shl X, Y), C. 2274e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp, 22750b57cec5SDimitry Andric BinaryOperator *Shl, 22760b57cec5SDimitry Andric const APInt &C) { 22770b57cec5SDimitry Andric const APInt *ShiftVal; 22780b57cec5SDimitry Andric if (Cmp.isEquality() && match(Shl->getOperand(0), m_APInt(ShiftVal))) 22790b57cec5SDimitry Andric return foldICmpShlConstConst(Cmp, Shl->getOperand(1), C, *ShiftVal); 22800b57cec5SDimitry Andric 228106c3fb27SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 228206c3fb27SDimitry Andric // (icmp pred (shl nuw&nsw X, Y), Csle0) 228306c3fb27SDimitry Andric // -> (icmp pred X, Csle0) 228406c3fb27SDimitry Andric // 228506c3fb27SDimitry Andric // The idea is the nuw/nsw essentially freeze the sign bit for the shift op 228606c3fb27SDimitry Andric // so X's must be what is used. 228706c3fb27SDimitry Andric if (C.sle(0) && Shl->hasNoUnsignedWrap() && Shl->hasNoSignedWrap()) 228806c3fb27SDimitry Andric return new ICmpInst(Pred, Shl->getOperand(0), Cmp.getOperand(1)); 228906c3fb27SDimitry Andric 229006c3fb27SDimitry Andric // (icmp eq/ne (shl nuw|nsw X, Y), 0) 229106c3fb27SDimitry Andric // -> (icmp eq/ne X, 0) 229206c3fb27SDimitry Andric if (ICmpInst::isEquality(Pred) && C.isZero() && 229306c3fb27SDimitry Andric (Shl->hasNoUnsignedWrap() || Shl->hasNoSignedWrap())) 229406c3fb27SDimitry Andric return new ICmpInst(Pred, Shl->getOperand(0), Cmp.getOperand(1)); 229506c3fb27SDimitry Andric 229606c3fb27SDimitry Andric // (icmp slt (shl nsw X, Y), 0/1) 229706c3fb27SDimitry Andric // -> (icmp slt X, 0/1) 229806c3fb27SDimitry Andric // (icmp sgt (shl nsw X, Y), 0/-1) 229906c3fb27SDimitry Andric // -> (icmp sgt X, 0/-1) 230006c3fb27SDimitry Andric // 230106c3fb27SDimitry Andric // NB: sge/sle with a constant will canonicalize to sgt/slt. 230206c3fb27SDimitry Andric if (Shl->hasNoSignedWrap() && 230306c3fb27SDimitry Andric (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT)) 230406c3fb27SDimitry Andric if (C.isZero() || (Pred == ICmpInst::ICMP_SGT ? C.isAllOnes() : C.isOne())) 230506c3fb27SDimitry Andric return new ICmpInst(Pred, Shl->getOperand(0), Cmp.getOperand(1)); 230606c3fb27SDimitry Andric 23070b57cec5SDimitry Andric const APInt *ShiftAmt; 23080b57cec5SDimitry Andric if (!match(Shl->getOperand(1), m_APInt(ShiftAmt))) 23090b57cec5SDimitry Andric return foldICmpShlOne(Cmp, Shl, C); 23100b57cec5SDimitry Andric 23110b57cec5SDimitry Andric // Check that the shift amount is in range. If not, don't perform undefined 23120b57cec5SDimitry Andric // shifts. When the shift is visited, it will be simplified. 23130b57cec5SDimitry Andric unsigned TypeBits = C.getBitWidth(); 23140b57cec5SDimitry Andric if (ShiftAmt->uge(TypeBits)) 23150b57cec5SDimitry Andric return nullptr; 23160b57cec5SDimitry Andric 23170b57cec5SDimitry Andric Value *X = Shl->getOperand(0); 23180b57cec5SDimitry Andric Type *ShType = Shl->getType(); 23190b57cec5SDimitry Andric 23200b57cec5SDimitry Andric // NSW guarantees that we are only shifting out sign bits from the high bits, 23210b57cec5SDimitry Andric // so we can ASHR the compare constant without needing a mask and eliminate 23220b57cec5SDimitry Andric // the shift. 23230b57cec5SDimitry Andric if (Shl->hasNoSignedWrap()) { 23240b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SGT) { 23250b57cec5SDimitry Andric // icmp Pred (shl nsw X, ShiftAmt), C --> icmp Pred X, (C >>s ShiftAmt) 23260b57cec5SDimitry Andric APInt ShiftedC = C.ashr(*ShiftAmt); 23270b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); 23280b57cec5SDimitry Andric } 23290b57cec5SDimitry Andric if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) && 23300b57cec5SDimitry Andric C.ashr(*ShiftAmt).shl(*ShiftAmt) == C) { 23310b57cec5SDimitry Andric APInt ShiftedC = C.ashr(*ShiftAmt); 23320b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); 23330b57cec5SDimitry Andric } 23340b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SLT) { 23350b57cec5SDimitry Andric // SLE is the same as above, but SLE is canonicalized to SLT, so convert: 23360b57cec5SDimitry Andric // (X << S) <=s C is equiv to X <=s (C >> S) for all C 23370b57cec5SDimitry Andric // (X << S) <s (C + 1) is equiv to X <s (C >> S) + 1 if C <s SMAX 23380b57cec5SDimitry Andric // (X << S) <s C is equiv to X <s ((C - 1) >> S) + 1 if C >s SMIN 23390b57cec5SDimitry Andric assert(!C.isMinSignedValue() && "Unexpected icmp slt"); 23400b57cec5SDimitry Andric APInt ShiftedC = (C - 1).ashr(*ShiftAmt) + 1; 23410b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); 23420b57cec5SDimitry Andric } 23430b57cec5SDimitry Andric } 23440b57cec5SDimitry Andric 23450b57cec5SDimitry Andric // NUW guarantees that we are only shifting out zero bits from the high bits, 23460b57cec5SDimitry Andric // so we can LSHR the compare constant without needing a mask and eliminate 23470b57cec5SDimitry Andric // the shift. 23480b57cec5SDimitry Andric if (Shl->hasNoUnsignedWrap()) { 23490b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT) { 23500b57cec5SDimitry Andric // icmp Pred (shl nuw X, ShiftAmt), C --> icmp Pred X, (C >>u ShiftAmt) 23510b57cec5SDimitry Andric APInt ShiftedC = C.lshr(*ShiftAmt); 23520b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); 23530b57cec5SDimitry Andric } 23540b57cec5SDimitry Andric if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) && 23550b57cec5SDimitry Andric C.lshr(*ShiftAmt).shl(*ShiftAmt) == C) { 23560b57cec5SDimitry Andric APInt ShiftedC = C.lshr(*ShiftAmt); 23570b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); 23580b57cec5SDimitry Andric } 23590b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT) { 23600b57cec5SDimitry Andric // ULE is the same as above, but ULE is canonicalized to ULT, so convert: 23610b57cec5SDimitry Andric // (X << S) <=u C is equiv to X <=u (C >> S) for all C 23620b57cec5SDimitry Andric // (X << S) <u (C + 1) is equiv to X <u (C >> S) + 1 if C <u ~0u 23630b57cec5SDimitry Andric // (X << S) <u C is equiv to X <u ((C - 1) >> S) + 1 if C >u 0 23640b57cec5SDimitry Andric assert(C.ugt(0) && "ult 0 should have been eliminated"); 23650b57cec5SDimitry Andric APInt ShiftedC = (C - 1).lshr(*ShiftAmt) + 1; 23660b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC)); 23670b57cec5SDimitry Andric } 23680b57cec5SDimitry Andric } 23690b57cec5SDimitry Andric 23700b57cec5SDimitry Andric if (Cmp.isEquality() && Shl->hasOneUse()) { 23710b57cec5SDimitry Andric // Strength-reduce the shift into an 'and'. 23720b57cec5SDimitry Andric Constant *Mask = ConstantInt::get( 23730b57cec5SDimitry Andric ShType, 23740b57cec5SDimitry Andric APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt->getZExtValue())); 23750b57cec5SDimitry Andric Value *And = Builder.CreateAnd(X, Mask, Shl->getName() + ".mask"); 23760b57cec5SDimitry Andric Constant *LShrC = ConstantInt::get(ShType, C.lshr(*ShiftAmt)); 23770b57cec5SDimitry Andric return new ICmpInst(Pred, And, LShrC); 23780b57cec5SDimitry Andric } 23790b57cec5SDimitry Andric 23800b57cec5SDimitry Andric // Otherwise, if this is a comparison of the sign bit, simplify to and/test. 23810b57cec5SDimitry Andric bool TrueIfSigned = false; 23820b57cec5SDimitry Andric if (Shl->hasOneUse() && isSignBitCheck(Pred, C, TrueIfSigned)) { 23830b57cec5SDimitry Andric // (X << 31) <s 0 --> (X & 1) != 0 23840b57cec5SDimitry Andric Constant *Mask = ConstantInt::get( 23850b57cec5SDimitry Andric ShType, 23860b57cec5SDimitry Andric APInt::getOneBitSet(TypeBits, TypeBits - ShiftAmt->getZExtValue() - 1)); 23870b57cec5SDimitry Andric Value *And = Builder.CreateAnd(X, Mask, Shl->getName() + ".mask"); 23880b57cec5SDimitry Andric return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ, 23890b57cec5SDimitry Andric And, Constant::getNullValue(ShType)); 23900b57cec5SDimitry Andric } 23910b57cec5SDimitry Andric 23920b57cec5SDimitry Andric // Simplify 'shl' inequality test into 'and' equality test. 23930b57cec5SDimitry Andric if (Cmp.isUnsigned() && Shl->hasOneUse()) { 23940b57cec5SDimitry Andric // (X l<< C2) u<=/u> C1 iff C1+1 is power of two -> X & (~C1 l>> C2) ==/!= 0 23950b57cec5SDimitry Andric if ((C + 1).isPowerOf2() && 23960b57cec5SDimitry Andric (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_UGT)) { 23970b57cec5SDimitry Andric Value *And = Builder.CreateAnd(X, (~C).lshr(ShiftAmt->getZExtValue())); 23980b57cec5SDimitry Andric return new ICmpInst(Pred == ICmpInst::ICMP_ULE ? ICmpInst::ICMP_EQ 23990b57cec5SDimitry Andric : ICmpInst::ICMP_NE, 24000b57cec5SDimitry Andric And, Constant::getNullValue(ShType)); 24010b57cec5SDimitry Andric } 24020b57cec5SDimitry Andric // (X l<< C2) u</u>= C1 iff C1 is power of two -> X & (-C1 l>> C2) ==/!= 0 24030b57cec5SDimitry Andric if (C.isPowerOf2() && 24040b57cec5SDimitry Andric (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)) { 24050b57cec5SDimitry Andric Value *And = 24060b57cec5SDimitry Andric Builder.CreateAnd(X, (~(C - 1)).lshr(ShiftAmt->getZExtValue())); 24070b57cec5SDimitry Andric return new ICmpInst(Pred == ICmpInst::ICMP_ULT ? ICmpInst::ICMP_EQ 24080b57cec5SDimitry Andric : ICmpInst::ICMP_NE, 24090b57cec5SDimitry Andric And, Constant::getNullValue(ShType)); 24100b57cec5SDimitry Andric } 24110b57cec5SDimitry Andric } 24120b57cec5SDimitry Andric 24130b57cec5SDimitry Andric // Transform (icmp pred iM (shl iM %v, N), C) 24140b57cec5SDimitry Andric // -> (icmp pred i(M-N) (trunc %v iM to i(M-N)), (trunc (C>>N)) 24150b57cec5SDimitry Andric // Transform the shl to a trunc if (trunc (C>>N)) has no loss and M-N. 24160b57cec5SDimitry Andric // This enables us to get rid of the shift in favor of a trunc that may be 24170b57cec5SDimitry Andric // free on the target. It has the additional benefit of comparing to a 24180b57cec5SDimitry Andric // smaller constant that may be more target-friendly. 24190b57cec5SDimitry Andric unsigned Amt = ShiftAmt->getLimitedValue(TypeBits - 1); 2420*0fca6ea1SDimitry Andric if (Shl->hasOneUse() && Amt != 0 && 2421*0fca6ea1SDimitry Andric shouldChangeType(ShType->getScalarSizeInBits(), TypeBits - Amt)) { 2422*0fca6ea1SDimitry Andric ICmpInst::Predicate CmpPred = Pred; 2423*0fca6ea1SDimitry Andric APInt RHSC = C; 2424*0fca6ea1SDimitry Andric 2425*0fca6ea1SDimitry Andric if (RHSC.countr_zero() < Amt && ICmpInst::isStrictPredicate(CmpPred)) { 2426*0fca6ea1SDimitry Andric // Try the flipped strictness predicate. 2427*0fca6ea1SDimitry Andric // e.g.: 2428*0fca6ea1SDimitry Andric // icmp ult i64 (shl X, 32), 8589934593 -> 2429*0fca6ea1SDimitry Andric // icmp ule i64 (shl X, 32), 8589934592 -> 2430*0fca6ea1SDimitry Andric // icmp ule i32 (trunc X, i32), 2 -> 2431*0fca6ea1SDimitry Andric // icmp ult i32 (trunc X, i32), 3 2432*0fca6ea1SDimitry Andric if (auto FlippedStrictness = 2433*0fca6ea1SDimitry Andric InstCombiner::getFlippedStrictnessPredicateAndConstant( 2434*0fca6ea1SDimitry Andric Pred, ConstantInt::get(ShType->getContext(), C))) { 2435*0fca6ea1SDimitry Andric CmpPred = FlippedStrictness->first; 2436*0fca6ea1SDimitry Andric RHSC = cast<ConstantInt>(FlippedStrictness->second)->getValue(); 2437*0fca6ea1SDimitry Andric } 2438*0fca6ea1SDimitry Andric } 2439*0fca6ea1SDimitry Andric 2440*0fca6ea1SDimitry Andric if (RHSC.countr_zero() >= Amt) { 2441*0fca6ea1SDimitry Andric Type *TruncTy = ShType->getWithNewBitWidth(TypeBits - Amt); 24420b57cec5SDimitry Andric Constant *NewC = 2443*0fca6ea1SDimitry Andric ConstantInt::get(TruncTy, RHSC.ashr(*ShiftAmt).trunc(TypeBits - Amt)); 2444*0fca6ea1SDimitry Andric return new ICmpInst(CmpPred, 2445*0fca6ea1SDimitry Andric Builder.CreateTrunc(X, TruncTy, "", /*IsNUW=*/false, 2446*0fca6ea1SDimitry Andric Shl->hasNoSignedWrap()), 2447*0fca6ea1SDimitry Andric NewC); 2448*0fca6ea1SDimitry Andric } 24490b57cec5SDimitry Andric } 24500b57cec5SDimitry Andric 24510b57cec5SDimitry Andric return nullptr; 24520b57cec5SDimitry Andric } 24530b57cec5SDimitry Andric 24540b57cec5SDimitry Andric /// Fold icmp ({al}shr X, Y), C. 2455e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp, 24560b57cec5SDimitry Andric BinaryOperator *Shr, 24570b57cec5SDimitry Andric const APInt &C) { 24580b57cec5SDimitry Andric // An exact shr only shifts out zero bits, so: 24590b57cec5SDimitry Andric // icmp eq/ne (shr X, Y), 0 --> icmp eq/ne X, 0 24600b57cec5SDimitry Andric Value *X = Shr->getOperand(0); 24610b57cec5SDimitry Andric CmpInst::Predicate Pred = Cmp.getPredicate(); 246204eeddc0SDimitry Andric if (Cmp.isEquality() && Shr->isExact() && C.isZero()) 24630b57cec5SDimitry Andric return new ICmpInst(Pred, X, Cmp.getOperand(1)); 24640b57cec5SDimitry Andric 246581ad6265SDimitry Andric bool IsAShr = Shr->getOpcode() == Instruction::AShr; 246681ad6265SDimitry Andric const APInt *ShiftValC; 2467fcaf7f86SDimitry Andric if (match(X, m_APInt(ShiftValC))) { 246881ad6265SDimitry Andric if (Cmp.isEquality()) 246981ad6265SDimitry Andric return foldICmpShrConstConst(Cmp, Shr->getOperand(1), C, *ShiftValC); 24700b57cec5SDimitry Andric 2471fcaf7f86SDimitry Andric // (ShiftValC >> Y) >s -1 --> Y != 0 with ShiftValC < 0 2472fcaf7f86SDimitry Andric // (ShiftValC >> Y) <s 0 --> Y == 0 with ShiftValC < 0 2473fcaf7f86SDimitry Andric bool TrueIfSigned; 2474fcaf7f86SDimitry Andric if (!IsAShr && ShiftValC->isNegative() && 2475fcaf7f86SDimitry Andric isSignBitCheck(Pred, C, TrueIfSigned)) 2476fcaf7f86SDimitry Andric return new ICmpInst(TrueIfSigned ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE, 2477fcaf7f86SDimitry Andric Shr->getOperand(1), 2478fcaf7f86SDimitry Andric ConstantInt::getNullValue(X->getType())); 2479fcaf7f86SDimitry Andric 248081ad6265SDimitry Andric // If the shifted constant is a power-of-2, test the shift amount directly: 2481fcaf7f86SDimitry Andric // (ShiftValC >> Y) >u C --> X <u (LZ(C) - LZ(ShiftValC)) 2482fcaf7f86SDimitry Andric // (ShiftValC >> Y) <u C --> X >=u (LZ(C-1) - LZ(ShiftValC)) 248381ad6265SDimitry Andric if (!IsAShr && ShiftValC->isPowerOf2() && 248481ad6265SDimitry Andric (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_ULT)) { 248581ad6265SDimitry Andric bool IsUGT = Pred == CmpInst::ICMP_UGT; 248681ad6265SDimitry Andric assert(ShiftValC->uge(C) && "Expected simplify of compare"); 248781ad6265SDimitry Andric assert((IsUGT || !C.isZero()) && "Expected X u< 0 to simplify"); 248881ad6265SDimitry Andric 248906c3fb27SDimitry Andric unsigned CmpLZ = IsUGT ? C.countl_zero() : (C - 1).countl_zero(); 249006c3fb27SDimitry Andric unsigned ShiftLZ = ShiftValC->countl_zero(); 249181ad6265SDimitry Andric Constant *NewC = ConstantInt::get(Shr->getType(), CmpLZ - ShiftLZ); 249281ad6265SDimitry Andric auto NewPred = IsUGT ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE; 249381ad6265SDimitry Andric return new ICmpInst(NewPred, Shr->getOperand(1), NewC); 249481ad6265SDimitry Andric } 249581ad6265SDimitry Andric } 249681ad6265SDimitry Andric 249781ad6265SDimitry Andric const APInt *ShiftAmtC; 249881ad6265SDimitry Andric if (!match(Shr->getOperand(1), m_APInt(ShiftAmtC))) 24990b57cec5SDimitry Andric return nullptr; 25000b57cec5SDimitry Andric 25010b57cec5SDimitry Andric // Check that the shift amount is in range. If not, don't perform undefined 25020b57cec5SDimitry Andric // shifts. When the shift is visited it will be simplified. 25030b57cec5SDimitry Andric unsigned TypeBits = C.getBitWidth(); 250481ad6265SDimitry Andric unsigned ShAmtVal = ShiftAmtC->getLimitedValue(TypeBits); 25050b57cec5SDimitry Andric if (ShAmtVal >= TypeBits || ShAmtVal == 0) 25060b57cec5SDimitry Andric return nullptr; 25070b57cec5SDimitry Andric 25080b57cec5SDimitry Andric bool IsExact = Shr->isExact(); 25090b57cec5SDimitry Andric Type *ShrTy = Shr->getType(); 25100b57cec5SDimitry Andric // TODO: If we could guarantee that InstSimplify would handle all of the 25110b57cec5SDimitry Andric // constant-value-based preconditions in the folds below, then we could assert 25120b57cec5SDimitry Andric // those conditions rather than checking them. This is difficult because of 25130b57cec5SDimitry Andric // undef/poison (PR34838). 25145f757f3fSDimitry Andric if (IsAShr && Shr->hasOneUse()) { 2515*0fca6ea1SDimitry Andric if (IsExact && (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT) && 2516*0fca6ea1SDimitry Andric (C - 1).isPowerOf2() && C.countLeadingZeros() > ShAmtVal) { 2517*0fca6ea1SDimitry Andric // When C - 1 is a power of two and the transform can be legally 2518*0fca6ea1SDimitry Andric // performed, prefer this form so the produced constant is close to a 2519*0fca6ea1SDimitry Andric // power of two. 2520*0fca6ea1SDimitry Andric // icmp slt/ult (ashr exact X, ShAmtC), C 2521*0fca6ea1SDimitry Andric // --> icmp slt/ult X, (C - 1) << ShAmtC) + 1 2522*0fca6ea1SDimitry Andric APInt ShiftedC = (C - 1).shl(ShAmtVal) + 1; 2523*0fca6ea1SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); 2524*0fca6ea1SDimitry Andric } 252504eeddc0SDimitry Andric if (IsExact || Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT) { 252604eeddc0SDimitry Andric // When ShAmtC can be shifted losslessly: 252704eeddc0SDimitry Andric // icmp PRED (ashr exact X, ShAmtC), C --> icmp PRED X, (C << ShAmtC) 252804eeddc0SDimitry Andric // icmp slt/ult (ashr X, ShAmtC), C --> icmp slt/ult X, (C << ShAmtC) 25290b57cec5SDimitry Andric APInt ShiftedC = C.shl(ShAmtVal); 25300b57cec5SDimitry Andric if (ShiftedC.ashr(ShAmtVal) == C) 25310b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); 25320b57cec5SDimitry Andric } 25330b57cec5SDimitry Andric if (Pred == CmpInst::ICMP_SGT) { 25340b57cec5SDimitry Andric // icmp sgt (ashr X, ShAmtC), C --> icmp sgt X, ((C + 1) << ShAmtC) - 1 25350b57cec5SDimitry Andric APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1; 25360b57cec5SDimitry Andric if (!C.isMaxSignedValue() && !(C + 1).shl(ShAmtVal).isMinSignedValue() && 25370b57cec5SDimitry Andric (ShiftedC + 1).ashr(ShAmtVal) == (C + 1)) 25380b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); 25390b57cec5SDimitry Andric } 254004eeddc0SDimitry Andric if (Pred == CmpInst::ICMP_UGT) { 254104eeddc0SDimitry Andric // icmp ugt (ashr X, ShAmtC), C --> icmp ugt X, ((C + 1) << ShAmtC) - 1 254281ad6265SDimitry Andric // 'C + 1 << ShAmtC' can overflow as a signed number, so the 2nd 254381ad6265SDimitry Andric // clause accounts for that pattern. 254404eeddc0SDimitry Andric APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1; 254581ad6265SDimitry Andric if ((ShiftedC + 1).ashr(ShAmtVal) == (C + 1) || 254681ad6265SDimitry Andric (C + 1).shl(ShAmtVal).isMinSignedValue()) 254704eeddc0SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); 254804eeddc0SDimitry Andric } 2549e8d8bef9SDimitry Andric 2550e8d8bef9SDimitry Andric // If the compare constant has significant bits above the lowest sign-bit, 2551e8d8bef9SDimitry Andric // then convert an unsigned cmp to a test of the sign-bit: 2552e8d8bef9SDimitry Andric // (ashr X, ShiftC) u> C --> X s< 0 2553e8d8bef9SDimitry Andric // (ashr X, ShiftC) u< C --> X s> -1 2554e8d8bef9SDimitry Andric if (C.getBitWidth() > 2 && C.getNumSignBits() <= ShAmtVal) { 2555e8d8bef9SDimitry Andric if (Pred == CmpInst::ICMP_UGT) { 2556e8d8bef9SDimitry Andric return new ICmpInst(CmpInst::ICMP_SLT, X, 2557e8d8bef9SDimitry Andric ConstantInt::getNullValue(ShrTy)); 2558e8d8bef9SDimitry Andric } 2559e8d8bef9SDimitry Andric if (Pred == CmpInst::ICMP_ULT) { 2560e8d8bef9SDimitry Andric return new ICmpInst(CmpInst::ICMP_SGT, X, 2561e8d8bef9SDimitry Andric ConstantInt::getAllOnesValue(ShrTy)); 2562e8d8bef9SDimitry Andric } 2563e8d8bef9SDimitry Andric } 25645f757f3fSDimitry Andric } else if (!IsAShr) { 25650b57cec5SDimitry Andric if (Pred == CmpInst::ICMP_ULT || (Pred == CmpInst::ICMP_UGT && IsExact)) { 25660b57cec5SDimitry Andric // icmp ult (lshr X, ShAmtC), C --> icmp ult X, (C << ShAmtC) 25670b57cec5SDimitry Andric // icmp ugt (lshr exact X, ShAmtC), C --> icmp ugt X, (C << ShAmtC) 25680b57cec5SDimitry Andric APInt ShiftedC = C.shl(ShAmtVal); 25690b57cec5SDimitry Andric if (ShiftedC.lshr(ShAmtVal) == C) 25700b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); 25710b57cec5SDimitry Andric } 25720b57cec5SDimitry Andric if (Pred == CmpInst::ICMP_UGT) { 25730b57cec5SDimitry Andric // icmp ugt (lshr X, ShAmtC), C --> icmp ugt X, ((C + 1) << ShAmtC) - 1 25740b57cec5SDimitry Andric APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1; 25750b57cec5SDimitry Andric if ((ShiftedC + 1).lshr(ShAmtVal) == (C + 1)) 25760b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); 25770b57cec5SDimitry Andric } 25780b57cec5SDimitry Andric } 25790b57cec5SDimitry Andric 25800b57cec5SDimitry Andric if (!Cmp.isEquality()) 25810b57cec5SDimitry Andric return nullptr; 25820b57cec5SDimitry Andric 25830b57cec5SDimitry Andric // Handle equality comparisons of shift-by-constant. 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andric // If the comparison constant changes with the shift, the comparison cannot 25860b57cec5SDimitry Andric // succeed (bits of the comparison constant cannot match the shifted value). 25870b57cec5SDimitry Andric // This should be known by InstSimplify and already be folded to true/false. 25880b57cec5SDimitry Andric assert(((IsAShr && C.shl(ShAmtVal).ashr(ShAmtVal) == C) || 25890b57cec5SDimitry Andric (!IsAShr && C.shl(ShAmtVal).lshr(ShAmtVal) == C)) && 25900b57cec5SDimitry Andric "Expected icmp+shr simplify did not occur."); 25910b57cec5SDimitry Andric 25920b57cec5SDimitry Andric // If the bits shifted out are known zero, compare the unshifted value: 25930b57cec5SDimitry Andric // (X & 4) >> 1 == 2 --> (X & 4) == 4. 25940b57cec5SDimitry Andric if (Shr->isExact()) 25950b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, C << ShAmtVal)); 25960b57cec5SDimitry Andric 2597349cc55cSDimitry Andric if (C.isZero()) { 2598fe6060f1SDimitry Andric // == 0 is u< 1. 2599fe6060f1SDimitry Andric if (Pred == CmpInst::ICMP_EQ) 2600fe6060f1SDimitry Andric return new ICmpInst(CmpInst::ICMP_ULT, X, 2601fe6060f1SDimitry Andric ConstantInt::get(ShrTy, (C + 1).shl(ShAmtVal))); 2602fe6060f1SDimitry Andric else 2603fe6060f1SDimitry Andric return new ICmpInst(CmpInst::ICMP_UGT, X, 2604fe6060f1SDimitry Andric ConstantInt::get(ShrTy, (C + 1).shl(ShAmtVal) - 1)); 2605fe6060f1SDimitry Andric } 2606fe6060f1SDimitry Andric 26070b57cec5SDimitry Andric if (Shr->hasOneUse()) { 26080b57cec5SDimitry Andric // Canonicalize the shift into an 'and': 26090b57cec5SDimitry Andric // icmp eq/ne (shr X, ShAmt), C --> icmp eq/ne (and X, HiMask), (C << ShAmt) 26100b57cec5SDimitry Andric APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal)); 26110b57cec5SDimitry Andric Constant *Mask = ConstantInt::get(ShrTy, Val); 26120b57cec5SDimitry Andric Value *And = Builder.CreateAnd(X, Mask, Shr->getName() + ".mask"); 26130b57cec5SDimitry Andric return new ICmpInst(Pred, And, ConstantInt::get(ShrTy, C << ShAmtVal)); 26140b57cec5SDimitry Andric } 26150b57cec5SDimitry Andric 26160b57cec5SDimitry Andric return nullptr; 26170b57cec5SDimitry Andric } 26180b57cec5SDimitry Andric 2619e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp, 26208bcb0991SDimitry Andric BinaryOperator *SRem, 26218bcb0991SDimitry Andric const APInt &C) { 26228bcb0991SDimitry Andric // Match an 'is positive' or 'is negative' comparison of remainder by a 26238bcb0991SDimitry Andric // constant power-of-2 value: 26248bcb0991SDimitry Andric // (X % pow2C) sgt/slt 0 26258bcb0991SDimitry Andric const ICmpInst::Predicate Pred = Cmp.getPredicate(); 262681ad6265SDimitry Andric if (Pred != ICmpInst::ICMP_SGT && Pred != ICmpInst::ICMP_SLT && 262781ad6265SDimitry Andric Pred != ICmpInst::ICMP_EQ && Pred != ICmpInst::ICMP_NE) 26288bcb0991SDimitry Andric return nullptr; 26298bcb0991SDimitry Andric 26308bcb0991SDimitry Andric // TODO: The one-use check is standard because we do not typically want to 26318bcb0991SDimitry Andric // create longer instruction sequences, but this might be a special-case 26328bcb0991SDimitry Andric // because srem is not good for analysis or codegen. 26338bcb0991SDimitry Andric if (!SRem->hasOneUse()) 26348bcb0991SDimitry Andric return nullptr; 26358bcb0991SDimitry Andric 26368bcb0991SDimitry Andric const APInt *DivisorC; 263781ad6265SDimitry Andric if (!match(SRem->getOperand(1), m_Power2(DivisorC))) 263881ad6265SDimitry Andric return nullptr; 263981ad6265SDimitry Andric 264081ad6265SDimitry Andric // For cmp_sgt/cmp_slt only zero valued C is handled. 264181ad6265SDimitry Andric // For cmp_eq/cmp_ne only positive valued C is handled. 264281ad6265SDimitry Andric if (((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT) && 264381ad6265SDimitry Andric !C.isZero()) || 264481ad6265SDimitry Andric ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) && 264581ad6265SDimitry Andric !C.isStrictlyPositive())) 26468bcb0991SDimitry Andric return nullptr; 26478bcb0991SDimitry Andric 26488bcb0991SDimitry Andric // Mask off the sign bit and the modulo bits (low-bits). 26498bcb0991SDimitry Andric Type *Ty = SRem->getType(); 26508bcb0991SDimitry Andric APInt SignMask = APInt::getSignMask(Ty->getScalarSizeInBits()); 26518bcb0991SDimitry Andric Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1)); 26528bcb0991SDimitry Andric Value *And = Builder.CreateAnd(SRem->getOperand(0), MaskC); 26538bcb0991SDimitry Andric 265481ad6265SDimitry Andric if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) 265581ad6265SDimitry Andric return new ICmpInst(Pred, And, ConstantInt::get(Ty, C)); 265681ad6265SDimitry Andric 26578bcb0991SDimitry Andric // For 'is positive?' check that the sign-bit is clear and at least 1 masked 26588bcb0991SDimitry Andric // bit is set. Example: 26598bcb0991SDimitry Andric // (i8 X % 32) s> 0 --> (X & 159) s> 0 26608bcb0991SDimitry Andric if (Pred == ICmpInst::ICMP_SGT) 26618bcb0991SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, And, ConstantInt::getNullValue(Ty)); 26628bcb0991SDimitry Andric 26638bcb0991SDimitry Andric // For 'is negative?' check that the sign-bit is set and at least 1 masked 26648bcb0991SDimitry Andric // bit is set. Example: 26658bcb0991SDimitry Andric // (i16 X % 4) s< 0 --> (X & 32771) u> 32768 26668bcb0991SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, And, ConstantInt::get(Ty, SignMask)); 26678bcb0991SDimitry Andric } 26688bcb0991SDimitry Andric 26690b57cec5SDimitry Andric /// Fold icmp (udiv X, Y), C. 2670e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpUDivConstant(ICmpInst &Cmp, 26710b57cec5SDimitry Andric BinaryOperator *UDiv, 26720b57cec5SDimitry Andric const APInt &C) { 267381ad6265SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 267481ad6265SDimitry Andric Value *X = UDiv->getOperand(0); 267581ad6265SDimitry Andric Value *Y = UDiv->getOperand(1); 267681ad6265SDimitry Andric Type *Ty = UDiv->getType(); 267781ad6265SDimitry Andric 26780b57cec5SDimitry Andric const APInt *C2; 267981ad6265SDimitry Andric if (!match(X, m_APInt(C2))) 26800b57cec5SDimitry Andric return nullptr; 26810b57cec5SDimitry Andric 26820b57cec5SDimitry Andric assert(*C2 != 0 && "udiv 0, X should have been simplified already."); 26830b57cec5SDimitry Andric 26840b57cec5SDimitry Andric // (icmp ugt (udiv C2, Y), C) -> (icmp ule Y, C2/(C+1)) 268581ad6265SDimitry Andric if (Pred == ICmpInst::ICMP_UGT) { 26860b57cec5SDimitry Andric assert(!C.isMaxValue() && 26870b57cec5SDimitry Andric "icmp ugt X, UINT_MAX should have been simplified already."); 26880b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULE, Y, 268981ad6265SDimitry Andric ConstantInt::get(Ty, C2->udiv(C + 1))); 26900b57cec5SDimitry Andric } 26910b57cec5SDimitry Andric 26920b57cec5SDimitry Andric // (icmp ult (udiv C2, Y), C) -> (icmp ugt Y, C2/C) 269381ad6265SDimitry Andric if (Pred == ICmpInst::ICMP_ULT) { 26940b57cec5SDimitry Andric assert(C != 0 && "icmp ult X, 0 should have been simplified already."); 26950b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, Y, 269681ad6265SDimitry Andric ConstantInt::get(Ty, C2->udiv(C))); 26970b57cec5SDimitry Andric } 26980b57cec5SDimitry Andric 26990b57cec5SDimitry Andric return nullptr; 27000b57cec5SDimitry Andric } 27010b57cec5SDimitry Andric 27020b57cec5SDimitry Andric /// Fold icmp ({su}div X, Y), C. 2703e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpDivConstant(ICmpInst &Cmp, 27040b57cec5SDimitry Andric BinaryOperator *Div, 27050b57cec5SDimitry Andric const APInt &C) { 270681ad6265SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 270781ad6265SDimitry Andric Value *X = Div->getOperand(0); 270881ad6265SDimitry Andric Value *Y = Div->getOperand(1); 270981ad6265SDimitry Andric Type *Ty = Div->getType(); 271081ad6265SDimitry Andric bool DivIsSigned = Div->getOpcode() == Instruction::SDiv; 271181ad6265SDimitry Andric 271281ad6265SDimitry Andric // If unsigned division and the compare constant is bigger than 271381ad6265SDimitry Andric // UMAX/2 (negative), there's only one pair of values that satisfies an 271481ad6265SDimitry Andric // equality check, so eliminate the division: 271581ad6265SDimitry Andric // (X u/ Y) == C --> (X == C) && (Y == 1) 271681ad6265SDimitry Andric // (X u/ Y) != C --> (X != C) || (Y != 1) 271781ad6265SDimitry Andric // Similarly, if signed division and the compare constant is exactly SMIN: 271881ad6265SDimitry Andric // (X s/ Y) == SMIN --> (X == SMIN) && (Y == 1) 271981ad6265SDimitry Andric // (X s/ Y) != SMIN --> (X != SMIN) || (Y != 1) 272081ad6265SDimitry Andric if (Cmp.isEquality() && Div->hasOneUse() && C.isSignBitSet() && 272181ad6265SDimitry Andric (!DivIsSigned || C.isMinSignedValue())) { 272281ad6265SDimitry Andric Value *XBig = Builder.CreateICmp(Pred, X, ConstantInt::get(Ty, C)); 272381ad6265SDimitry Andric Value *YOne = Builder.CreateICmp(Pred, Y, ConstantInt::get(Ty, 1)); 272481ad6265SDimitry Andric auto Logic = Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or; 272581ad6265SDimitry Andric return BinaryOperator::Create(Logic, XBig, YOne); 272681ad6265SDimitry Andric } 272781ad6265SDimitry Andric 27280b57cec5SDimitry Andric // Fold: icmp pred ([us]div X, C2), C -> range test 27290b57cec5SDimitry Andric // Fold this div into the comparison, producing a range check. 27300b57cec5SDimitry Andric // Determine, based on the divide type, what the range is being 27310b57cec5SDimitry Andric // checked. If there is an overflow on the low or high side, remember 27320b57cec5SDimitry Andric // it, otherwise compute the range [low, hi) bounding the new value. 27330b57cec5SDimitry Andric // See: InsertRangeTest above for the kinds of replacements possible. 27340b57cec5SDimitry Andric const APInt *C2; 273581ad6265SDimitry Andric if (!match(Y, m_APInt(C2))) 27360b57cec5SDimitry Andric return nullptr; 27370b57cec5SDimitry Andric 27380b57cec5SDimitry Andric // FIXME: If the operand types don't match the type of the divide 27390b57cec5SDimitry Andric // then don't attempt this transform. The code below doesn't have the 27400b57cec5SDimitry Andric // logic to deal with a signed divide and an unsigned compare (and 27410b57cec5SDimitry Andric // vice versa). This is because (x /s C2) <s C produces different 27420b57cec5SDimitry Andric // results than (x /s C2) <u C or (x /u C2) <s C or even 27430b57cec5SDimitry Andric // (x /u C2) <u C. Simply casting the operands and result won't 27440b57cec5SDimitry Andric // work. :( The if statement below tests that condition and bails 27450b57cec5SDimitry Andric // if it finds it. 27460b57cec5SDimitry Andric if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) 27470b57cec5SDimitry Andric return nullptr; 27480b57cec5SDimitry Andric 27490b57cec5SDimitry Andric // The ProdOV computation fails on divide by 0 and divide by -1. Cases with 27500b57cec5SDimitry Andric // INT_MIN will also fail if the divisor is 1. Although folds of all these 27510b57cec5SDimitry Andric // division-by-constant cases should be present, we can not assert that they 27520b57cec5SDimitry Andric // have happened before we reach this icmp instruction. 2753349cc55cSDimitry Andric if (C2->isZero() || C2->isOne() || (DivIsSigned && C2->isAllOnes())) 27540b57cec5SDimitry Andric return nullptr; 27550b57cec5SDimitry Andric 27560b57cec5SDimitry Andric // Compute Prod = C * C2. We are essentially solving an equation of 27570b57cec5SDimitry Andric // form X / C2 = C. We solve for X by multiplying C2 and C. 27580b57cec5SDimitry Andric // By solving for X, we can turn this into a range check instead of computing 27590b57cec5SDimitry Andric // a divide. 27600b57cec5SDimitry Andric APInt Prod = C * *C2; 27610b57cec5SDimitry Andric 27620b57cec5SDimitry Andric // Determine if the product overflows by seeing if the product is not equal to 27630b57cec5SDimitry Andric // the divide. Make sure we do the same kind of divide as in the LHS 27640b57cec5SDimitry Andric // instruction that we're folding. 27650b57cec5SDimitry Andric bool ProdOV = (DivIsSigned ? Prod.sdiv(*C2) : Prod.udiv(*C2)) != C; 27660b57cec5SDimitry Andric 27670b57cec5SDimitry Andric // If the division is known to be exact, then there is no remainder from the 27680b57cec5SDimitry Andric // divide, so the covered range size is unit, otherwise it is the divisor. 27690b57cec5SDimitry Andric APInt RangeSize = Div->isExact() ? APInt(C2->getBitWidth(), 1) : *C2; 27700b57cec5SDimitry Andric 27710b57cec5SDimitry Andric // Figure out the interval that is being checked. For example, a comparison 27720b57cec5SDimitry Andric // like "X /u 5 == 0" is really checking that X is in the interval [0, 5). 27730b57cec5SDimitry Andric // Compute this interval based on the constants involved and the signedness of 27740b57cec5SDimitry Andric // the compare/divide. This computes a half-open interval, keeping track of 27750b57cec5SDimitry Andric // whether either value in the interval overflows. After analysis each 27760b57cec5SDimitry Andric // overflow variable is set to 0 if it's corresponding bound variable is valid 27770b57cec5SDimitry Andric // -1 if overflowed off the bottom end, or +1 if overflowed off the top end. 27780b57cec5SDimitry Andric int LoOverflow = 0, HiOverflow = 0; 27790b57cec5SDimitry Andric APInt LoBound, HiBound; 27800b57cec5SDimitry Andric 27810b57cec5SDimitry Andric if (!DivIsSigned) { // udiv 27820b57cec5SDimitry Andric // e.g. X/5 op 3 --> [15, 20) 27830b57cec5SDimitry Andric LoBound = Prod; 27840b57cec5SDimitry Andric HiOverflow = LoOverflow = ProdOV; 27850b57cec5SDimitry Andric if (!HiOverflow) { 27860b57cec5SDimitry Andric // If this is not an exact divide, then many values in the range collapse 27870b57cec5SDimitry Andric // to the same result value. 27880b57cec5SDimitry Andric HiOverflow = addWithOverflow(HiBound, LoBound, RangeSize, false); 27890b57cec5SDimitry Andric } 27900b57cec5SDimitry Andric } else if (C2->isStrictlyPositive()) { // Divisor is > 0. 2791349cc55cSDimitry Andric if (C.isZero()) { // (X / pos) op 0 27920b57cec5SDimitry Andric // Can't overflow. e.g. X/2 op 0 --> [-1, 2) 27930b57cec5SDimitry Andric LoBound = -(RangeSize - 1); 27940b57cec5SDimitry Andric HiBound = RangeSize; 27950b57cec5SDimitry Andric } else if (C.isStrictlyPositive()) { // (X / pos) op pos 27960b57cec5SDimitry Andric LoBound = Prod; // e.g. X/5 op 3 --> [15, 20) 27970b57cec5SDimitry Andric HiOverflow = LoOverflow = ProdOV; 27980b57cec5SDimitry Andric if (!HiOverflow) 27990b57cec5SDimitry Andric HiOverflow = addWithOverflow(HiBound, Prod, RangeSize, true); 28000b57cec5SDimitry Andric } else { // (X / pos) op neg 28010b57cec5SDimitry Andric // e.g. X/5 op -3 --> [-15-4, -15+1) --> [-19, -14) 28020b57cec5SDimitry Andric HiBound = Prod + 1; 28030b57cec5SDimitry Andric LoOverflow = HiOverflow = ProdOV ? -1 : 0; 28040b57cec5SDimitry Andric if (!LoOverflow) { 28050b57cec5SDimitry Andric APInt DivNeg = -RangeSize; 28060b57cec5SDimitry Andric LoOverflow = addWithOverflow(LoBound, HiBound, DivNeg, true) ? -1 : 0; 28070b57cec5SDimitry Andric } 28080b57cec5SDimitry Andric } 28090b57cec5SDimitry Andric } else if (C2->isNegative()) { // Divisor is < 0. 28100b57cec5SDimitry Andric if (Div->isExact()) 28110b57cec5SDimitry Andric RangeSize.negate(); 2812349cc55cSDimitry Andric if (C.isZero()) { // (X / neg) op 0 28130b57cec5SDimitry Andric // e.g. X/-5 op 0 --> [-4, 5) 28140b57cec5SDimitry Andric LoBound = RangeSize + 1; 28150b57cec5SDimitry Andric HiBound = -RangeSize; 28160b57cec5SDimitry Andric if (HiBound == *C2) { // -INTMIN = INTMIN 28170b57cec5SDimitry Andric HiOverflow = 1; // [INTMIN+1, overflow) 28180b57cec5SDimitry Andric HiBound = APInt(); // e.g. X/INTMIN = 0 --> X > INTMIN 28190b57cec5SDimitry Andric } 28200b57cec5SDimitry Andric } else if (C.isStrictlyPositive()) { // (X / neg) op pos 28210b57cec5SDimitry Andric // e.g. X/-5 op 3 --> [-19, -14) 28220b57cec5SDimitry Andric HiBound = Prod + 1; 28230b57cec5SDimitry Andric HiOverflow = LoOverflow = ProdOV ? -1 : 0; 28240b57cec5SDimitry Andric if (!LoOverflow) 282581ad6265SDimitry Andric LoOverflow = 282681ad6265SDimitry Andric addWithOverflow(LoBound, HiBound, RangeSize, true) ? -1 : 0; 28270b57cec5SDimitry Andric } else { // (X / neg) op neg 28280b57cec5SDimitry Andric LoBound = Prod; // e.g. X/-5 op -3 --> [15, 20) 28290b57cec5SDimitry Andric LoOverflow = HiOverflow = ProdOV; 28300b57cec5SDimitry Andric if (!HiOverflow) 28310b57cec5SDimitry Andric HiOverflow = subWithOverflow(HiBound, Prod, RangeSize, true); 28320b57cec5SDimitry Andric } 28330b57cec5SDimitry Andric 28340b57cec5SDimitry Andric // Dividing by a negative swaps the condition. LT <-> GT 28350b57cec5SDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 28360b57cec5SDimitry Andric } 28370b57cec5SDimitry Andric 28380b57cec5SDimitry Andric switch (Pred) { 283981ad6265SDimitry Andric default: 284081ad6265SDimitry Andric llvm_unreachable("Unhandled icmp predicate!"); 28410b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: 28420b57cec5SDimitry Andric if (LoOverflow && HiOverflow) 28430b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getFalse()); 28440b57cec5SDimitry Andric if (HiOverflow) 284581ad6265SDimitry Andric return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, 284681ad6265SDimitry Andric X, ConstantInt::get(Ty, LoBound)); 28470b57cec5SDimitry Andric if (LoOverflow) 284881ad6265SDimitry Andric return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, 284981ad6265SDimitry Andric X, ConstantInt::get(Ty, HiBound)); 28500b57cec5SDimitry Andric return replaceInstUsesWith( 28510b57cec5SDimitry Andric Cmp, insertRangeTest(X, LoBound, HiBound, DivIsSigned, true)); 28520b57cec5SDimitry Andric case ICmpInst::ICMP_NE: 28530b57cec5SDimitry Andric if (LoOverflow && HiOverflow) 28540b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getTrue()); 28550b57cec5SDimitry Andric if (HiOverflow) 285681ad6265SDimitry Andric return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, 285781ad6265SDimitry Andric X, ConstantInt::get(Ty, LoBound)); 28580b57cec5SDimitry Andric if (LoOverflow) 285981ad6265SDimitry Andric return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, 286081ad6265SDimitry Andric X, ConstantInt::get(Ty, HiBound)); 286181ad6265SDimitry Andric return replaceInstUsesWith( 286281ad6265SDimitry Andric Cmp, insertRangeTest(X, LoBound, HiBound, DivIsSigned, false)); 28630b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: 28640b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: 28650b57cec5SDimitry Andric if (LoOverflow == +1) // Low bound is greater than input range. 28660b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getTrue()); 28670b57cec5SDimitry Andric if (LoOverflow == -1) // Low bound is less than input range. 28680b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getFalse()); 286981ad6265SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(Ty, LoBound)); 28700b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: 28710b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: 28720b57cec5SDimitry Andric if (HiOverflow == +1) // High bound greater than input range. 28730b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getFalse()); 28740b57cec5SDimitry Andric if (HiOverflow == -1) // High bound less than input range. 28750b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Builder.getTrue()); 28760b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT) 287781ad6265SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, HiBound)); 287881ad6265SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGE, X, ConstantInt::get(Ty, HiBound)); 28790b57cec5SDimitry Andric } 28800b57cec5SDimitry Andric 28810b57cec5SDimitry Andric return nullptr; 28820b57cec5SDimitry Andric } 28830b57cec5SDimitry Andric 28840b57cec5SDimitry Andric /// Fold icmp (sub X, Y), C. 2885e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp, 28860b57cec5SDimitry Andric BinaryOperator *Sub, 28870b57cec5SDimitry Andric const APInt &C) { 28880b57cec5SDimitry Andric Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1); 28890b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 2890349cc55cSDimitry Andric Type *Ty = Sub->getType(); 28910b57cec5SDimitry Andric 2892349cc55cSDimitry Andric // (SubC - Y) == C) --> Y == (SubC - C) 2893349cc55cSDimitry Andric // (SubC - Y) != C) --> Y != (SubC - C) 2894349cc55cSDimitry Andric Constant *SubC; 2895349cc55cSDimitry Andric if (Cmp.isEquality() && match(X, m_ImmConstant(SubC))) { 2896349cc55cSDimitry Andric return new ICmpInst(Pred, Y, 2897349cc55cSDimitry Andric ConstantExpr::getSub(SubC, ConstantInt::get(Ty, C))); 2898349cc55cSDimitry Andric } 28998bcb0991SDimitry Andric 29000b57cec5SDimitry Andric // (icmp P (sub nuw|nsw C2, Y), C) -> (icmp swap(P) Y, C2-C) 2901349cc55cSDimitry Andric const APInt *C2; 2902349cc55cSDimitry Andric APInt SubResult; 2903349cc55cSDimitry Andric ICmpInst::Predicate SwappedPred = Cmp.getSwappedPredicate(); 2904349cc55cSDimitry Andric bool HasNSW = Sub->hasNoSignedWrap(); 2905349cc55cSDimitry Andric bool HasNUW = Sub->hasNoUnsignedWrap(); 29060b57cec5SDimitry Andric if (match(X, m_APInt(C2)) && 2907349cc55cSDimitry Andric ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) && 29080b57cec5SDimitry Andric !subWithOverflow(SubResult, *C2, C, Cmp.isSigned())) 2909349cc55cSDimitry Andric return new ICmpInst(SwappedPred, Y, ConstantInt::get(Ty, SubResult)); 29100b57cec5SDimitry Andric 291181ad6265SDimitry Andric // X - Y == 0 --> X == Y. 291281ad6265SDimitry Andric // X - Y != 0 --> X != Y. 291381ad6265SDimitry Andric // TODO: We allow this with multiple uses as long as the other uses are not 291481ad6265SDimitry Andric // in phis. The phi use check is guarding against a codegen regression 291581ad6265SDimitry Andric // for a loop test. If the backend could undo this (and possibly 291681ad6265SDimitry Andric // subsequent transforms), we would not need this hack. 291781ad6265SDimitry Andric if (Cmp.isEquality() && C.isZero() && 291881ad6265SDimitry Andric none_of((Sub->users()), [](const User *U) { return isa<PHINode>(U); })) 291981ad6265SDimitry Andric return new ICmpInst(Pred, X, Y); 292081ad6265SDimitry Andric 29210b57cec5SDimitry Andric // The following transforms are only worth it if the only user of the subtract 29220b57cec5SDimitry Andric // is the icmp. 2923349cc55cSDimitry Andric // TODO: This is an artificial restriction for all of the transforms below 292481ad6265SDimitry Andric // that only need a single replacement icmp. Can these use the phi test 292581ad6265SDimitry Andric // like the transform above here? 29260b57cec5SDimitry Andric if (!Sub->hasOneUse()) 29270b57cec5SDimitry Andric return nullptr; 29280b57cec5SDimitry Andric 29290b57cec5SDimitry Andric if (Sub->hasNoSignedWrap()) { 29300b57cec5SDimitry Andric // (icmp sgt (sub nsw X, Y), -1) -> (icmp sge X, Y) 2931349cc55cSDimitry Andric if (Pred == ICmpInst::ICMP_SGT && C.isAllOnes()) 29320b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGE, X, Y); 29330b57cec5SDimitry Andric 29340b57cec5SDimitry Andric // (icmp sgt (sub nsw X, Y), 0) -> (icmp sgt X, Y) 2935349cc55cSDimitry Andric if (Pred == ICmpInst::ICMP_SGT && C.isZero()) 29360b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, X, Y); 29370b57cec5SDimitry Andric 29380b57cec5SDimitry Andric // (icmp slt (sub nsw X, Y), 0) -> (icmp slt X, Y) 2939349cc55cSDimitry Andric if (Pred == ICmpInst::ICMP_SLT && C.isZero()) 29400b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, X, Y); 29410b57cec5SDimitry Andric 29420b57cec5SDimitry Andric // (icmp slt (sub nsw X, Y), 1) -> (icmp sle X, Y) 2943349cc55cSDimitry Andric if (Pred == ICmpInst::ICMP_SLT && C.isOne()) 29440b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLE, X, Y); 29450b57cec5SDimitry Andric } 29460b57cec5SDimitry Andric 29470b57cec5SDimitry Andric if (!match(X, m_APInt(C2))) 29480b57cec5SDimitry Andric return nullptr; 29490b57cec5SDimitry Andric 29500b57cec5SDimitry Andric // C2 - Y <u C -> (Y | (C - 1)) == C2 29510b57cec5SDimitry Andric // iff (C2 & (C - 1)) == C - 1 and C is a power of 2 29520b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C.isPowerOf2() && 29530b57cec5SDimitry Andric (*C2 & (C - 1)) == (C - 1)) 29540b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Builder.CreateOr(Y, C - 1), X); 29550b57cec5SDimitry Andric 29560b57cec5SDimitry Andric // C2 - Y >u C -> (Y | C) != C2 29570b57cec5SDimitry Andric // iff C2 & C == C and C + 1 is a power of 2 29580b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT && (C + 1).isPowerOf2() && (*C2 & C) == C) 29590b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Builder.CreateOr(Y, C), X); 29600b57cec5SDimitry Andric 2961349cc55cSDimitry Andric // We have handled special cases that reduce. 2962349cc55cSDimitry Andric // Canonicalize any remaining sub to add as: 2963349cc55cSDimitry Andric // (C2 - Y) > C --> (Y + ~C2) < ~C 2964349cc55cSDimitry Andric Value *Add = Builder.CreateAdd(Y, ConstantInt::get(Ty, ~(*C2)), "notsub", 2965349cc55cSDimitry Andric HasNUW, HasNSW); 2966349cc55cSDimitry Andric return new ICmpInst(SwappedPred, Add, ConstantInt::get(Ty, ~C)); 29670b57cec5SDimitry Andric } 29680b57cec5SDimitry Andric 29695f757f3fSDimitry Andric static Value *createLogicFromTable(const std::bitset<4> &Table, Value *Op0, 29705f757f3fSDimitry Andric Value *Op1, IRBuilderBase &Builder, 29715f757f3fSDimitry Andric bool HasOneUse) { 29725f757f3fSDimitry Andric auto FoldConstant = [&](bool Val) { 29735f757f3fSDimitry Andric Constant *Res = Val ? Builder.getTrue() : Builder.getFalse(); 29745f757f3fSDimitry Andric if (Op0->getType()->isVectorTy()) 29755f757f3fSDimitry Andric Res = ConstantVector::getSplat( 29765f757f3fSDimitry Andric cast<VectorType>(Op0->getType())->getElementCount(), Res); 29775f757f3fSDimitry Andric return Res; 29785f757f3fSDimitry Andric }; 29795f757f3fSDimitry Andric 29805f757f3fSDimitry Andric switch (Table.to_ulong()) { 29815f757f3fSDimitry Andric case 0: // 0 0 0 0 29825f757f3fSDimitry Andric return FoldConstant(false); 29835f757f3fSDimitry Andric case 1: // 0 0 0 1 29845f757f3fSDimitry Andric return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) : nullptr; 29855f757f3fSDimitry Andric case 2: // 0 0 1 0 29865f757f3fSDimitry Andric return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) : nullptr; 29875f757f3fSDimitry Andric case 3: // 0 0 1 1 29885f757f3fSDimitry Andric return Builder.CreateNot(Op0); 29895f757f3fSDimitry Andric case 4: // 0 1 0 0 29905f757f3fSDimitry Andric return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) : nullptr; 29915f757f3fSDimitry Andric case 5: // 0 1 0 1 29925f757f3fSDimitry Andric return Builder.CreateNot(Op1); 29935f757f3fSDimitry Andric case 6: // 0 1 1 0 29945f757f3fSDimitry Andric return Builder.CreateXor(Op0, Op1); 29955f757f3fSDimitry Andric case 7: // 0 1 1 1 29965f757f3fSDimitry Andric return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) : nullptr; 29975f757f3fSDimitry Andric case 8: // 1 0 0 0 29985f757f3fSDimitry Andric return Builder.CreateAnd(Op0, Op1); 29995f757f3fSDimitry Andric case 9: // 1 0 0 1 30005f757f3fSDimitry Andric return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) : nullptr; 30015f757f3fSDimitry Andric case 10: // 1 0 1 0 30025f757f3fSDimitry Andric return Op1; 30035f757f3fSDimitry Andric case 11: // 1 0 1 1 30045f757f3fSDimitry Andric return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) : nullptr; 30055f757f3fSDimitry Andric case 12: // 1 1 0 0 30065f757f3fSDimitry Andric return Op0; 30075f757f3fSDimitry Andric case 13: // 1 1 0 1 30085f757f3fSDimitry Andric return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) : nullptr; 30095f757f3fSDimitry Andric case 14: // 1 1 1 0 30105f757f3fSDimitry Andric return Builder.CreateOr(Op0, Op1); 30115f757f3fSDimitry Andric case 15: // 1 1 1 1 30125f757f3fSDimitry Andric return FoldConstant(true); 30135f757f3fSDimitry Andric default: 30145f757f3fSDimitry Andric llvm_unreachable("Invalid Operation"); 30155f757f3fSDimitry Andric } 30165f757f3fSDimitry Andric return nullptr; 30175f757f3fSDimitry Andric } 30185f757f3fSDimitry Andric 30190b57cec5SDimitry Andric /// Fold icmp (add X, Y), C. 3020e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp, 30210b57cec5SDimitry Andric BinaryOperator *Add, 30220b57cec5SDimitry Andric const APInt &C) { 30230b57cec5SDimitry Andric Value *Y = Add->getOperand(1); 30245f757f3fSDimitry Andric Value *X = Add->getOperand(0); 30255f757f3fSDimitry Andric 30265f757f3fSDimitry Andric Value *Op0, *Op1; 30275f757f3fSDimitry Andric Instruction *Ext0, *Ext1; 30285f757f3fSDimitry Andric const CmpInst::Predicate Pred = Cmp.getPredicate(); 30295f757f3fSDimitry Andric if (match(Add, 30305f757f3fSDimitry Andric m_Add(m_CombineAnd(m_Instruction(Ext0), m_ZExtOrSExt(m_Value(Op0))), 30315f757f3fSDimitry Andric m_CombineAnd(m_Instruction(Ext1), 30325f757f3fSDimitry Andric m_ZExtOrSExt(m_Value(Op1))))) && 30335f757f3fSDimitry Andric Op0->getType()->isIntOrIntVectorTy(1) && 30345f757f3fSDimitry Andric Op1->getType()->isIntOrIntVectorTy(1)) { 30355f757f3fSDimitry Andric unsigned BW = C.getBitWidth(); 30365f757f3fSDimitry Andric std::bitset<4> Table; 30375f757f3fSDimitry Andric auto ComputeTable = [&](bool Op0Val, bool Op1Val) { 30385f757f3fSDimitry Andric int Res = 0; 30395f757f3fSDimitry Andric if (Op0Val) 30405f757f3fSDimitry Andric Res += isa<ZExtInst>(Ext0) ? 1 : -1; 30415f757f3fSDimitry Andric if (Op1Val) 30425f757f3fSDimitry Andric Res += isa<ZExtInst>(Ext1) ? 1 : -1; 30435f757f3fSDimitry Andric return ICmpInst::compare(APInt(BW, Res, true), C, Pred); 30445f757f3fSDimitry Andric }; 30455f757f3fSDimitry Andric 30465f757f3fSDimitry Andric Table[0] = ComputeTable(false, false); 30475f757f3fSDimitry Andric Table[1] = ComputeTable(false, true); 30485f757f3fSDimitry Andric Table[2] = ComputeTable(true, false); 30495f757f3fSDimitry Andric Table[3] = ComputeTable(true, true); 30505f757f3fSDimitry Andric if (auto *Cond = 30515f757f3fSDimitry Andric createLogicFromTable(Table, Op0, Op1, Builder, Add->hasOneUse())) 30525f757f3fSDimitry Andric return replaceInstUsesWith(Cmp, Cond); 30535f757f3fSDimitry Andric } 30540b57cec5SDimitry Andric const APInt *C2; 30550b57cec5SDimitry Andric if (Cmp.isEquality() || !match(Y, m_APInt(C2))) 30560b57cec5SDimitry Andric return nullptr; 30570b57cec5SDimitry Andric 30580b57cec5SDimitry Andric // Fold icmp pred (add X, C2), C. 30590b57cec5SDimitry Andric Type *Ty = Add->getType(); 30600b57cec5SDimitry Andric 30610b57cec5SDimitry Andric // If the add does not wrap, we can always adjust the compare by subtracting 30620b57cec5SDimitry Andric // the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE 30630b57cec5SDimitry Andric // are canonicalized to SGT/SLT/UGT/ULT. 30640b57cec5SDimitry Andric if ((Add->hasNoSignedWrap() && 30650b57cec5SDimitry Andric (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT)) || 30660b57cec5SDimitry Andric (Add->hasNoUnsignedWrap() && 30670b57cec5SDimitry Andric (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT))) { 30680b57cec5SDimitry Andric bool Overflow; 30690b57cec5SDimitry Andric APInt NewC = 30700b57cec5SDimitry Andric Cmp.isSigned() ? C.ssub_ov(*C2, Overflow) : C.usub_ov(*C2, Overflow); 30710b57cec5SDimitry Andric // If there is overflow, the result must be true or false. 30720b57cec5SDimitry Andric // TODO: Can we assert there is no overflow because InstSimplify always 30730b57cec5SDimitry Andric // handles those cases? 30740b57cec5SDimitry Andric if (!Overflow) 30750b57cec5SDimitry Andric // icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2) 30760b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC)); 30770b57cec5SDimitry Andric } 30780b57cec5SDimitry Andric 30790b57cec5SDimitry Andric auto CR = ConstantRange::makeExactICmpRegion(Pred, C).subtract(*C2); 30800b57cec5SDimitry Andric const APInt &Upper = CR.getUpper(); 30810b57cec5SDimitry Andric const APInt &Lower = CR.getLower(); 30820b57cec5SDimitry Andric if (Cmp.isSigned()) { 30830b57cec5SDimitry Andric if (Lower.isSignMask()) 30840b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, X, ConstantInt::get(Ty, Upper)); 30850b57cec5SDimitry Andric if (Upper.isSignMask()) 30860b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGE, X, ConstantInt::get(Ty, Lower)); 30870b57cec5SDimitry Andric } else { 30880b57cec5SDimitry Andric if (Lower.isMinValue()) 30890b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULT, X, ConstantInt::get(Ty, Upper)); 30900b57cec5SDimitry Andric if (Upper.isMinValue()) 30910b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower)); 30920b57cec5SDimitry Andric } 30930b57cec5SDimitry Andric 3094fe6060f1SDimitry Andric // This set of folds is intentionally placed after folds that use no-wrapping 3095fe6060f1SDimitry Andric // flags because those folds are likely better for later analysis/codegen. 3096fe6060f1SDimitry Andric const APInt SMax = APInt::getSignedMaxValue(Ty->getScalarSizeInBits()); 3097fe6060f1SDimitry Andric const APInt SMin = APInt::getSignedMinValue(Ty->getScalarSizeInBits()); 3098fe6060f1SDimitry Andric 3099fe6060f1SDimitry Andric // Fold compare with offset to opposite sign compare if it eliminates offset: 3100fe6060f1SDimitry Andric // (X + C2) >u C --> X <s -C2 (if C == C2 + SMAX) 3101fe6060f1SDimitry Andric if (Pred == CmpInst::ICMP_UGT && C == *C2 + SMax) 3102fe6060f1SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, X, ConstantInt::get(Ty, -(*C2))); 3103fe6060f1SDimitry Andric 3104fe6060f1SDimitry Andric // (X + C2) <u C --> X >s ~C2 (if C == C2 + SMIN) 3105fe6060f1SDimitry Andric if (Pred == CmpInst::ICMP_ULT && C == *C2 + SMin) 3106fe6060f1SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, X, ConstantInt::get(Ty, ~(*C2))); 3107fe6060f1SDimitry Andric 3108fe6060f1SDimitry Andric // (X + C2) >s C --> X <u (SMAX - C) (if C == C2 - 1) 3109fe6060f1SDimitry Andric if (Pred == CmpInst::ICMP_SGT && C == *C2 - 1) 3110fe6060f1SDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULT, X, ConstantInt::get(Ty, SMax - C)); 3111fe6060f1SDimitry Andric 3112fe6060f1SDimitry Andric // (X + C2) <s C --> X >u (C ^ SMAX) (if C == C2) 3113fe6060f1SDimitry Andric if (Pred == CmpInst::ICMP_SLT && C == *C2) 3114fe6060f1SDimitry Andric return new ICmpInst(ICmpInst::ICMP_UGT, X, ConstantInt::get(Ty, C ^ SMax)); 3115fe6060f1SDimitry Andric 3116bdd1243dSDimitry Andric // (X + -1) <u C --> X <=u C (if X is never null) 3117bdd1243dSDimitry Andric if (Pred == CmpInst::ICMP_ULT && C2->isAllOnes()) { 3118bdd1243dSDimitry Andric const SimplifyQuery Q = SQ.getWithInstruction(&Cmp); 3119*0fca6ea1SDimitry Andric if (llvm::isKnownNonZero(X, Q)) 3120bdd1243dSDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULE, X, ConstantInt::get(Ty, C)); 3121bdd1243dSDimitry Andric } 3122bdd1243dSDimitry Andric 3123480093f4SDimitry Andric if (!Add->hasOneUse()) 3124480093f4SDimitry Andric return nullptr; 3125480093f4SDimitry Andric 31260b57cec5SDimitry Andric // X+C <u C2 -> (X & -C2) == C 31270b57cec5SDimitry Andric // iff C & (C2-1) == 0 31280b57cec5SDimitry Andric // C2 is a power of 2 31290b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C.isPowerOf2() && (*C2 & (C - 1)) == 0) 31300b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Builder.CreateAnd(X, -C), 31310b57cec5SDimitry Andric ConstantExpr::getNeg(cast<Constant>(Y))); 31320b57cec5SDimitry Andric 3133*0fca6ea1SDimitry Andric // X+C2 <u C -> (X & C) == 2C 3134*0fca6ea1SDimitry Andric // iff C == -(C2) 3135*0fca6ea1SDimitry Andric // C2 is a power of 2 3136*0fca6ea1SDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C2->isPowerOf2() && C == -*C2) 3137*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Builder.CreateAnd(X, C), 3138*0fca6ea1SDimitry Andric ConstantInt::get(Ty, C * 2)); 3139*0fca6ea1SDimitry Andric 31400b57cec5SDimitry Andric // X+C >u C2 -> (X & ~C2) != C 31410b57cec5SDimitry Andric // iff C & C2 == 0 31420b57cec5SDimitry Andric // C2+1 is a power of 2 31430b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT && (C + 1).isPowerOf2() && (*C2 & C) == 0) 31440b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Builder.CreateAnd(X, ~C), 31450b57cec5SDimitry Andric ConstantExpr::getNeg(cast<Constant>(Y))); 31460b57cec5SDimitry Andric 3147349cc55cSDimitry Andric // The range test idiom can use either ult or ugt. Arbitrarily canonicalize 3148349cc55cSDimitry Andric // to the ult form. 3149349cc55cSDimitry Andric // X+C2 >u C -> X+(C2-C-1) <u ~C 3150349cc55cSDimitry Andric if (Pred == ICmpInst::ICMP_UGT) 3151349cc55cSDimitry Andric return new ICmpInst(ICmpInst::ICMP_ULT, 3152349cc55cSDimitry Andric Builder.CreateAdd(X, ConstantInt::get(Ty, *C2 - C - 1)), 3153349cc55cSDimitry Andric ConstantInt::get(Ty, ~C)); 3154349cc55cSDimitry Andric 31550b57cec5SDimitry Andric return nullptr; 31560b57cec5SDimitry Andric } 31570b57cec5SDimitry Andric 3158e8d8bef9SDimitry Andric bool InstCombinerImpl::matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, 31590b57cec5SDimitry Andric Value *&RHS, ConstantInt *&Less, 31600b57cec5SDimitry Andric ConstantInt *&Equal, 31610b57cec5SDimitry Andric ConstantInt *&Greater) { 31620b57cec5SDimitry Andric // TODO: Generalize this to work with other comparison idioms or ensure 31630b57cec5SDimitry Andric // they get canonicalized into this form. 31640b57cec5SDimitry Andric 31658bcb0991SDimitry Andric // select i1 (a == b), 31668bcb0991SDimitry Andric // i32 Equal, 31678bcb0991SDimitry Andric // i32 (select i1 (a < b), i32 Less, i32 Greater) 31688bcb0991SDimitry Andric // where Equal, Less and Greater are placeholders for any three constants. 31698bcb0991SDimitry Andric ICmpInst::Predicate PredA; 31708bcb0991SDimitry Andric if (!match(SI->getCondition(), m_ICmp(PredA, m_Value(LHS), m_Value(RHS))) || 31718bcb0991SDimitry Andric !ICmpInst::isEquality(PredA)) 31720b57cec5SDimitry Andric return false; 31738bcb0991SDimitry Andric Value *EqualVal = SI->getTrueValue(); 31748bcb0991SDimitry Andric Value *UnequalVal = SI->getFalseValue(); 31758bcb0991SDimitry Andric // We still can get non-canonical predicate here, so canonicalize. 31768bcb0991SDimitry Andric if (PredA == ICmpInst::ICMP_NE) 31778bcb0991SDimitry Andric std::swap(EqualVal, UnequalVal); 31788bcb0991SDimitry Andric if (!match(EqualVal, m_ConstantInt(Equal))) 31798bcb0991SDimitry Andric return false; 31808bcb0991SDimitry Andric ICmpInst::Predicate PredB; 31818bcb0991SDimitry Andric Value *LHS2, *RHS2; 31828bcb0991SDimitry Andric if (!match(UnequalVal, m_Select(m_ICmp(PredB, m_Value(LHS2), m_Value(RHS2)), 31838bcb0991SDimitry Andric m_ConstantInt(Less), m_ConstantInt(Greater)))) 31848bcb0991SDimitry Andric return false; 31858bcb0991SDimitry Andric // We can get predicate mismatch here, so canonicalize if possible: 31868bcb0991SDimitry Andric // First, ensure that 'LHS' match. 31878bcb0991SDimitry Andric if (LHS2 != LHS) { 31888bcb0991SDimitry Andric // x sgt y <--> y slt x 31898bcb0991SDimitry Andric std::swap(LHS2, RHS2); 31908bcb0991SDimitry Andric PredB = ICmpInst::getSwappedPredicate(PredB); 31918bcb0991SDimitry Andric } 31928bcb0991SDimitry Andric if (LHS2 != LHS) 31938bcb0991SDimitry Andric return false; 31948bcb0991SDimitry Andric // We also need to canonicalize 'RHS'. 31958bcb0991SDimitry Andric if (PredB == ICmpInst::ICMP_SGT && isa<Constant>(RHS2)) { 31968bcb0991SDimitry Andric // x sgt C-1 <--> x sge C <--> not(x slt C) 31978bcb0991SDimitry Andric auto FlippedStrictness = 3198e8d8bef9SDimitry Andric InstCombiner::getFlippedStrictnessPredicateAndConstant( 3199e8d8bef9SDimitry Andric PredB, cast<Constant>(RHS2)); 32008bcb0991SDimitry Andric if (!FlippedStrictness) 32018bcb0991SDimitry Andric return false; 32024824e7fdSDimitry Andric assert(FlippedStrictness->first == ICmpInst::ICMP_SGE && 32034824e7fdSDimitry Andric "basic correctness failure"); 32048bcb0991SDimitry Andric RHS2 = FlippedStrictness->second; 32058bcb0991SDimitry Andric // And kind-of perform the result swap. 32068bcb0991SDimitry Andric std::swap(Less, Greater); 32078bcb0991SDimitry Andric PredB = ICmpInst::ICMP_SLT; 32088bcb0991SDimitry Andric } 32098bcb0991SDimitry Andric return PredB == ICmpInst::ICMP_SLT && RHS == RHS2; 32100b57cec5SDimitry Andric } 32110b57cec5SDimitry Andric 3212e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpSelectConstant(ICmpInst &Cmp, 32130b57cec5SDimitry Andric SelectInst *Select, 32140b57cec5SDimitry Andric ConstantInt *C) { 32150b57cec5SDimitry Andric 32160b57cec5SDimitry Andric assert(C && "Cmp RHS should be a constant int!"); 32170b57cec5SDimitry Andric // If we're testing a constant value against the result of a three way 32180b57cec5SDimitry Andric // comparison, the result can be expressed directly in terms of the 32190b57cec5SDimitry Andric // original values being compared. Note: We could possibly be more 32200b57cec5SDimitry Andric // aggressive here and remove the hasOneUse test. The original select is 32210b57cec5SDimitry Andric // really likely to simplify or sink when we remove a test of the result. 32220b57cec5SDimitry Andric Value *OrigLHS, *OrigRHS; 32230b57cec5SDimitry Andric ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan; 32240b57cec5SDimitry Andric if (Cmp.hasOneUse() && 32250b57cec5SDimitry Andric matchThreeWayIntCompare(Select, OrigLHS, OrigRHS, C1LessThan, C2Equal, 32260b57cec5SDimitry Andric C3GreaterThan)) { 32270b57cec5SDimitry Andric assert(C1LessThan && C2Equal && C3GreaterThan); 32280b57cec5SDimitry Andric 3229*0fca6ea1SDimitry Andric bool TrueWhenLessThan = ICmpInst::compare( 3230*0fca6ea1SDimitry Andric C1LessThan->getValue(), C->getValue(), Cmp.getPredicate()); 3231*0fca6ea1SDimitry Andric bool TrueWhenEqual = ICmpInst::compare(C2Equal->getValue(), C->getValue(), 3232*0fca6ea1SDimitry Andric Cmp.getPredicate()); 3233*0fca6ea1SDimitry Andric bool TrueWhenGreaterThan = ICmpInst::compare( 3234*0fca6ea1SDimitry Andric C3GreaterThan->getValue(), C->getValue(), Cmp.getPredicate()); 32350b57cec5SDimitry Andric 32360b57cec5SDimitry Andric // This generates the new instruction that will replace the original Cmp 32370b57cec5SDimitry Andric // Instruction. Instead of enumerating the various combinations when 32380b57cec5SDimitry Andric // TrueWhenLessThan, TrueWhenEqual and TrueWhenGreaterThan are true versus 32390b57cec5SDimitry Andric // false, we rely on chaining of ORs and future passes of InstCombine to 32400b57cec5SDimitry Andric // simplify the OR further (i.e. a s< b || a == b becomes a s<= b). 32410b57cec5SDimitry Andric 32420b57cec5SDimitry Andric // When none of the three constants satisfy the predicate for the RHS (C), 32430b57cec5SDimitry Andric // the entire original Cmp can be simplified to a false. 32440b57cec5SDimitry Andric Value *Cond = Builder.getFalse(); 32450b57cec5SDimitry Andric if (TrueWhenLessThan) 32460b57cec5SDimitry Andric Cond = Builder.CreateOr(Cond, Builder.CreateICmp(ICmpInst::ICMP_SLT, 32470b57cec5SDimitry Andric OrigLHS, OrigRHS)); 32480b57cec5SDimitry Andric if (TrueWhenEqual) 32490b57cec5SDimitry Andric Cond = Builder.CreateOr(Cond, Builder.CreateICmp(ICmpInst::ICMP_EQ, 32500b57cec5SDimitry Andric OrigLHS, OrigRHS)); 32510b57cec5SDimitry Andric if (TrueWhenGreaterThan) 32520b57cec5SDimitry Andric Cond = Builder.CreateOr(Cond, Builder.CreateICmp(ICmpInst::ICMP_SGT, 32530b57cec5SDimitry Andric OrigLHS, OrigRHS)); 32540b57cec5SDimitry Andric 32550b57cec5SDimitry Andric return replaceInstUsesWith(Cmp, Cond); 32560b57cec5SDimitry Andric } 32570b57cec5SDimitry Andric return nullptr; 32580b57cec5SDimitry Andric } 32590b57cec5SDimitry Andric 3260349cc55cSDimitry Andric Instruction *InstCombinerImpl::foldICmpBitCast(ICmpInst &Cmp) { 32610b57cec5SDimitry Andric auto *Bitcast = dyn_cast<BitCastInst>(Cmp.getOperand(0)); 32620b57cec5SDimitry Andric if (!Bitcast) 32630b57cec5SDimitry Andric return nullptr; 32640b57cec5SDimitry Andric 32650b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 32660b57cec5SDimitry Andric Value *Op1 = Cmp.getOperand(1); 32670b57cec5SDimitry Andric Value *BCSrcOp = Bitcast->getOperand(0); 326881ad6265SDimitry Andric Type *SrcType = Bitcast->getSrcTy(); 326981ad6265SDimitry Andric Type *DstType = Bitcast->getType(); 32700b57cec5SDimitry Andric 327181ad6265SDimitry Andric // Make sure the bitcast doesn't change between scalar and vector and 327281ad6265SDimitry Andric // doesn't change the number of vector elements. 327381ad6265SDimitry Andric if (SrcType->isVectorTy() == DstType->isVectorTy() && 327481ad6265SDimitry Andric SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) { 32750b57cec5SDimitry Andric // Zero-equality and sign-bit checks are preserved through sitofp + bitcast. 32760b57cec5SDimitry Andric Value *X; 32770b57cec5SDimitry Andric if (match(BCSrcOp, m_SIToFP(m_Value(X)))) { 32780b57cec5SDimitry Andric // icmp eq (bitcast (sitofp X)), 0 --> icmp eq X, 0 32790b57cec5SDimitry Andric // icmp ne (bitcast (sitofp X)), 0 --> icmp ne X, 0 32800b57cec5SDimitry Andric // icmp slt (bitcast (sitofp X)), 0 --> icmp slt X, 0 32810b57cec5SDimitry Andric // icmp sgt (bitcast (sitofp X)), 0 --> icmp sgt X, 0 32820b57cec5SDimitry Andric if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_SLT || 32830b57cec5SDimitry Andric Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SGT) && 32840b57cec5SDimitry Andric match(Op1, m_Zero())) 32850b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); 32860b57cec5SDimitry Andric 32870b57cec5SDimitry Andric // icmp slt (bitcast (sitofp X)), 1 --> icmp slt X, 1 32880b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_One())) 32890b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), 1)); 32900b57cec5SDimitry Andric 32910b57cec5SDimitry Andric // icmp sgt (bitcast (sitofp X)), -1 --> icmp sgt X, -1 32920b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes())) 32930b57cec5SDimitry Andric return new ICmpInst(Pred, X, 32940b57cec5SDimitry Andric ConstantInt::getAllOnesValue(X->getType())); 32950b57cec5SDimitry Andric } 32960b57cec5SDimitry Andric 32970b57cec5SDimitry Andric // Zero-equality checks are preserved through unsigned floating-point casts: 32980b57cec5SDimitry Andric // icmp eq (bitcast (uitofp X)), 0 --> icmp eq X, 0 32990b57cec5SDimitry Andric // icmp ne (bitcast (uitofp X)), 0 --> icmp ne X, 0 33000b57cec5SDimitry Andric if (match(BCSrcOp, m_UIToFP(m_Value(X)))) 33010b57cec5SDimitry Andric if (Cmp.isEquality() && match(Op1, m_Zero())) 33020b57cec5SDimitry Andric return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); 33035ffd83dbSDimitry Andric 3304*0fca6ea1SDimitry Andric const APInt *C; 3305*0fca6ea1SDimitry Andric bool TrueIfSigned; 3306*0fca6ea1SDimitry Andric if (match(Op1, m_APInt(C)) && Bitcast->hasOneUse()) { 33075ffd83dbSDimitry Andric // If this is a sign-bit test of a bitcast of a casted FP value, eliminate 33085ffd83dbSDimitry Andric // the FP extend/truncate because that cast does not change the sign-bit. 33095ffd83dbSDimitry Andric // This is true for all standard IEEE-754 types and the X86 80-bit type. 33105ffd83dbSDimitry Andric // The sign-bit is always the most significant bit in those types. 3311*0fca6ea1SDimitry Andric if (isSignBitCheck(Pred, *C, TrueIfSigned) && 3312*0fca6ea1SDimitry Andric (match(BCSrcOp, m_FPExt(m_Value(X))) || 3313*0fca6ea1SDimitry Andric match(BCSrcOp, m_FPTrunc(m_Value(X))))) { 33145ffd83dbSDimitry Andric // (bitcast (fpext/fptrunc X)) to iX) < 0 --> (bitcast X to iY) < 0 33155ffd83dbSDimitry Andric // (bitcast (fpext/fptrunc X)) to iX) > -1 --> (bitcast X to iY) > -1 33165ffd83dbSDimitry Andric Type *XType = X->getType(); 33175ffd83dbSDimitry Andric 33185ffd83dbSDimitry Andric // We can't currently handle Power style floating point operations here. 331981ad6265SDimitry Andric if (!(XType->isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) { 33205ffd83dbSDimitry Andric Type *NewType = Builder.getIntNTy(XType->getScalarSizeInBits()); 33215ffd83dbSDimitry Andric if (auto *XVTy = dyn_cast<VectorType>(XType)) 3322e8d8bef9SDimitry Andric NewType = VectorType::get(NewType, XVTy->getElementCount()); 33235ffd83dbSDimitry Andric Value *NewBitcast = Builder.CreateBitCast(X, NewType); 33245ffd83dbSDimitry Andric if (TrueIfSigned) 33255ffd83dbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, NewBitcast, 33265ffd83dbSDimitry Andric ConstantInt::getNullValue(NewType)); 33275ffd83dbSDimitry Andric else 33285ffd83dbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, NewBitcast, 33295ffd83dbSDimitry Andric ConstantInt::getAllOnesValue(NewType)); 33305ffd83dbSDimitry Andric } 33315ffd83dbSDimitry Andric } 3332*0fca6ea1SDimitry Andric 3333*0fca6ea1SDimitry Andric // icmp eq/ne (bitcast X to int), special fp -> llvm.is.fpclass(X, class) 3334*0fca6ea1SDimitry Andric Type *FPType = SrcType->getScalarType(); 3335*0fca6ea1SDimitry Andric if (!Cmp.getParent()->getParent()->hasFnAttribute( 3336*0fca6ea1SDimitry Andric Attribute::NoImplicitFloat) && 3337*0fca6ea1SDimitry Andric Cmp.isEquality() && FPType->isIEEELikeFPTy()) { 3338*0fca6ea1SDimitry Andric FPClassTest Mask = APFloat(FPType->getFltSemantics(), *C).classify(); 3339*0fca6ea1SDimitry Andric if (Mask & (fcInf | fcZero)) { 3340*0fca6ea1SDimitry Andric if (Pred == ICmpInst::ICMP_NE) 3341*0fca6ea1SDimitry Andric Mask = ~Mask; 3342*0fca6ea1SDimitry Andric return replaceInstUsesWith(Cmp, 3343*0fca6ea1SDimitry Andric Builder.createIsFPClass(BCSrcOp, Mask)); 3344*0fca6ea1SDimitry Andric } 3345*0fca6ea1SDimitry Andric } 33465ffd83dbSDimitry Andric } 33470b57cec5SDimitry Andric } 33480b57cec5SDimitry Andric 3349349cc55cSDimitry Andric const APInt *C; 335081ad6265SDimitry Andric if (!match(Cmp.getOperand(1), m_APInt(C)) || !DstType->isIntegerTy() || 335181ad6265SDimitry Andric !SrcType->isIntOrIntVectorTy()) 3352349cc55cSDimitry Andric return nullptr; 3353349cc55cSDimitry Andric 3354349cc55cSDimitry Andric // If this is checking if all elements of a vector compare are set or not, 3355349cc55cSDimitry Andric // invert the casted vector equality compare and test if all compare 3356349cc55cSDimitry Andric // elements are clear or not. Compare against zero is generally easier for 3357349cc55cSDimitry Andric // analysis and codegen. 3358349cc55cSDimitry Andric // icmp eq/ne (bitcast (not X) to iN), -1 --> icmp eq/ne (bitcast X to iN), 0 3359349cc55cSDimitry Andric // Example: are all elements equal? --> are zero elements not equal? 3360349cc55cSDimitry Andric // TODO: Try harder to reduce compare of 2 freely invertible operands? 33615f757f3fSDimitry Andric if (Cmp.isEquality() && C->isAllOnes() && Bitcast->hasOneUse()) { 33625f757f3fSDimitry Andric if (Value *NotBCSrcOp = 33635f757f3fSDimitry Andric getFreelyInverted(BCSrcOp, BCSrcOp->hasOneUse(), &Builder)) { 33645f757f3fSDimitry Andric Value *Cast = Builder.CreateBitCast(NotBCSrcOp, DstType); 336581ad6265SDimitry Andric return new ICmpInst(Pred, Cast, ConstantInt::getNullValue(DstType)); 3366349cc55cSDimitry Andric } 33675f757f3fSDimitry Andric } 3368349cc55cSDimitry Andric 3369349cc55cSDimitry Andric // If this is checking if all elements of an extended vector are clear or not, 3370349cc55cSDimitry Andric // compare in a narrow type to eliminate the extend: 3371349cc55cSDimitry Andric // icmp eq/ne (bitcast (ext X) to iN), 0 --> icmp eq/ne (bitcast X to iM), 0 3372349cc55cSDimitry Andric Value *X; 3373349cc55cSDimitry Andric if (Cmp.isEquality() && C->isZero() && Bitcast->hasOneUse() && 3374349cc55cSDimitry Andric match(BCSrcOp, m_ZExtOrSExt(m_Value(X)))) { 3375349cc55cSDimitry Andric if (auto *VecTy = dyn_cast<FixedVectorType>(X->getType())) { 3376349cc55cSDimitry Andric Type *NewType = Builder.getIntNTy(VecTy->getPrimitiveSizeInBits()); 3377349cc55cSDimitry Andric Value *NewCast = Builder.CreateBitCast(X, NewType); 3378349cc55cSDimitry Andric return new ICmpInst(Pred, NewCast, ConstantInt::getNullValue(NewType)); 3379349cc55cSDimitry Andric } 3380349cc55cSDimitry Andric } 3381349cc55cSDimitry Andric 33820b57cec5SDimitry Andric // Folding: icmp <pred> iN X, C 33830b57cec5SDimitry Andric // where X = bitcast <M x iK> (shufflevector <M x iK> %vec, undef, SC)) to iN 33840b57cec5SDimitry Andric // and C is a splat of a K-bit pattern 33850b57cec5SDimitry Andric // and SC is a constant vector = <C', C', C', ..., C'> 33860b57cec5SDimitry Andric // Into: 33870b57cec5SDimitry Andric // %E = extractelement <M x iK> %vec, i32 C' 33880b57cec5SDimitry Andric // icmp <pred> iK %E, trunc(C) 33890b57cec5SDimitry Andric Value *Vec; 33905ffd83dbSDimitry Andric ArrayRef<int> Mask; 33915ffd83dbSDimitry Andric if (match(BCSrcOp, m_Shuffle(m_Value(Vec), m_Undef(), m_Mask(Mask)))) { 33920b57cec5SDimitry Andric // Check whether every element of Mask is the same constant 3393bdd1243dSDimitry Andric if (all_equal(Mask)) { 339481ad6265SDimitry Andric auto *VecTy = cast<VectorType>(SrcType); 33950b57cec5SDimitry Andric auto *EltTy = cast<IntegerType>(VecTy->getElementType()); 33960b57cec5SDimitry Andric if (C->isSplat(EltTy->getBitWidth())) { 33970b57cec5SDimitry Andric // Fold the icmp based on the value of C 33980b57cec5SDimitry Andric // If C is M copies of an iK sized bit pattern, 33990b57cec5SDimitry Andric // then: 34000b57cec5SDimitry Andric // => %E = extractelement <N x iK> %vec, i32 Elem 34010b57cec5SDimitry Andric // icmp <pred> iK %SplatVal, <pattern> 34025ffd83dbSDimitry Andric Value *Elem = Builder.getInt32(Mask[0]); 34030b57cec5SDimitry Andric Value *Extract = Builder.CreateExtractElement(Vec, Elem); 34040b57cec5SDimitry Andric Value *NewC = ConstantInt::get(EltTy, C->trunc(EltTy->getBitWidth())); 34050b57cec5SDimitry Andric return new ICmpInst(Pred, Extract, NewC); 34060b57cec5SDimitry Andric } 34070b57cec5SDimitry Andric } 34080b57cec5SDimitry Andric } 34090b57cec5SDimitry Andric return nullptr; 34100b57cec5SDimitry Andric } 34110b57cec5SDimitry Andric 34120b57cec5SDimitry Andric /// Try to fold integer comparisons with a constant operand: icmp Pred X, C 34130b57cec5SDimitry Andric /// where X is some kind of instruction. 3414e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpInstWithConstant(ICmpInst &Cmp) { 34150b57cec5SDimitry Andric const APInt *C; 34160b57cec5SDimitry Andric 341781ad6265SDimitry Andric if (match(Cmp.getOperand(1), m_APInt(C))) { 341881ad6265SDimitry Andric if (auto *BO = dyn_cast<BinaryOperator>(Cmp.getOperand(0))) 341981ad6265SDimitry Andric if (Instruction *I = foldICmpBinOpWithConstant(Cmp, BO, *C)) 34200b57cec5SDimitry Andric return I; 34210b57cec5SDimitry Andric 342281ad6265SDimitry Andric if (auto *SI = dyn_cast<SelectInst>(Cmp.getOperand(0))) 34230b57cec5SDimitry Andric // For now, we only support constant integers while folding the 34240b57cec5SDimitry Andric // ICMP(SELECT)) pattern. We can extend this to support vector of integers 34250b57cec5SDimitry Andric // similar to the cases handled by binary ops above. 342681ad6265SDimitry Andric if (auto *ConstRHS = dyn_cast<ConstantInt>(Cmp.getOperand(1))) 34270b57cec5SDimitry Andric if (Instruction *I = foldICmpSelectConstant(Cmp, SI, ConstRHS)) 34280b57cec5SDimitry Andric return I; 34290b57cec5SDimitry Andric 343081ad6265SDimitry Andric if (auto *TI = dyn_cast<TruncInst>(Cmp.getOperand(0))) 34310b57cec5SDimitry Andric if (Instruction *I = foldICmpTruncConstant(Cmp, TI, *C)) 34320b57cec5SDimitry Andric return I; 34330b57cec5SDimitry Andric 34340b57cec5SDimitry Andric if (auto *II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0))) 34350b57cec5SDimitry Andric if (Instruction *I = foldICmpIntrinsicWithConstant(Cmp, II, *C)) 34360b57cec5SDimitry Andric return I; 3437bdd1243dSDimitry Andric 3438bdd1243dSDimitry Andric // (extractval ([s/u]subo X, Y), 0) == 0 --> X == Y 3439bdd1243dSDimitry Andric // (extractval ([s/u]subo X, Y), 0) != 0 --> X != Y 3440bdd1243dSDimitry Andric // TODO: This checks one-use, but that is not strictly necessary. 3441bdd1243dSDimitry Andric Value *Cmp0 = Cmp.getOperand(0); 3442bdd1243dSDimitry Andric Value *X, *Y; 3443bdd1243dSDimitry Andric if (C->isZero() && Cmp.isEquality() && Cmp0->hasOneUse() && 3444bdd1243dSDimitry Andric (match(Cmp0, 3445bdd1243dSDimitry Andric m_ExtractValue<0>(m_Intrinsic<Intrinsic::ssub_with_overflow>( 3446bdd1243dSDimitry Andric m_Value(X), m_Value(Y)))) || 3447bdd1243dSDimitry Andric match(Cmp0, 3448bdd1243dSDimitry Andric m_ExtractValue<0>(m_Intrinsic<Intrinsic::usub_with_overflow>( 3449bdd1243dSDimitry Andric m_Value(X), m_Value(Y)))))) 3450bdd1243dSDimitry Andric return new ICmpInst(Cmp.getPredicate(), X, Y); 345181ad6265SDimitry Andric } 345281ad6265SDimitry Andric 3453*0fca6ea1SDimitry Andric if (match(Cmp.getOperand(1), m_APIntAllowPoison(C))) 3454*0fca6ea1SDimitry Andric return foldICmpInstWithConstantAllowPoison(Cmp, *C); 34550b57cec5SDimitry Andric 34560b57cec5SDimitry Andric return nullptr; 34570b57cec5SDimitry Andric } 34580b57cec5SDimitry Andric 34590b57cec5SDimitry Andric /// Fold an icmp equality instruction with binary operator LHS and constant RHS: 34600b57cec5SDimitry Andric /// icmp eq/ne BO, C. 3461e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant( 3462e8d8bef9SDimitry Andric ICmpInst &Cmp, BinaryOperator *BO, const APInt &C) { 34630b57cec5SDimitry Andric // TODO: Some of these folds could work with arbitrary constants, but this 34640b57cec5SDimitry Andric // function is limited to scalar and vector splat constants. 34650b57cec5SDimitry Andric if (!Cmp.isEquality()) 34660b57cec5SDimitry Andric return nullptr; 34670b57cec5SDimitry Andric 34680b57cec5SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 34690b57cec5SDimitry Andric bool isICMP_NE = Pred == ICmpInst::ICMP_NE; 34700b57cec5SDimitry Andric Constant *RHS = cast<Constant>(Cmp.getOperand(1)); 34710b57cec5SDimitry Andric Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1); 34720b57cec5SDimitry Andric 34730b57cec5SDimitry Andric switch (BO->getOpcode()) { 34740b57cec5SDimitry Andric case Instruction::SRem: 34750b57cec5SDimitry Andric // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. 3476349cc55cSDimitry Andric if (C.isZero() && BO->hasOneUse()) { 34770b57cec5SDimitry Andric const APInt *BOC; 34780b57cec5SDimitry Andric if (match(BOp1, m_APInt(BOC)) && BOC->sgt(1) && BOC->isPowerOf2()) { 34790b57cec5SDimitry Andric Value *NewRem = Builder.CreateURem(BOp0, BOp1, BO->getName()); 34800b57cec5SDimitry Andric return new ICmpInst(Pred, NewRem, 34810b57cec5SDimitry Andric Constant::getNullValue(BO->getType())); 34820b57cec5SDimitry Andric } 34830b57cec5SDimitry Andric } 34840b57cec5SDimitry Andric break; 34850b57cec5SDimitry Andric case Instruction::Add: { 3486bdd1243dSDimitry Andric // (A + C2) == C --> A == (C - C2) 3487bdd1243dSDimitry Andric // (A + C2) != C --> A != (C - C2) 3488bdd1243dSDimitry Andric // TODO: Remove the one-use limitation? See discussion in D58633. 3489bdd1243dSDimitry Andric if (Constant *C2 = dyn_cast<Constant>(BOp1)) { 34905ffd83dbSDimitry Andric if (BO->hasOneUse()) 3491bdd1243dSDimitry Andric return new ICmpInst(Pred, BOp0, ConstantExpr::getSub(RHS, C2)); 3492349cc55cSDimitry Andric } else if (C.isZero()) { 34930b57cec5SDimitry Andric // Replace ((add A, B) != 0) with (A != -B) if A or B is 34940b57cec5SDimitry Andric // efficiently invertible, or if the add has just this one use. 34950b57cec5SDimitry Andric if (Value *NegVal = dyn_castNegVal(BOp1)) 34960b57cec5SDimitry Andric return new ICmpInst(Pred, BOp0, NegVal); 34970b57cec5SDimitry Andric if (Value *NegVal = dyn_castNegVal(BOp0)) 34980b57cec5SDimitry Andric return new ICmpInst(Pred, NegVal, BOp1); 34990b57cec5SDimitry Andric if (BO->hasOneUse()) { 3500*0fca6ea1SDimitry Andric // (add nuw A, B) != 0 -> (or A, B) != 0 3501*0fca6ea1SDimitry Andric if (match(BO, m_NUWAdd(m_Value(), m_Value()))) { 3502*0fca6ea1SDimitry Andric Value *Or = Builder.CreateOr(BOp0, BOp1); 3503*0fca6ea1SDimitry Andric return new ICmpInst(Pred, Or, Constant::getNullValue(BO->getType())); 3504*0fca6ea1SDimitry Andric } 35050b57cec5SDimitry Andric Value *Neg = Builder.CreateNeg(BOp1); 35060b57cec5SDimitry Andric Neg->takeName(BO); 35070b57cec5SDimitry Andric return new ICmpInst(Pred, BOp0, Neg); 35080b57cec5SDimitry Andric } 35090b57cec5SDimitry Andric } 35100b57cec5SDimitry Andric break; 35110b57cec5SDimitry Andric } 35120b57cec5SDimitry Andric case Instruction::Xor: 35130b57cec5SDimitry Andric if (Constant *BOC = dyn_cast<Constant>(BOp1)) { 35140b57cec5SDimitry Andric // For the xor case, we can xor two constants together, eliminating 35150b57cec5SDimitry Andric // the explicit xor. 35160b57cec5SDimitry Andric return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC)); 3517349cc55cSDimitry Andric } else if (C.isZero()) { 35180b57cec5SDimitry Andric // Replace ((xor A, B) != 0) with (A != B) 35190b57cec5SDimitry Andric return new ICmpInst(Pred, BOp0, BOp1); 35200b57cec5SDimitry Andric } 35210b57cec5SDimitry Andric break; 35220b57cec5SDimitry Andric case Instruction::Or: { 35230b57cec5SDimitry Andric const APInt *BOC; 35240b57cec5SDimitry Andric if (match(BOp1, m_APInt(BOC)) && BO->hasOneUse() && RHS->isAllOnesValue()) { 35250b57cec5SDimitry Andric // Comparing if all bits outside of a constant mask are set? 35260b57cec5SDimitry Andric // Replace (X | C) == -1 with (X & ~C) == ~C. 35270b57cec5SDimitry Andric // This removes the -1 constant. 35280b57cec5SDimitry Andric Constant *NotBOC = ConstantExpr::getNot(cast<Constant>(BOp1)); 35290b57cec5SDimitry Andric Value *And = Builder.CreateAnd(BOp0, NotBOC); 35300b57cec5SDimitry Andric return new ICmpInst(Pred, And, NotBOC); 35310b57cec5SDimitry Andric } 35320b57cec5SDimitry Andric break; 35330b57cec5SDimitry Andric } 35340b57cec5SDimitry Andric case Instruction::UDiv: 353506c3fb27SDimitry Andric case Instruction::SDiv: 353606c3fb27SDimitry Andric if (BO->isExact()) { 353706c3fb27SDimitry Andric // div exact X, Y eq/ne 0 -> X eq/ne 0 353806c3fb27SDimitry Andric // div exact X, Y eq/ne 1 -> X eq/ne Y 353906c3fb27SDimitry Andric // div exact X, Y eq/ne C -> 354006c3fb27SDimitry Andric // if Y * C never-overflow && OneUse: 354106c3fb27SDimitry Andric // -> Y * C eq/ne X 354206c3fb27SDimitry Andric if (C.isZero()) 354306c3fb27SDimitry Andric return new ICmpInst(Pred, BOp0, Constant::getNullValue(BO->getType())); 354406c3fb27SDimitry Andric else if (C.isOne()) 354506c3fb27SDimitry Andric return new ICmpInst(Pred, BOp0, BOp1); 354606c3fb27SDimitry Andric else if (BO->hasOneUse()) { 354706c3fb27SDimitry Andric OverflowResult OR = computeOverflow( 354806c3fb27SDimitry Andric Instruction::Mul, BO->getOpcode() == Instruction::SDiv, BOp1, 354906c3fb27SDimitry Andric Cmp.getOperand(1), BO); 355006c3fb27SDimitry Andric if (OR == OverflowResult::NeverOverflows) { 355106c3fb27SDimitry Andric Value *YC = 355206c3fb27SDimitry Andric Builder.CreateMul(BOp1, ConstantInt::get(BO->getType(), C)); 355306c3fb27SDimitry Andric return new ICmpInst(Pred, YC, BOp0); 355406c3fb27SDimitry Andric } 355506c3fb27SDimitry Andric } 355606c3fb27SDimitry Andric } 355706c3fb27SDimitry Andric if (BO->getOpcode() == Instruction::UDiv && C.isZero()) { 35580b57cec5SDimitry Andric // (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A) 35590b57cec5SDimitry Andric auto NewPred = isICMP_NE ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_UGT; 35600b57cec5SDimitry Andric return new ICmpInst(NewPred, BOp1, BOp0); 35610b57cec5SDimitry Andric } 35620b57cec5SDimitry Andric break; 35630b57cec5SDimitry Andric default: 35640b57cec5SDimitry Andric break; 35650b57cec5SDimitry Andric } 35660b57cec5SDimitry Andric return nullptr; 35670b57cec5SDimitry Andric } 35680b57cec5SDimitry Andric 356906c3fb27SDimitry Andric static Instruction *foldCtpopPow2Test(ICmpInst &I, IntrinsicInst *CtpopLhs, 357006c3fb27SDimitry Andric const APInt &CRhs, 357106c3fb27SDimitry Andric InstCombiner::BuilderTy &Builder, 357206c3fb27SDimitry Andric const SimplifyQuery &Q) { 357306c3fb27SDimitry Andric assert(CtpopLhs->getIntrinsicID() == Intrinsic::ctpop && 357406c3fb27SDimitry Andric "Non-ctpop intrin in ctpop fold"); 357506c3fb27SDimitry Andric if (!CtpopLhs->hasOneUse()) 357606c3fb27SDimitry Andric return nullptr; 357706c3fb27SDimitry Andric 357806c3fb27SDimitry Andric // Power of 2 test: 357906c3fb27SDimitry Andric // isPow2OrZero : ctpop(X) u< 2 358006c3fb27SDimitry Andric // isPow2 : ctpop(X) == 1 358106c3fb27SDimitry Andric // NotPow2OrZero: ctpop(X) u> 1 358206c3fb27SDimitry Andric // NotPow2 : ctpop(X) != 1 358306c3fb27SDimitry Andric // If we know any bit of X can be folded to: 358406c3fb27SDimitry Andric // IsPow2 : X & (~Bit) == 0 358506c3fb27SDimitry Andric // NotPow2 : X & (~Bit) != 0 358606c3fb27SDimitry Andric const ICmpInst::Predicate Pred = I.getPredicate(); 358706c3fb27SDimitry Andric if (((I.isEquality() || Pred == ICmpInst::ICMP_UGT) && CRhs == 1) || 358806c3fb27SDimitry Andric (Pred == ICmpInst::ICMP_ULT && CRhs == 2)) { 358906c3fb27SDimitry Andric Value *Op = CtpopLhs->getArgOperand(0); 359006c3fb27SDimitry Andric KnownBits OpKnown = computeKnownBits(Op, Q.DL, 359106c3fb27SDimitry Andric /*Depth*/ 0, Q.AC, Q.CxtI, Q.DT); 359206c3fb27SDimitry Andric // No need to check for count > 1, that should be already constant folded. 359306c3fb27SDimitry Andric if (OpKnown.countMinPopulation() == 1) { 359406c3fb27SDimitry Andric Value *And = Builder.CreateAnd( 359506c3fb27SDimitry Andric Op, Constant::getIntegerValue(Op->getType(), ~(OpKnown.One))); 359606c3fb27SDimitry Andric return new ICmpInst( 359706c3fb27SDimitry Andric (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_ULT) 359806c3fb27SDimitry Andric ? ICmpInst::ICMP_EQ 359906c3fb27SDimitry Andric : ICmpInst::ICMP_NE, 360006c3fb27SDimitry Andric And, Constant::getNullValue(Op->getType())); 360106c3fb27SDimitry Andric } 360206c3fb27SDimitry Andric } 360306c3fb27SDimitry Andric 360406c3fb27SDimitry Andric return nullptr; 360506c3fb27SDimitry Andric } 360606c3fb27SDimitry Andric 36070b57cec5SDimitry Andric /// Fold an equality icmp with LLVM intrinsic and constant operand. 3608e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant( 3609e8d8bef9SDimitry Andric ICmpInst &Cmp, IntrinsicInst *II, const APInt &C) { 36100b57cec5SDimitry Andric Type *Ty = II->getType(); 36110b57cec5SDimitry Andric unsigned BitWidth = C.getBitWidth(); 3612349cc55cSDimitry Andric const ICmpInst::Predicate Pred = Cmp.getPredicate(); 3613349cc55cSDimitry Andric 36140b57cec5SDimitry Andric switch (II->getIntrinsicID()) { 3615e8d8bef9SDimitry Andric case Intrinsic::abs: 3616e8d8bef9SDimitry Andric // abs(A) == 0 -> A == 0 3617e8d8bef9SDimitry Andric // abs(A) == INT_MIN -> A == INT_MIN 3618349cc55cSDimitry Andric if (C.isZero() || C.isMinSignedValue()) 3619349cc55cSDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), ConstantInt::get(Ty, C)); 3620e8d8bef9SDimitry Andric break; 3621e8d8bef9SDimitry Andric 36220b57cec5SDimitry Andric case Intrinsic::bswap: 36235ffd83dbSDimitry Andric // bswap(A) == C -> A == bswap(C) 3624349cc55cSDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), 36255ffd83dbSDimitry Andric ConstantInt::get(Ty, C.byteSwap())); 36260b57cec5SDimitry Andric 362706c3fb27SDimitry Andric case Intrinsic::bitreverse: 362806c3fb27SDimitry Andric // bitreverse(A) == C -> A == bitreverse(C) 362906c3fb27SDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), 363006c3fb27SDimitry Andric ConstantInt::get(Ty, C.reverseBits())); 363106c3fb27SDimitry Andric 36320b57cec5SDimitry Andric case Intrinsic::ctlz: 36330b57cec5SDimitry Andric case Intrinsic::cttz: { 36340b57cec5SDimitry Andric // ctz(A) == bitwidth(A) -> A == 0 and likewise for != 36355ffd83dbSDimitry Andric if (C == BitWidth) 3636349cc55cSDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), 36375ffd83dbSDimitry Andric ConstantInt::getNullValue(Ty)); 36380b57cec5SDimitry Andric 36390b57cec5SDimitry Andric // ctz(A) == C -> A & Mask1 == Mask2, where Mask2 only has bit C set 36400b57cec5SDimitry Andric // and Mask1 has bits 0..C+1 set. Similar for ctl, but for high bits. 36410b57cec5SDimitry Andric // Limit to one use to ensure we don't increase instruction count. 36420b57cec5SDimitry Andric unsigned Num = C.getLimitedValue(BitWidth); 36430b57cec5SDimitry Andric if (Num != BitWidth && II->hasOneUse()) { 36440b57cec5SDimitry Andric bool IsTrailing = II->getIntrinsicID() == Intrinsic::cttz; 36450b57cec5SDimitry Andric APInt Mask1 = IsTrailing ? APInt::getLowBitsSet(BitWidth, Num + 1) 36460b57cec5SDimitry Andric : APInt::getHighBitsSet(BitWidth, Num + 1); 36470b57cec5SDimitry Andric APInt Mask2 = IsTrailing 36480b57cec5SDimitry Andric ? APInt::getOneBitSet(BitWidth, Num) 36490b57cec5SDimitry Andric : APInt::getOneBitSet(BitWidth, BitWidth - Num - 1); 3650349cc55cSDimitry Andric return new ICmpInst(Pred, Builder.CreateAnd(II->getArgOperand(0), Mask1), 36515ffd83dbSDimitry Andric ConstantInt::get(Ty, Mask2)); 36520b57cec5SDimitry Andric } 36530b57cec5SDimitry Andric break; 36540b57cec5SDimitry Andric } 36550b57cec5SDimitry Andric 36560b57cec5SDimitry Andric case Intrinsic::ctpop: { 36570b57cec5SDimitry Andric // popcount(A) == 0 -> A == 0 and likewise for != 36580b57cec5SDimitry Andric // popcount(A) == bitwidth(A) -> A == -1 and likewise for != 3659349cc55cSDimitry Andric bool IsZero = C.isZero(); 36605ffd83dbSDimitry Andric if (IsZero || C == BitWidth) 3661349cc55cSDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), 3662349cc55cSDimitry Andric IsZero ? Constant::getNullValue(Ty) 3663349cc55cSDimitry Andric : Constant::getAllOnesValue(Ty)); 36645ffd83dbSDimitry Andric 36650b57cec5SDimitry Andric break; 36660b57cec5SDimitry Andric } 36678bcb0991SDimitry Andric 3668349cc55cSDimitry Andric case Intrinsic::fshl: 3669349cc55cSDimitry Andric case Intrinsic::fshr: 3670349cc55cSDimitry Andric if (II->getArgOperand(0) == II->getArgOperand(1)) { 3671349cc55cSDimitry Andric const APInt *RotAmtC; 3672349cc55cSDimitry Andric // ror(X, RotAmtC) == C --> X == rol(C, RotAmtC) 3673349cc55cSDimitry Andric // rol(X, RotAmtC) == C --> X == ror(C, RotAmtC) 3674349cc55cSDimitry Andric if (match(II->getArgOperand(2), m_APInt(RotAmtC))) 3675349cc55cSDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), 3676349cc55cSDimitry Andric II->getIntrinsicID() == Intrinsic::fshl 3677349cc55cSDimitry Andric ? ConstantInt::get(Ty, C.rotr(*RotAmtC)) 3678349cc55cSDimitry Andric : ConstantInt::get(Ty, C.rotl(*RotAmtC))); 3679349cc55cSDimitry Andric } 3680349cc55cSDimitry Andric break; 3681349cc55cSDimitry Andric 368206c3fb27SDimitry Andric case Intrinsic::umax: 36838bcb0991SDimitry Andric case Intrinsic::uadd_sat: { 36848bcb0991SDimitry Andric // uadd.sat(a, b) == 0 -> (a | b) == 0 368506c3fb27SDimitry Andric // umax(a, b) == 0 -> (a | b) == 0 368606c3fb27SDimitry Andric if (C.isZero() && II->hasOneUse()) { 36878bcb0991SDimitry Andric Value *Or = Builder.CreateOr(II->getArgOperand(0), II->getArgOperand(1)); 3688349cc55cSDimitry Andric return new ICmpInst(Pred, Or, Constant::getNullValue(Ty)); 36898bcb0991SDimitry Andric } 36908bcb0991SDimitry Andric break; 36918bcb0991SDimitry Andric } 36928bcb0991SDimitry Andric 369306c3fb27SDimitry Andric case Intrinsic::ssub_sat: 369406c3fb27SDimitry Andric // ssub.sat(a, b) == 0 -> a == b 369506c3fb27SDimitry Andric if (C.isZero()) 369606c3fb27SDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1)); 369706c3fb27SDimitry Andric break; 36988bcb0991SDimitry Andric case Intrinsic::usub_sat: { 36998bcb0991SDimitry Andric // usub.sat(a, b) == 0 -> a <= b 3700349cc55cSDimitry Andric if (C.isZero()) { 3701349cc55cSDimitry Andric ICmpInst::Predicate NewPred = 3702349cc55cSDimitry Andric Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_UGT; 37035ffd83dbSDimitry Andric return new ICmpInst(NewPred, II->getArgOperand(0), II->getArgOperand(1)); 37048bcb0991SDimitry Andric } 37058bcb0991SDimitry Andric break; 37068bcb0991SDimitry Andric } 37070b57cec5SDimitry Andric default: 37080b57cec5SDimitry Andric break; 37090b57cec5SDimitry Andric } 37100b57cec5SDimitry Andric 37110b57cec5SDimitry Andric return nullptr; 37120b57cec5SDimitry Andric } 37130b57cec5SDimitry Andric 3714349cc55cSDimitry Andric /// Fold an icmp with LLVM intrinsics 371506c3fb27SDimitry Andric static Instruction * 371606c3fb27SDimitry Andric foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp, 371706c3fb27SDimitry Andric InstCombiner::BuilderTy &Builder) { 3718349cc55cSDimitry Andric assert(Cmp.isEquality()); 3719349cc55cSDimitry Andric 3720349cc55cSDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 3721349cc55cSDimitry Andric Value *Op0 = Cmp.getOperand(0); 3722349cc55cSDimitry Andric Value *Op1 = Cmp.getOperand(1); 3723349cc55cSDimitry Andric const auto *IIOp0 = dyn_cast<IntrinsicInst>(Op0); 3724349cc55cSDimitry Andric const auto *IIOp1 = dyn_cast<IntrinsicInst>(Op1); 3725349cc55cSDimitry Andric if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID()) 3726349cc55cSDimitry Andric return nullptr; 3727349cc55cSDimitry Andric 3728349cc55cSDimitry Andric switch (IIOp0->getIntrinsicID()) { 3729349cc55cSDimitry Andric case Intrinsic::bswap: 3730349cc55cSDimitry Andric case Intrinsic::bitreverse: 3731349cc55cSDimitry Andric // If both operands are byte-swapped or bit-reversed, just compare the 3732349cc55cSDimitry Andric // original values. 3733349cc55cSDimitry Andric return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0)); 3734349cc55cSDimitry Andric case Intrinsic::fshl: 373506c3fb27SDimitry Andric case Intrinsic::fshr: { 3736349cc55cSDimitry Andric // If both operands are rotated by same amount, just compare the 3737349cc55cSDimitry Andric // original values. 3738349cc55cSDimitry Andric if (IIOp0->getOperand(0) != IIOp0->getOperand(1)) 3739349cc55cSDimitry Andric break; 3740349cc55cSDimitry Andric if (IIOp1->getOperand(0) != IIOp1->getOperand(1)) 3741349cc55cSDimitry Andric break; 374206c3fb27SDimitry Andric if (IIOp0->getOperand(2) == IIOp1->getOperand(2)) 3743349cc55cSDimitry Andric return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0)); 374406c3fb27SDimitry Andric 374506c3fb27SDimitry Andric // rotate(X, AmtX) == rotate(Y, AmtY) 374606c3fb27SDimitry Andric // -> rotate(X, AmtX - AmtY) == Y 374706c3fb27SDimitry Andric // Do this if either both rotates have one use or if only one has one use 374806c3fb27SDimitry Andric // and AmtX/AmtY are constants. 374906c3fb27SDimitry Andric unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse(); 375006c3fb27SDimitry Andric if (OneUses == 2 || 375106c3fb27SDimitry Andric (OneUses == 1 && match(IIOp0->getOperand(2), m_ImmConstant()) && 375206c3fb27SDimitry Andric match(IIOp1->getOperand(2), m_ImmConstant()))) { 375306c3fb27SDimitry Andric Value *SubAmt = 375406c3fb27SDimitry Andric Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2)); 375506c3fb27SDimitry Andric Value *CombinedRotate = Builder.CreateIntrinsic( 375606c3fb27SDimitry Andric Op0->getType(), IIOp0->getIntrinsicID(), 375706c3fb27SDimitry Andric {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt}); 375806c3fb27SDimitry Andric return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate); 375906c3fb27SDimitry Andric } 376006c3fb27SDimitry Andric } break; 3761349cc55cSDimitry Andric default: 3762349cc55cSDimitry Andric break; 3763349cc55cSDimitry Andric } 3764349cc55cSDimitry Andric 3765349cc55cSDimitry Andric return nullptr; 3766349cc55cSDimitry Andric } 3767349cc55cSDimitry Andric 376881ad6265SDimitry Andric /// Try to fold integer comparisons with a constant operand: icmp Pred X, C 3769*0fca6ea1SDimitry Andric /// where X is some kind of instruction and C is AllowPoison. 3770*0fca6ea1SDimitry Andric /// TODO: Move more folds which allow poison to this function. 377181ad6265SDimitry Andric Instruction * 3772*0fca6ea1SDimitry Andric InstCombinerImpl::foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp, 377381ad6265SDimitry Andric const APInt &C) { 377481ad6265SDimitry Andric const ICmpInst::Predicate Pred = Cmp.getPredicate(); 377581ad6265SDimitry Andric if (auto *II = dyn_cast<IntrinsicInst>(Cmp.getOperand(0))) { 377681ad6265SDimitry Andric switch (II->getIntrinsicID()) { 377781ad6265SDimitry Andric default: 377881ad6265SDimitry Andric break; 377981ad6265SDimitry Andric case Intrinsic::fshl: 378081ad6265SDimitry Andric case Intrinsic::fshr: 378181ad6265SDimitry Andric if (Cmp.isEquality() && II->getArgOperand(0) == II->getArgOperand(1)) { 378281ad6265SDimitry Andric // (rot X, ?) == 0/-1 --> X == 0/-1 378381ad6265SDimitry Andric if (C.isZero() || C.isAllOnes()) 378481ad6265SDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), Cmp.getOperand(1)); 378581ad6265SDimitry Andric } 378681ad6265SDimitry Andric break; 378781ad6265SDimitry Andric } 378881ad6265SDimitry Andric } 378981ad6265SDimitry Andric 379081ad6265SDimitry Andric return nullptr; 379181ad6265SDimitry Andric } 379281ad6265SDimitry Andric 379381ad6265SDimitry Andric /// Fold an icmp with BinaryOp and constant operand: icmp Pred BO, C. 379481ad6265SDimitry Andric Instruction *InstCombinerImpl::foldICmpBinOpWithConstant(ICmpInst &Cmp, 379581ad6265SDimitry Andric BinaryOperator *BO, 379681ad6265SDimitry Andric const APInt &C) { 379781ad6265SDimitry Andric switch (BO->getOpcode()) { 379881ad6265SDimitry Andric case Instruction::Xor: 379981ad6265SDimitry Andric if (Instruction *I = foldICmpXorConstant(Cmp, BO, C)) 380081ad6265SDimitry Andric return I; 380181ad6265SDimitry Andric break; 380281ad6265SDimitry Andric case Instruction::And: 380381ad6265SDimitry Andric if (Instruction *I = foldICmpAndConstant(Cmp, BO, C)) 380481ad6265SDimitry Andric return I; 380581ad6265SDimitry Andric break; 380681ad6265SDimitry Andric case Instruction::Or: 380781ad6265SDimitry Andric if (Instruction *I = foldICmpOrConstant(Cmp, BO, C)) 380881ad6265SDimitry Andric return I; 380981ad6265SDimitry Andric break; 381081ad6265SDimitry Andric case Instruction::Mul: 381181ad6265SDimitry Andric if (Instruction *I = foldICmpMulConstant(Cmp, BO, C)) 381281ad6265SDimitry Andric return I; 381381ad6265SDimitry Andric break; 381481ad6265SDimitry Andric case Instruction::Shl: 381581ad6265SDimitry Andric if (Instruction *I = foldICmpShlConstant(Cmp, BO, C)) 381681ad6265SDimitry Andric return I; 381781ad6265SDimitry Andric break; 381881ad6265SDimitry Andric case Instruction::LShr: 381981ad6265SDimitry Andric case Instruction::AShr: 382081ad6265SDimitry Andric if (Instruction *I = foldICmpShrConstant(Cmp, BO, C)) 382181ad6265SDimitry Andric return I; 382281ad6265SDimitry Andric break; 382381ad6265SDimitry Andric case Instruction::SRem: 382481ad6265SDimitry Andric if (Instruction *I = foldICmpSRemConstant(Cmp, BO, C)) 382581ad6265SDimitry Andric return I; 382681ad6265SDimitry Andric break; 382781ad6265SDimitry Andric case Instruction::UDiv: 382881ad6265SDimitry Andric if (Instruction *I = foldICmpUDivConstant(Cmp, BO, C)) 382981ad6265SDimitry Andric return I; 3830bdd1243dSDimitry Andric [[fallthrough]]; 383181ad6265SDimitry Andric case Instruction::SDiv: 383281ad6265SDimitry Andric if (Instruction *I = foldICmpDivConstant(Cmp, BO, C)) 383381ad6265SDimitry Andric return I; 383481ad6265SDimitry Andric break; 383581ad6265SDimitry Andric case Instruction::Sub: 383681ad6265SDimitry Andric if (Instruction *I = foldICmpSubConstant(Cmp, BO, C)) 383781ad6265SDimitry Andric return I; 383881ad6265SDimitry Andric break; 383981ad6265SDimitry Andric case Instruction::Add: 384081ad6265SDimitry Andric if (Instruction *I = foldICmpAddConstant(Cmp, BO, C)) 384181ad6265SDimitry Andric return I; 384281ad6265SDimitry Andric break; 384381ad6265SDimitry Andric default: 384481ad6265SDimitry Andric break; 384581ad6265SDimitry Andric } 384681ad6265SDimitry Andric 384781ad6265SDimitry Andric // TODO: These folds could be refactored to be part of the above calls. 384881ad6265SDimitry Andric return foldICmpBinOpEqualityWithConstant(Cmp, BO, C); 384981ad6265SDimitry Andric } 385081ad6265SDimitry Andric 385106c3fb27SDimitry Andric static Instruction * 385206c3fb27SDimitry Andric foldICmpUSubSatOrUAddSatWithConstant(ICmpInst::Predicate Pred, 385306c3fb27SDimitry Andric SaturatingInst *II, const APInt &C, 385406c3fb27SDimitry Andric InstCombiner::BuilderTy &Builder) { 385506c3fb27SDimitry Andric // This transform may end up producing more than one instruction for the 385606c3fb27SDimitry Andric // intrinsic, so limit it to one user of the intrinsic. 385706c3fb27SDimitry Andric if (!II->hasOneUse()) 385806c3fb27SDimitry Andric return nullptr; 385906c3fb27SDimitry Andric 386006c3fb27SDimitry Andric // Let Y = [add/sub]_sat(X, C) pred C2 386106c3fb27SDimitry Andric // SatVal = The saturating value for the operation 386206c3fb27SDimitry Andric // WillWrap = Whether or not the operation will underflow / overflow 386306c3fb27SDimitry Andric // => Y = (WillWrap ? SatVal : (X binop C)) pred C2 386406c3fb27SDimitry Andric // => Y = WillWrap ? (SatVal pred C2) : ((X binop C) pred C2) 386506c3fb27SDimitry Andric // 386606c3fb27SDimitry Andric // When (SatVal pred C2) is true, then 386706c3fb27SDimitry Andric // Y = WillWrap ? true : ((X binop C) pred C2) 386806c3fb27SDimitry Andric // => Y = WillWrap || ((X binop C) pred C2) 386906c3fb27SDimitry Andric // else 387006c3fb27SDimitry Andric // Y = WillWrap ? false : ((X binop C) pred C2) 387106c3fb27SDimitry Andric // => Y = !WillWrap ? ((X binop C) pred C2) : false 387206c3fb27SDimitry Andric // => Y = !WillWrap && ((X binop C) pred C2) 387306c3fb27SDimitry Andric Value *Op0 = II->getOperand(0); 387406c3fb27SDimitry Andric Value *Op1 = II->getOperand(1); 387506c3fb27SDimitry Andric 387606c3fb27SDimitry Andric const APInt *COp1; 387706c3fb27SDimitry Andric // This transform only works when the intrinsic has an integral constant or 387806c3fb27SDimitry Andric // splat vector as the second operand. 387906c3fb27SDimitry Andric if (!match(Op1, m_APInt(COp1))) 388006c3fb27SDimitry Andric return nullptr; 388106c3fb27SDimitry Andric 388206c3fb27SDimitry Andric APInt SatVal; 388306c3fb27SDimitry Andric switch (II->getIntrinsicID()) { 388406c3fb27SDimitry Andric default: 388506c3fb27SDimitry Andric llvm_unreachable( 388606c3fb27SDimitry Andric "This function only works with usub_sat and uadd_sat for now!"); 388706c3fb27SDimitry Andric case Intrinsic::uadd_sat: 388806c3fb27SDimitry Andric SatVal = APInt::getAllOnes(C.getBitWidth()); 388906c3fb27SDimitry Andric break; 389006c3fb27SDimitry Andric case Intrinsic::usub_sat: 389106c3fb27SDimitry Andric SatVal = APInt::getZero(C.getBitWidth()); 389206c3fb27SDimitry Andric break; 389306c3fb27SDimitry Andric } 389406c3fb27SDimitry Andric 389506c3fb27SDimitry Andric // Check (SatVal pred C2) 389606c3fb27SDimitry Andric bool SatValCheck = ICmpInst::compare(SatVal, C, Pred); 389706c3fb27SDimitry Andric 389806c3fb27SDimitry Andric // !WillWrap. 389906c3fb27SDimitry Andric ConstantRange C1 = ConstantRange::makeExactNoWrapRegion( 390006c3fb27SDimitry Andric II->getBinaryOp(), *COp1, II->getNoWrapKind()); 390106c3fb27SDimitry Andric 390206c3fb27SDimitry Andric // WillWrap. 390306c3fb27SDimitry Andric if (SatValCheck) 390406c3fb27SDimitry Andric C1 = C1.inverse(); 390506c3fb27SDimitry Andric 390606c3fb27SDimitry Andric ConstantRange C2 = ConstantRange::makeExactICmpRegion(Pred, C); 390706c3fb27SDimitry Andric if (II->getBinaryOp() == Instruction::Add) 390806c3fb27SDimitry Andric C2 = C2.sub(*COp1); 390906c3fb27SDimitry Andric else 391006c3fb27SDimitry Andric C2 = C2.add(*COp1); 391106c3fb27SDimitry Andric 391206c3fb27SDimitry Andric Instruction::BinaryOps CombiningOp = 391306c3fb27SDimitry Andric SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And; 391406c3fb27SDimitry Andric 391506c3fb27SDimitry Andric std::optional<ConstantRange> Combination; 391606c3fb27SDimitry Andric if (CombiningOp == Instruction::BinaryOps::Or) 391706c3fb27SDimitry Andric Combination = C1.exactUnionWith(C2); 391806c3fb27SDimitry Andric else /* CombiningOp == Instruction::BinaryOps::And */ 391906c3fb27SDimitry Andric Combination = C1.exactIntersectWith(C2); 392006c3fb27SDimitry Andric 392106c3fb27SDimitry Andric if (!Combination) 392206c3fb27SDimitry Andric return nullptr; 392306c3fb27SDimitry Andric 392406c3fb27SDimitry Andric CmpInst::Predicate EquivPred; 392506c3fb27SDimitry Andric APInt EquivInt; 392606c3fb27SDimitry Andric APInt EquivOffset; 392706c3fb27SDimitry Andric 392806c3fb27SDimitry Andric Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset); 392906c3fb27SDimitry Andric 393006c3fb27SDimitry Andric return new ICmpInst( 393106c3fb27SDimitry Andric EquivPred, 393206c3fb27SDimitry Andric Builder.CreateAdd(Op0, ConstantInt::get(Op1->getType(), EquivOffset)), 393306c3fb27SDimitry Andric ConstantInt::get(Op1->getType(), EquivInt)); 393406c3fb27SDimitry Andric } 393506c3fb27SDimitry Andric 3936*0fca6ea1SDimitry Andric static Instruction * 3937*0fca6ea1SDimitry Andric foldICmpOfCmpIntrinsicWithConstant(ICmpInst::Predicate Pred, IntrinsicInst *I, 3938*0fca6ea1SDimitry Andric const APInt &C, 3939*0fca6ea1SDimitry Andric InstCombiner::BuilderTy &Builder) { 3940*0fca6ea1SDimitry Andric std::optional<ICmpInst::Predicate> NewPredicate = std::nullopt; 3941*0fca6ea1SDimitry Andric switch (Pred) { 3942*0fca6ea1SDimitry Andric case ICmpInst::ICMP_EQ: 3943*0fca6ea1SDimitry Andric case ICmpInst::ICMP_NE: 3944*0fca6ea1SDimitry Andric if (C.isZero()) 3945*0fca6ea1SDimitry Andric NewPredicate = Pred; 3946*0fca6ea1SDimitry Andric else if (C.isOne()) 3947*0fca6ea1SDimitry Andric NewPredicate = 3948*0fca6ea1SDimitry Andric Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_UGT : ICmpInst::ICMP_ULE; 3949*0fca6ea1SDimitry Andric else if (C.isAllOnes()) 3950*0fca6ea1SDimitry Andric NewPredicate = 3951*0fca6ea1SDimitry Andric Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_UGE; 3952*0fca6ea1SDimitry Andric break; 3953*0fca6ea1SDimitry Andric 3954*0fca6ea1SDimitry Andric case ICmpInst::ICMP_SGT: 3955*0fca6ea1SDimitry Andric if (C.isAllOnes()) 3956*0fca6ea1SDimitry Andric NewPredicate = ICmpInst::ICMP_UGE; 3957*0fca6ea1SDimitry Andric else if (C.isZero()) 3958*0fca6ea1SDimitry Andric NewPredicate = ICmpInst::ICMP_UGT; 3959*0fca6ea1SDimitry Andric break; 3960*0fca6ea1SDimitry Andric 3961*0fca6ea1SDimitry Andric case ICmpInst::ICMP_SLT: 3962*0fca6ea1SDimitry Andric if (C.isZero()) 3963*0fca6ea1SDimitry Andric NewPredicate = ICmpInst::ICMP_ULT; 3964*0fca6ea1SDimitry Andric else if (C.isOne()) 3965*0fca6ea1SDimitry Andric NewPredicate = ICmpInst::ICMP_ULE; 3966*0fca6ea1SDimitry Andric break; 3967*0fca6ea1SDimitry Andric 3968*0fca6ea1SDimitry Andric default: 3969*0fca6ea1SDimitry Andric break; 3970*0fca6ea1SDimitry Andric } 3971*0fca6ea1SDimitry Andric 3972*0fca6ea1SDimitry Andric if (!NewPredicate) 3973*0fca6ea1SDimitry Andric return nullptr; 3974*0fca6ea1SDimitry Andric 3975*0fca6ea1SDimitry Andric if (I->getIntrinsicID() == Intrinsic::scmp) 3976*0fca6ea1SDimitry Andric NewPredicate = ICmpInst::getSignedPredicate(*NewPredicate); 3977*0fca6ea1SDimitry Andric Value *LHS = I->getOperand(0); 3978*0fca6ea1SDimitry Andric Value *RHS = I->getOperand(1); 3979*0fca6ea1SDimitry Andric return new ICmpInst(*NewPredicate, LHS, RHS); 3980*0fca6ea1SDimitry Andric } 3981*0fca6ea1SDimitry Andric 39820b57cec5SDimitry Andric /// Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C. 3983e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp, 39840b57cec5SDimitry Andric IntrinsicInst *II, 39850b57cec5SDimitry Andric const APInt &C) { 398606c3fb27SDimitry Andric ICmpInst::Predicate Pred = Cmp.getPredicate(); 398706c3fb27SDimitry Andric 398806c3fb27SDimitry Andric // Handle folds that apply for any kind of icmp. 398906c3fb27SDimitry Andric switch (II->getIntrinsicID()) { 399006c3fb27SDimitry Andric default: 399106c3fb27SDimitry Andric break; 399206c3fb27SDimitry Andric case Intrinsic::uadd_sat: 399306c3fb27SDimitry Andric case Intrinsic::usub_sat: 399406c3fb27SDimitry Andric if (auto *Folded = foldICmpUSubSatOrUAddSatWithConstant( 399506c3fb27SDimitry Andric Pred, cast<SaturatingInst>(II), C, Builder)) 399606c3fb27SDimitry Andric return Folded; 399706c3fb27SDimitry Andric break; 399806c3fb27SDimitry Andric case Intrinsic::ctpop: { 399906c3fb27SDimitry Andric const SimplifyQuery Q = SQ.getWithInstruction(&Cmp); 400006c3fb27SDimitry Andric if (Instruction *R = foldCtpopPow2Test(Cmp, II, C, Builder, Q)) 400106c3fb27SDimitry Andric return R; 400206c3fb27SDimitry Andric } break; 4003*0fca6ea1SDimitry Andric case Intrinsic::scmp: 4004*0fca6ea1SDimitry Andric case Intrinsic::ucmp: 4005*0fca6ea1SDimitry Andric if (auto *Folded = foldICmpOfCmpIntrinsicWithConstant(Pred, II, C, Builder)) 4006*0fca6ea1SDimitry Andric return Folded; 4007*0fca6ea1SDimitry Andric break; 400806c3fb27SDimitry Andric } 400906c3fb27SDimitry Andric 40100b57cec5SDimitry Andric if (Cmp.isEquality()) 40110b57cec5SDimitry Andric return foldICmpEqIntrinsicWithConstant(Cmp, II, C); 40120b57cec5SDimitry Andric 40130b57cec5SDimitry Andric Type *Ty = II->getType(); 40140b57cec5SDimitry Andric unsigned BitWidth = C.getBitWidth(); 40150b57cec5SDimitry Andric switch (II->getIntrinsicID()) { 4016e8d8bef9SDimitry Andric case Intrinsic::ctpop: { 4017e8d8bef9SDimitry Andric // (ctpop X > BitWidth - 1) --> X == -1 4018e8d8bef9SDimitry Andric Value *X = II->getArgOperand(0); 4019e8d8bef9SDimitry Andric if (C == BitWidth - 1 && Pred == ICmpInst::ICMP_UGT) 4020e8d8bef9SDimitry Andric return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, X, 4021e8d8bef9SDimitry Andric ConstantInt::getAllOnesValue(Ty)); 4022e8d8bef9SDimitry Andric // (ctpop X < BitWidth) --> X != -1 4023e8d8bef9SDimitry Andric if (C == BitWidth && Pred == ICmpInst::ICMP_ULT) 4024e8d8bef9SDimitry Andric return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, X, 4025e8d8bef9SDimitry Andric ConstantInt::getAllOnesValue(Ty)); 4026e8d8bef9SDimitry Andric break; 4027e8d8bef9SDimitry Andric } 40280b57cec5SDimitry Andric case Intrinsic::ctlz: { 40290b57cec5SDimitry Andric // ctlz(0bXXXXXXXX) > 3 -> 0bXXXXXXXX < 0b00010000 4030e8d8bef9SDimitry Andric if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) { 40310b57cec5SDimitry Andric unsigned Num = C.getLimitedValue(); 40320b57cec5SDimitry Andric APInt Limit = APInt::getOneBitSet(BitWidth, BitWidth - Num - 1); 40330b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT, 40340b57cec5SDimitry Andric II->getArgOperand(0), ConstantInt::get(Ty, Limit)); 40350b57cec5SDimitry Andric } 40360b57cec5SDimitry Andric 40370b57cec5SDimitry Andric // ctlz(0bXXXXXXXX) < 3 -> 0bXXXXXXXX > 0b00011111 4038e8d8bef9SDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C.uge(1) && C.ule(BitWidth)) { 40390b57cec5SDimitry Andric unsigned Num = C.getLimitedValue(); 40400b57cec5SDimitry Andric APInt Limit = APInt::getLowBitsSet(BitWidth, BitWidth - Num); 40410b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, 40420b57cec5SDimitry Andric II->getArgOperand(0), ConstantInt::get(Ty, Limit)); 40430b57cec5SDimitry Andric } 40440b57cec5SDimitry Andric break; 40450b57cec5SDimitry Andric } 40460b57cec5SDimitry Andric case Intrinsic::cttz: { 40470b57cec5SDimitry Andric // Limit to one use to ensure we don't increase instruction count. 40480b57cec5SDimitry Andric if (!II->hasOneUse()) 40490b57cec5SDimitry Andric return nullptr; 40500b57cec5SDimitry Andric 40510b57cec5SDimitry Andric // cttz(0bXXXXXXXX) > 3 -> 0bXXXXXXXX & 0b00001111 == 0 4052e8d8bef9SDimitry Andric if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) { 40530b57cec5SDimitry Andric APInt Mask = APInt::getLowBitsSet(BitWidth, C.getLimitedValue() + 1); 40540b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, 40550b57cec5SDimitry Andric Builder.CreateAnd(II->getArgOperand(0), Mask), 40560b57cec5SDimitry Andric ConstantInt::getNullValue(Ty)); 40570b57cec5SDimitry Andric } 40580b57cec5SDimitry Andric 40590b57cec5SDimitry Andric // cttz(0bXXXXXXXX) < 3 -> 0bXXXXXXXX & 0b00000111 != 0 4060e8d8bef9SDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C.uge(1) && C.ule(BitWidth)) { 40610b57cec5SDimitry Andric APInt Mask = APInt::getLowBitsSet(BitWidth, C.getLimitedValue()); 40620b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, 40630b57cec5SDimitry Andric Builder.CreateAnd(II->getArgOperand(0), Mask), 40640b57cec5SDimitry Andric ConstantInt::getNullValue(Ty)); 40650b57cec5SDimitry Andric } 40660b57cec5SDimitry Andric break; 40670b57cec5SDimitry Andric } 406806c3fb27SDimitry Andric case Intrinsic::ssub_sat: 406906c3fb27SDimitry Andric // ssub.sat(a, b) spred 0 -> a spred b 407006c3fb27SDimitry Andric if (ICmpInst::isSigned(Pred)) { 407106c3fb27SDimitry Andric if (C.isZero()) 407206c3fb27SDimitry Andric return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1)); 407306c3fb27SDimitry Andric // X s<= 0 is cannonicalized to X s< 1 407406c3fb27SDimitry Andric if (Pred == ICmpInst::ICMP_SLT && C.isOne()) 407506c3fb27SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLE, II->getArgOperand(0), 407606c3fb27SDimitry Andric II->getArgOperand(1)); 407706c3fb27SDimitry Andric // X s>= 0 is cannonicalized to X s> -1 407806c3fb27SDimitry Andric if (Pred == ICmpInst::ICMP_SGT && C.isAllOnes()) 407906c3fb27SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGE, II->getArgOperand(0), 408006c3fb27SDimitry Andric II->getArgOperand(1)); 408106c3fb27SDimitry Andric } 408206c3fb27SDimitry Andric break; 40830b57cec5SDimitry Andric default: 40840b57cec5SDimitry Andric break; 40850b57cec5SDimitry Andric } 40860b57cec5SDimitry Andric 40870b57cec5SDimitry Andric return nullptr; 40880b57cec5SDimitry Andric } 40890b57cec5SDimitry Andric 40900b57cec5SDimitry Andric /// Handle icmp with constant (but not simple integer constant) RHS. 4091e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) { 40920b57cec5SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 40930b57cec5SDimitry Andric Constant *RHSC = dyn_cast<Constant>(Op1); 40940b57cec5SDimitry Andric Instruction *LHSI = dyn_cast<Instruction>(Op0); 40950b57cec5SDimitry Andric if (!RHSC || !LHSI) 40960b57cec5SDimitry Andric return nullptr; 40970b57cec5SDimitry Andric 40980b57cec5SDimitry Andric switch (LHSI->getOpcode()) { 40990b57cec5SDimitry Andric case Instruction::PHI: 41000b57cec5SDimitry Andric if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI))) 41010b57cec5SDimitry Andric return NV; 41020b57cec5SDimitry Andric break; 410381ad6265SDimitry Andric case Instruction::IntToPtr: 410481ad6265SDimitry Andric // icmp pred inttoptr(X), null -> icmp pred X, 0 410581ad6265SDimitry Andric if (RHSC->isNullValue() && 410681ad6265SDimitry Andric DL.getIntPtrType(RHSC->getType()) == LHSI->getOperand(0)->getType()) 410781ad6265SDimitry Andric return new ICmpInst( 410881ad6265SDimitry Andric I.getPredicate(), LHSI->getOperand(0), 410981ad6265SDimitry Andric Constant::getNullValue(LHSI->getOperand(0)->getType())); 411081ad6265SDimitry Andric break; 4111fe6060f1SDimitry Andric 411281ad6265SDimitry Andric case Instruction::Load: 411381ad6265SDimitry Andric // Try to optimize things like "A[i] > 4" to index computations. 411481ad6265SDimitry Andric if (GetElementPtrInst *GEP = 411581ad6265SDimitry Andric dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) 411681ad6265SDimitry Andric if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0))) 411781ad6265SDimitry Andric if (Instruction *Res = 411881ad6265SDimitry Andric foldCmpLoadFromIndexedGlobal(cast<LoadInst>(LHSI), GEP, GV, I)) 411981ad6265SDimitry Andric return Res; 412081ad6265SDimitry Andric break; 4121fe6060f1SDimitry Andric } 412281ad6265SDimitry Andric 412381ad6265SDimitry Andric return nullptr; 412481ad6265SDimitry Andric } 412581ad6265SDimitry Andric 412681ad6265SDimitry Andric Instruction *InstCombinerImpl::foldSelectICmp(ICmpInst::Predicate Pred, 412781ad6265SDimitry Andric SelectInst *SI, Value *RHS, 412881ad6265SDimitry Andric const ICmpInst &I) { 412981ad6265SDimitry Andric // Try to fold the comparison into the select arms, which will cause the 413081ad6265SDimitry Andric // select to be converted into a logical and/or. 413181ad6265SDimitry Andric auto SimplifyOp = [&](Value *Op, bool SelectCondIsTrue) -> Value * { 413281ad6265SDimitry Andric if (Value *Res = simplifyICmpInst(Pred, Op, RHS, SQ)) 413381ad6265SDimitry Andric return Res; 4134bdd1243dSDimitry Andric if (std::optional<bool> Impl = isImpliedCondition( 4135bdd1243dSDimitry Andric SI->getCondition(), Pred, Op, RHS, DL, SelectCondIsTrue)) 413681ad6265SDimitry Andric return ConstantInt::get(I.getType(), *Impl); 413781ad6265SDimitry Andric return nullptr; 4138fe6060f1SDimitry Andric }; 413981ad6265SDimitry Andric 414081ad6265SDimitry Andric ConstantInt *CI = nullptr; 414181ad6265SDimitry Andric Value *Op1 = SimplifyOp(SI->getOperand(1), true); 4142fe6060f1SDimitry Andric if (Op1) 41430b57cec5SDimitry Andric CI = dyn_cast<ConstantInt>(Op1); 4144fe6060f1SDimitry Andric 414581ad6265SDimitry Andric Value *Op2 = SimplifyOp(SI->getOperand(2), false); 4146fe6060f1SDimitry Andric if (Op2) 41470b57cec5SDimitry Andric CI = dyn_cast<ConstantInt>(Op2); 41480b57cec5SDimitry Andric 41490b57cec5SDimitry Andric // We only want to perform this transformation if it will not lead to 41500b57cec5SDimitry Andric // additional code. This is true if either both sides of the select 41510b57cec5SDimitry Andric // fold to a constant (in which case the icmp is replaced with a select 41520b57cec5SDimitry Andric // which will usually simplify) or this is the only user of the 41530b57cec5SDimitry Andric // select (in which case we are trading a select+icmp for a simpler 41540b57cec5SDimitry Andric // select+icmp) or all uses of the select can be replaced based on 41550b57cec5SDimitry Andric // dominance information ("Global cases"). 41560b57cec5SDimitry Andric bool Transform = false; 41570b57cec5SDimitry Andric if (Op1 && Op2) 41580b57cec5SDimitry Andric Transform = true; 41590b57cec5SDimitry Andric else if (Op1 || Op2) { 41600b57cec5SDimitry Andric // Local case 416181ad6265SDimitry Andric if (SI->hasOneUse()) 41620b57cec5SDimitry Andric Transform = true; 41630b57cec5SDimitry Andric // Global cases 41640b57cec5SDimitry Andric else if (CI && !CI->isZero()) 41650b57cec5SDimitry Andric // When Op1 is constant try replacing select with second operand. 41660b57cec5SDimitry Andric // Otherwise Op2 is constant and try replacing select with first 41670b57cec5SDimitry Andric // operand. 416881ad6265SDimitry Andric Transform = replacedSelectWithOperand(SI, &I, Op1 ? 2 : 1); 41690b57cec5SDimitry Andric } 41700b57cec5SDimitry Andric if (Transform) { 41710b57cec5SDimitry Andric if (!Op1) 417281ad6265SDimitry Andric Op1 = Builder.CreateICmp(Pred, SI->getOperand(1), RHS, I.getName()); 41730b57cec5SDimitry Andric if (!Op2) 417481ad6265SDimitry Andric Op2 = Builder.CreateICmp(Pred, SI->getOperand(2), RHS, I.getName()); 417581ad6265SDimitry Andric return SelectInst::Create(SI->getOperand(0), Op1, Op2); 41760b57cec5SDimitry Andric } 41770b57cec5SDimitry Andric 41780b57cec5SDimitry Andric return nullptr; 41790b57cec5SDimitry Andric } 41800b57cec5SDimitry Andric 4181*0fca6ea1SDimitry Andric // Returns whether V is a Mask ((X + 1) & X == 0) or ~Mask (-Pow2OrZero) 4182*0fca6ea1SDimitry Andric static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, 4183*0fca6ea1SDimitry Andric unsigned Depth = 0) { 4184*0fca6ea1SDimitry Andric if (Not ? match(V, m_NegatedPower2OrZero()) : match(V, m_LowBitMaskOrZero())) 4185*0fca6ea1SDimitry Andric return true; 4186*0fca6ea1SDimitry Andric if (V->getType()->getScalarSizeInBits() == 1) 4187*0fca6ea1SDimitry Andric return true; 4188*0fca6ea1SDimitry Andric if (Depth++ >= MaxAnalysisRecursionDepth) 4189*0fca6ea1SDimitry Andric return false; 4190*0fca6ea1SDimitry Andric Value *X; 4191*0fca6ea1SDimitry Andric const Instruction *I = dyn_cast<Instruction>(V); 4192*0fca6ea1SDimitry Andric if (!I) 4193*0fca6ea1SDimitry Andric return false; 4194*0fca6ea1SDimitry Andric switch (I->getOpcode()) { 4195*0fca6ea1SDimitry Andric case Instruction::ZExt: 4196*0fca6ea1SDimitry Andric // ZExt(Mask) is a Mask. 4197*0fca6ea1SDimitry Andric return !Not && isMaskOrZero(I->getOperand(0), Not, Q, Depth); 4198*0fca6ea1SDimitry Andric case Instruction::SExt: 4199*0fca6ea1SDimitry Andric // SExt(Mask) is a Mask. 4200*0fca6ea1SDimitry Andric // SExt(~Mask) is a ~Mask. 4201*0fca6ea1SDimitry Andric return isMaskOrZero(I->getOperand(0), Not, Q, Depth); 4202*0fca6ea1SDimitry Andric case Instruction::And: 4203*0fca6ea1SDimitry Andric case Instruction::Or: 4204*0fca6ea1SDimitry Andric // Mask0 | Mask1 is a Mask. 4205*0fca6ea1SDimitry Andric // Mask0 & Mask1 is a Mask. 4206*0fca6ea1SDimitry Andric // ~Mask0 | ~Mask1 is a ~Mask. 4207*0fca6ea1SDimitry Andric // ~Mask0 & ~Mask1 is a ~Mask. 4208*0fca6ea1SDimitry Andric return isMaskOrZero(I->getOperand(1), Not, Q, Depth) && 4209*0fca6ea1SDimitry Andric isMaskOrZero(I->getOperand(0), Not, Q, Depth); 4210*0fca6ea1SDimitry Andric case Instruction::Xor: 4211*0fca6ea1SDimitry Andric if (match(V, m_Not(m_Value(X)))) 4212*0fca6ea1SDimitry Andric return isMaskOrZero(X, !Not, Q, Depth); 4213*0fca6ea1SDimitry Andric 4214*0fca6ea1SDimitry Andric // (X ^ -X) is a ~Mask 4215*0fca6ea1SDimitry Andric if (Not) 4216*0fca6ea1SDimitry Andric return match(V, m_c_Xor(m_Value(X), m_Neg(m_Deferred(X)))); 4217*0fca6ea1SDimitry Andric // (X ^ (X - 1)) is a Mask 4218*0fca6ea1SDimitry Andric else 4219*0fca6ea1SDimitry Andric return match(V, m_c_Xor(m_Value(X), m_Add(m_Deferred(X), m_AllOnes()))); 4220*0fca6ea1SDimitry Andric case Instruction::Select: 4221*0fca6ea1SDimitry Andric // c ? Mask0 : Mask1 is a Mask. 4222*0fca6ea1SDimitry Andric return isMaskOrZero(I->getOperand(1), Not, Q, Depth) && 4223*0fca6ea1SDimitry Andric isMaskOrZero(I->getOperand(2), Not, Q, Depth); 4224*0fca6ea1SDimitry Andric case Instruction::Shl: 4225*0fca6ea1SDimitry Andric // (~Mask) << X is a ~Mask. 4226*0fca6ea1SDimitry Andric return Not && isMaskOrZero(I->getOperand(0), Not, Q, Depth); 4227*0fca6ea1SDimitry Andric case Instruction::LShr: 4228*0fca6ea1SDimitry Andric // Mask >> X is a Mask. 4229*0fca6ea1SDimitry Andric return !Not && isMaskOrZero(I->getOperand(0), Not, Q, Depth); 4230*0fca6ea1SDimitry Andric case Instruction::AShr: 4231*0fca6ea1SDimitry Andric // Mask s>> X is a Mask. 4232*0fca6ea1SDimitry Andric // ~Mask s>> X is a ~Mask. 4233*0fca6ea1SDimitry Andric return isMaskOrZero(I->getOperand(0), Not, Q, Depth); 4234*0fca6ea1SDimitry Andric case Instruction::Add: 4235*0fca6ea1SDimitry Andric // Pow2 - 1 is a Mask. 4236*0fca6ea1SDimitry Andric if (!Not && match(I->getOperand(1), m_AllOnes())) 4237*0fca6ea1SDimitry Andric return isKnownToBeAPowerOfTwo(I->getOperand(0), Q.DL, /*OrZero*/ true, 4238*0fca6ea1SDimitry Andric Depth, Q.AC, Q.CxtI, Q.DT); 4239*0fca6ea1SDimitry Andric break; 4240*0fca6ea1SDimitry Andric case Instruction::Sub: 4241*0fca6ea1SDimitry Andric // -Pow2 is a ~Mask. 4242*0fca6ea1SDimitry Andric if (Not && match(I->getOperand(0), m_Zero())) 4243*0fca6ea1SDimitry Andric return isKnownToBeAPowerOfTwo(I->getOperand(1), Q.DL, /*OrZero*/ true, 4244*0fca6ea1SDimitry Andric Depth, Q.AC, Q.CxtI, Q.DT); 4245*0fca6ea1SDimitry Andric break; 4246*0fca6ea1SDimitry Andric case Instruction::Call: { 4247*0fca6ea1SDimitry Andric if (auto *II = dyn_cast<IntrinsicInst>(I)) { 4248*0fca6ea1SDimitry Andric switch (II->getIntrinsicID()) { 4249*0fca6ea1SDimitry Andric // min/max(Mask0, Mask1) is a Mask. 4250*0fca6ea1SDimitry Andric // min/max(~Mask0, ~Mask1) is a ~Mask. 4251*0fca6ea1SDimitry Andric case Intrinsic::umax: 4252*0fca6ea1SDimitry Andric case Intrinsic::smax: 4253*0fca6ea1SDimitry Andric case Intrinsic::umin: 4254*0fca6ea1SDimitry Andric case Intrinsic::smin: 4255*0fca6ea1SDimitry Andric return isMaskOrZero(II->getArgOperand(1), Not, Q, Depth) && 4256*0fca6ea1SDimitry Andric isMaskOrZero(II->getArgOperand(0), Not, Q, Depth); 4257*0fca6ea1SDimitry Andric 4258*0fca6ea1SDimitry Andric // In the context of masks, bitreverse(Mask) == ~Mask 4259*0fca6ea1SDimitry Andric case Intrinsic::bitreverse: 4260*0fca6ea1SDimitry Andric return isMaskOrZero(II->getArgOperand(0), !Not, Q, Depth); 4261*0fca6ea1SDimitry Andric default: 4262*0fca6ea1SDimitry Andric break; 4263*0fca6ea1SDimitry Andric } 4264*0fca6ea1SDimitry Andric } 4265*0fca6ea1SDimitry Andric break; 4266*0fca6ea1SDimitry Andric } 4267*0fca6ea1SDimitry Andric default: 4268*0fca6ea1SDimitry Andric break; 4269*0fca6ea1SDimitry Andric } 4270*0fca6ea1SDimitry Andric return false; 4271*0fca6ea1SDimitry Andric } 4272*0fca6ea1SDimitry Andric 42730b57cec5SDimitry Andric /// Some comparisons can be simplified. 42740b57cec5SDimitry Andric /// In this case, we are looking for comparisons that look like 42750b57cec5SDimitry Andric /// a check for a lossy truncation. 42760b57cec5SDimitry Andric /// Folds: 42770b57cec5SDimitry Andric /// icmp SrcPred (x & Mask), x to icmp DstPred x, Mask 4278*0fca6ea1SDimitry Andric /// icmp SrcPred (x & ~Mask), ~Mask to icmp DstPred x, ~Mask 4279*0fca6ea1SDimitry Andric /// icmp eq/ne (x & ~Mask), 0 to icmp DstPred x, Mask 4280*0fca6ea1SDimitry Andric /// icmp eq/ne (~x | Mask), -1 to icmp DstPred x, Mask 42810b57cec5SDimitry Andric /// Where Mask is some pattern that produces all-ones in low bits: 42820b57cec5SDimitry Andric /// (-1 >> y) 42830b57cec5SDimitry Andric /// ((-1 << y) >> y) <- non-canonical, has extra uses 42840b57cec5SDimitry Andric /// ~(-1 << y) 42850b57cec5SDimitry Andric /// ((1 << y) + (-1)) <- non-canonical, has extra uses 42860b57cec5SDimitry Andric /// The Mask can be a constant, too. 42870b57cec5SDimitry Andric /// For some predicates, the operands are commutative. 42880b57cec5SDimitry Andric /// For others, x can only be on a specific side. 4289*0fca6ea1SDimitry Andric static Value *foldICmpWithLowBitMaskedVal(ICmpInst::Predicate Pred, Value *Op0, 4290*0fca6ea1SDimitry Andric Value *Op1, const SimplifyQuery &Q, 4291*0fca6ea1SDimitry Andric InstCombiner &IC) { 42920b57cec5SDimitry Andric 42930b57cec5SDimitry Andric ICmpInst::Predicate DstPred; 4294*0fca6ea1SDimitry Andric switch (Pred) { 42950b57cec5SDimitry Andric case ICmpInst::Predicate::ICMP_EQ: 4296*0fca6ea1SDimitry Andric // x & Mask == x 4297*0fca6ea1SDimitry Andric // x & ~Mask == 0 4298*0fca6ea1SDimitry Andric // ~x | Mask == -1 4299*0fca6ea1SDimitry Andric // -> x u<= Mask 4300*0fca6ea1SDimitry Andric // x & ~Mask == ~Mask 4301*0fca6ea1SDimitry Andric // -> ~Mask u<= x 43020b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_ULE; 43030b57cec5SDimitry Andric break; 43040b57cec5SDimitry Andric case ICmpInst::Predicate::ICMP_NE: 4305*0fca6ea1SDimitry Andric // x & Mask != x 4306*0fca6ea1SDimitry Andric // x & ~Mask != 0 4307*0fca6ea1SDimitry Andric // ~x | Mask != -1 4308*0fca6ea1SDimitry Andric // -> x u> Mask 4309*0fca6ea1SDimitry Andric // x & ~Mask != ~Mask 4310*0fca6ea1SDimitry Andric // -> ~Mask u> x 43110b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_UGT; 43120b57cec5SDimitry Andric break; 43135ffd83dbSDimitry Andric case ICmpInst::Predicate::ICMP_ULT: 4314*0fca6ea1SDimitry Andric // x & Mask u< x 4315*0fca6ea1SDimitry Andric // -> x u> Mask 4316*0fca6ea1SDimitry Andric // x & ~Mask u< ~Mask 4317*0fca6ea1SDimitry Andric // -> ~Mask u> x 43180b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_UGT; 43190b57cec5SDimitry Andric break; 43200b57cec5SDimitry Andric case ICmpInst::Predicate::ICMP_UGE: 4321*0fca6ea1SDimitry Andric // x & Mask u>= x 4322*0fca6ea1SDimitry Andric // -> x u<= Mask 4323*0fca6ea1SDimitry Andric // x & ~Mask u>= ~Mask 4324*0fca6ea1SDimitry Andric // -> ~Mask u<= x 43250b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_ULE; 43260b57cec5SDimitry Andric break; 43275ffd83dbSDimitry Andric case ICmpInst::Predicate::ICMP_SLT: 4328*0fca6ea1SDimitry Andric // x & Mask s< x [iff Mask s>= 0] 4329*0fca6ea1SDimitry Andric // -> x s> Mask 4330*0fca6ea1SDimitry Andric // x & ~Mask s< ~Mask [iff ~Mask != 0] 4331*0fca6ea1SDimitry Andric // -> ~Mask s> x 43320b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_SGT; 43330b57cec5SDimitry Andric break; 43340b57cec5SDimitry Andric case ICmpInst::Predicate::ICMP_SGE: 4335*0fca6ea1SDimitry Andric // x & Mask s>= x [iff Mask s>= 0] 4336*0fca6ea1SDimitry Andric // -> x s<= Mask 4337*0fca6ea1SDimitry Andric // x & ~Mask s>= ~Mask [iff ~Mask != 0] 4338*0fca6ea1SDimitry Andric // -> ~Mask s<= x 43390b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_SLE; 43400b57cec5SDimitry Andric break; 43410b57cec5SDimitry Andric default: 4342*0fca6ea1SDimitry Andric // We don't support sgt,sle 4343*0fca6ea1SDimitry Andric // ult/ugt are simplified to true/false respectively. 4344*0fca6ea1SDimitry Andric return nullptr; 43450b57cec5SDimitry Andric } 43460b57cec5SDimitry Andric 4347*0fca6ea1SDimitry Andric Value *X, *M; 4348*0fca6ea1SDimitry Andric // Put search code in lambda for early positive returns. 4349*0fca6ea1SDimitry Andric auto IsLowBitMask = [&]() { 4350*0fca6ea1SDimitry Andric if (match(Op0, m_c_And(m_Specific(Op1), m_Value(M)))) { 4351*0fca6ea1SDimitry Andric X = Op1; 4352*0fca6ea1SDimitry Andric // Look for: x & Mask pred x 4353*0fca6ea1SDimitry Andric if (isMaskOrZero(M, /*Not=*/false, Q)) { 4354*0fca6ea1SDimitry Andric return !ICmpInst::isSigned(Pred) || 4355*0fca6ea1SDimitry Andric (match(M, m_NonNegative()) || isKnownNonNegative(M, Q)); 4356480093f4SDimitry Andric } 4357480093f4SDimitry Andric 4358*0fca6ea1SDimitry Andric // Look for: x & ~Mask pred ~Mask 4359*0fca6ea1SDimitry Andric if (isMaskOrZero(X, /*Not=*/true, Q)) { 4360*0fca6ea1SDimitry Andric return !ICmpInst::isSigned(Pred) || isKnownNonZero(X, Q); 4361*0fca6ea1SDimitry Andric } 4362*0fca6ea1SDimitry Andric return false; 4363*0fca6ea1SDimitry Andric } 4364*0fca6ea1SDimitry Andric if (ICmpInst::isEquality(Pred) && match(Op1, m_AllOnes()) && 4365*0fca6ea1SDimitry Andric match(Op0, m_OneUse(m_Or(m_Value(X), m_Value(M))))) { 4366*0fca6ea1SDimitry Andric 4367*0fca6ea1SDimitry Andric auto Check = [&]() { 4368*0fca6ea1SDimitry Andric // Look for: ~x | Mask == -1 4369*0fca6ea1SDimitry Andric if (isMaskOrZero(M, /*Not=*/false, Q)) { 4370*0fca6ea1SDimitry Andric if (Value *NotX = 4371*0fca6ea1SDimitry Andric IC.getFreelyInverted(X, X->hasOneUse(), &IC.Builder)) { 4372*0fca6ea1SDimitry Andric X = NotX; 4373*0fca6ea1SDimitry Andric return true; 4374*0fca6ea1SDimitry Andric } 4375*0fca6ea1SDimitry Andric } 4376*0fca6ea1SDimitry Andric return false; 4377*0fca6ea1SDimitry Andric }; 4378*0fca6ea1SDimitry Andric if (Check()) 4379*0fca6ea1SDimitry Andric return true; 4380*0fca6ea1SDimitry Andric std::swap(X, M); 4381*0fca6ea1SDimitry Andric return Check(); 4382*0fca6ea1SDimitry Andric } 4383*0fca6ea1SDimitry Andric if (ICmpInst::isEquality(Pred) && match(Op1, m_Zero()) && 4384*0fca6ea1SDimitry Andric match(Op0, m_OneUse(m_And(m_Value(X), m_Value(M))))) { 4385*0fca6ea1SDimitry Andric auto Check = [&]() { 4386*0fca6ea1SDimitry Andric // Look for: x & ~Mask == 0 4387*0fca6ea1SDimitry Andric if (isMaskOrZero(M, /*Not=*/true, Q)) { 4388*0fca6ea1SDimitry Andric if (Value *NotM = 4389*0fca6ea1SDimitry Andric IC.getFreelyInverted(M, M->hasOneUse(), &IC.Builder)) { 4390*0fca6ea1SDimitry Andric M = NotM; 4391*0fca6ea1SDimitry Andric return true; 4392*0fca6ea1SDimitry Andric } 4393*0fca6ea1SDimitry Andric } 4394*0fca6ea1SDimitry Andric return false; 4395*0fca6ea1SDimitry Andric }; 4396*0fca6ea1SDimitry Andric if (Check()) 4397*0fca6ea1SDimitry Andric return true; 4398*0fca6ea1SDimitry Andric std::swap(X, M); 4399*0fca6ea1SDimitry Andric return Check(); 4400*0fca6ea1SDimitry Andric } 4401*0fca6ea1SDimitry Andric return false; 4402*0fca6ea1SDimitry Andric }; 4403*0fca6ea1SDimitry Andric 4404*0fca6ea1SDimitry Andric if (!IsLowBitMask()) 4405*0fca6ea1SDimitry Andric return nullptr; 4406*0fca6ea1SDimitry Andric 4407*0fca6ea1SDimitry Andric return IC.Builder.CreateICmp(DstPred, X, M); 44080b57cec5SDimitry Andric } 44090b57cec5SDimitry Andric 44100b57cec5SDimitry Andric /// Some comparisons can be simplified. 44110b57cec5SDimitry Andric /// In this case, we are looking for comparisons that look like 44120b57cec5SDimitry Andric /// a check for a lossy signed truncation. 44130b57cec5SDimitry Andric /// Folds: (MaskedBits is a constant.) 44140b57cec5SDimitry Andric /// ((%x << MaskedBits) a>> MaskedBits) SrcPred %x 44150b57cec5SDimitry Andric /// Into: 44160b57cec5SDimitry Andric /// (add %x, (1 << (KeptBits-1))) DstPred (1 << KeptBits) 44170b57cec5SDimitry Andric /// Where KeptBits = bitwidth(%x) - MaskedBits 44180b57cec5SDimitry Andric static Value * 44190b57cec5SDimitry Andric foldICmpWithTruncSignExtendedVal(ICmpInst &I, 44200b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder) { 44210b57cec5SDimitry Andric ICmpInst::Predicate SrcPred; 44220b57cec5SDimitry Andric Value *X; 44230b57cec5SDimitry Andric const APInt *C0, *C1; // FIXME: non-splats, potentially with undef. 44240b57cec5SDimitry Andric // We are ok with 'shl' having multiple uses, but 'ashr' must be one-use. 44250b57cec5SDimitry Andric if (!match(&I, m_c_ICmp(SrcPred, 44260b57cec5SDimitry Andric m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C0)), 44270b57cec5SDimitry Andric m_APInt(C1))), 44280b57cec5SDimitry Andric m_Deferred(X)))) 44290b57cec5SDimitry Andric return nullptr; 44300b57cec5SDimitry Andric 44310b57cec5SDimitry Andric // Potential handling of non-splats: for each element: 44320b57cec5SDimitry Andric // * if both are undef, replace with constant 0. 44330b57cec5SDimitry Andric // Because (1<<0) is OK and is 1, and ((1<<0)>>1) is also OK and is 0. 44340b57cec5SDimitry Andric // * if both are not undef, and are different, bailout. 44350b57cec5SDimitry Andric // * else, only one is undef, then pick the non-undef one. 44360b57cec5SDimitry Andric 44370b57cec5SDimitry Andric // The shift amount must be equal. 44380b57cec5SDimitry Andric if (*C0 != *C1) 44390b57cec5SDimitry Andric return nullptr; 44400b57cec5SDimitry Andric const APInt &MaskedBits = *C0; 44410b57cec5SDimitry Andric assert(MaskedBits != 0 && "shift by zero should be folded away already."); 44420b57cec5SDimitry Andric 44430b57cec5SDimitry Andric ICmpInst::Predicate DstPred; 44440b57cec5SDimitry Andric switch (SrcPred) { 44450b57cec5SDimitry Andric case ICmpInst::Predicate::ICMP_EQ: 44460b57cec5SDimitry Andric // ((%x << MaskedBits) a>> MaskedBits) == %x 44470b57cec5SDimitry Andric // => 44480b57cec5SDimitry Andric // (add %x, (1 << (KeptBits-1))) u< (1 << KeptBits) 44490b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_ULT; 44500b57cec5SDimitry Andric break; 44510b57cec5SDimitry Andric case ICmpInst::Predicate::ICMP_NE: 44520b57cec5SDimitry Andric // ((%x << MaskedBits) a>> MaskedBits) != %x 44530b57cec5SDimitry Andric // => 44540b57cec5SDimitry Andric // (add %x, (1 << (KeptBits-1))) u>= (1 << KeptBits) 44550b57cec5SDimitry Andric DstPred = ICmpInst::Predicate::ICMP_UGE; 44560b57cec5SDimitry Andric break; 44570b57cec5SDimitry Andric // FIXME: are more folds possible? 44580b57cec5SDimitry Andric default: 44590b57cec5SDimitry Andric return nullptr; 44600b57cec5SDimitry Andric } 44610b57cec5SDimitry Andric 44620b57cec5SDimitry Andric auto *XType = X->getType(); 44630b57cec5SDimitry Andric const unsigned XBitWidth = XType->getScalarSizeInBits(); 44640b57cec5SDimitry Andric const APInt BitWidth = APInt(XBitWidth, XBitWidth); 44650b57cec5SDimitry Andric assert(BitWidth.ugt(MaskedBits) && "shifts should leave some bits untouched"); 44660b57cec5SDimitry Andric 44670b57cec5SDimitry Andric // KeptBits = bitwidth(%x) - MaskedBits 44680b57cec5SDimitry Andric const APInt KeptBits = BitWidth - MaskedBits; 44690b57cec5SDimitry Andric assert(KeptBits.ugt(0) && KeptBits.ult(BitWidth) && "unreachable"); 44700b57cec5SDimitry Andric // ICmpCst = (1 << KeptBits) 44710b57cec5SDimitry Andric const APInt ICmpCst = APInt(XBitWidth, 1).shl(KeptBits); 44720b57cec5SDimitry Andric assert(ICmpCst.isPowerOf2()); 44730b57cec5SDimitry Andric // AddCst = (1 << (KeptBits-1)) 44740b57cec5SDimitry Andric const APInt AddCst = ICmpCst.lshr(1); 44750b57cec5SDimitry Andric assert(AddCst.ult(ICmpCst) && AddCst.isPowerOf2()); 44760b57cec5SDimitry Andric 44770b57cec5SDimitry Andric // T0 = add %x, AddCst 44780b57cec5SDimitry Andric Value *T0 = Builder.CreateAdd(X, ConstantInt::get(XType, AddCst)); 44790b57cec5SDimitry Andric // T1 = T0 DstPred ICmpCst 44800b57cec5SDimitry Andric Value *T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst)); 44810b57cec5SDimitry Andric 44820b57cec5SDimitry Andric return T1; 44830b57cec5SDimitry Andric } 44840b57cec5SDimitry Andric 44850b57cec5SDimitry Andric // Given pattern: 44860b57cec5SDimitry Andric // icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0 44870b57cec5SDimitry Andric // we should move shifts to the same hand of 'and', i.e. rewrite as 44880b57cec5SDimitry Andric // icmp eq/ne (and (x shift (Q+K)), y), 0 iff (Q+K) u< bitwidth(x) 44890b57cec5SDimitry Andric // We are only interested in opposite logical shifts here. 44908bcb0991SDimitry Andric // One of the shifts can be truncated. 44910b57cec5SDimitry Andric // If we can, we want to end up creating 'lshr' shift. 44920b57cec5SDimitry Andric static Value * 44930b57cec5SDimitry Andric foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ, 44940b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder) { 44950b57cec5SDimitry Andric if (!I.isEquality() || !match(I.getOperand(1), m_Zero()) || 44960b57cec5SDimitry Andric !I.getOperand(0)->hasOneUse()) 44970b57cec5SDimitry Andric return nullptr; 44980b57cec5SDimitry Andric 44990b57cec5SDimitry Andric auto m_AnyLogicalShift = m_LogicalShift(m_Value(), m_Value()); 45000b57cec5SDimitry Andric 45018bcb0991SDimitry Andric // Look for an 'and' of two logical shifts, one of which may be truncated. 45028bcb0991SDimitry Andric // We use m_TruncOrSelf() on the RHS to correctly handle commutative case. 45038bcb0991SDimitry Andric Instruction *XShift, *MaybeTruncation, *YShift; 45048bcb0991SDimitry Andric if (!match( 45058bcb0991SDimitry Andric I.getOperand(0), 45060b57cec5SDimitry Andric m_c_And(m_CombineAnd(m_AnyLogicalShift, m_Instruction(XShift)), 45078bcb0991SDimitry Andric m_CombineAnd(m_TruncOrSelf(m_CombineAnd( 45088bcb0991SDimitry Andric m_AnyLogicalShift, m_Instruction(YShift))), 45098bcb0991SDimitry Andric m_Instruction(MaybeTruncation))))) 45100b57cec5SDimitry Andric return nullptr; 45110b57cec5SDimitry Andric 45128bcb0991SDimitry Andric // We potentially looked past 'trunc', but only when matching YShift, 45138bcb0991SDimitry Andric // therefore YShift must have the widest type. 45148bcb0991SDimitry Andric Instruction *WidestShift = YShift; 45158bcb0991SDimitry Andric // Therefore XShift must have the shallowest type. 45168bcb0991SDimitry Andric // Or they both have identical types if there was no truncation. 45178bcb0991SDimitry Andric Instruction *NarrowestShift = XShift; 45188bcb0991SDimitry Andric 45198bcb0991SDimitry Andric Type *WidestTy = WidestShift->getType(); 452047395794SDimitry Andric Type *NarrowestTy = NarrowestShift->getType(); 452147395794SDimitry Andric assert(NarrowestTy == I.getOperand(0)->getType() && 45228bcb0991SDimitry Andric "We did not look past any shifts while matching XShift though."); 45238bcb0991SDimitry Andric bool HadTrunc = WidestTy != I.getOperand(0)->getType(); 45248bcb0991SDimitry Andric 45250b57cec5SDimitry Andric // If YShift is a 'lshr', swap the shifts around. 45268bcb0991SDimitry Andric if (match(YShift, m_LShr(m_Value(), m_Value()))) 45270b57cec5SDimitry Andric std::swap(XShift, YShift); 45280b57cec5SDimitry Andric 45290b57cec5SDimitry Andric // The shifts must be in opposite directions. 45300b57cec5SDimitry Andric auto XShiftOpcode = XShift->getOpcode(); 45310b57cec5SDimitry Andric if (XShiftOpcode == YShift->getOpcode()) 45320b57cec5SDimitry Andric return nullptr; // Do not care about same-direction shifts here. 45330b57cec5SDimitry Andric 45340b57cec5SDimitry Andric Value *X, *XShAmt, *Y, *YShAmt; 45358bcb0991SDimitry Andric match(XShift, m_BinOp(m_Value(X), m_ZExtOrSelf(m_Value(XShAmt)))); 45368bcb0991SDimitry Andric match(YShift, m_BinOp(m_Value(Y), m_ZExtOrSelf(m_Value(YShAmt)))); 45370b57cec5SDimitry Andric 45380b57cec5SDimitry Andric // If one of the values being shifted is a constant, then we will end with 45398bcb0991SDimitry Andric // and+icmp, and [zext+]shift instrs will be constant-folded. If they are not, 45400b57cec5SDimitry Andric // however, we will need to ensure that we won't increase instruction count. 45410b57cec5SDimitry Andric if (!isa<Constant>(X) && !isa<Constant>(Y)) { 45420b57cec5SDimitry Andric // At least one of the hands of the 'and' should be one-use shift. 45430b57cec5SDimitry Andric if (!match(I.getOperand(0), 45440b57cec5SDimitry Andric m_c_And(m_OneUse(m_AnyLogicalShift), m_Value()))) 45450b57cec5SDimitry Andric return nullptr; 45468bcb0991SDimitry Andric if (HadTrunc) { 45478bcb0991SDimitry Andric // Due to the 'trunc', we will need to widen X. For that either the old 45488bcb0991SDimitry Andric // 'trunc' or the shift amt in the non-truncated shift should be one-use. 45498bcb0991SDimitry Andric if (!MaybeTruncation->hasOneUse() && 45508bcb0991SDimitry Andric !NarrowestShift->getOperand(1)->hasOneUse()) 45518bcb0991SDimitry Andric return nullptr; 45528bcb0991SDimitry Andric } 45530b57cec5SDimitry Andric } 45540b57cec5SDimitry Andric 45558bcb0991SDimitry Andric // We have two shift amounts from two different shifts. The types of those 45568bcb0991SDimitry Andric // shift amounts may not match. If that's the case let's bailout now. 45578bcb0991SDimitry Andric if (XShAmt->getType() != YShAmt->getType()) 45588bcb0991SDimitry Andric return nullptr; 45598bcb0991SDimitry Andric 456047395794SDimitry Andric // As input, we have the following pattern: 456147395794SDimitry Andric // icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0 456247395794SDimitry Andric // We want to rewrite that as: 456347395794SDimitry Andric // icmp eq/ne (and (x shift (Q+K)), y), 0 iff (Q+K) u< bitwidth(x) 456447395794SDimitry Andric // While we know that originally (Q+K) would not overflow 456547395794SDimitry Andric // (because 2 * (N-1) u<= iN -1), we have looked past extensions of 456647395794SDimitry Andric // shift amounts. so it may now overflow in smaller bitwidth. 456747395794SDimitry Andric // To ensure that does not happen, we need to ensure that the total maximal 456847395794SDimitry Andric // shift amount is still representable in that smaller bit width. 456947395794SDimitry Andric unsigned MaximalPossibleTotalShiftAmount = 457047395794SDimitry Andric (WidestTy->getScalarSizeInBits() - 1) + 457147395794SDimitry Andric (NarrowestTy->getScalarSizeInBits() - 1); 457247395794SDimitry Andric APInt MaximalRepresentableShiftAmount = 4573349cc55cSDimitry Andric APInt::getAllOnes(XShAmt->getType()->getScalarSizeInBits()); 457447395794SDimitry Andric if (MaximalRepresentableShiftAmount.ult(MaximalPossibleTotalShiftAmount)) 457547395794SDimitry Andric return nullptr; 457647395794SDimitry Andric 45770b57cec5SDimitry Andric // Can we fold (XShAmt+YShAmt) ? 45788bcb0991SDimitry Andric auto *NewShAmt = dyn_cast_or_null<Constant>( 457981ad6265SDimitry Andric simplifyAddInst(XShAmt, YShAmt, /*isNSW=*/false, 45808bcb0991SDimitry Andric /*isNUW=*/false, SQ.getWithInstruction(&I))); 45810b57cec5SDimitry Andric if (!NewShAmt) 45820b57cec5SDimitry Andric return nullptr; 45835f757f3fSDimitry Andric if (NewShAmt->getType() != WidestTy) { 45845f757f3fSDimitry Andric NewShAmt = 45855f757f3fSDimitry Andric ConstantFoldCastOperand(Instruction::ZExt, NewShAmt, WidestTy, SQ.DL); 45865f757f3fSDimitry Andric if (!NewShAmt) 45875f757f3fSDimitry Andric return nullptr; 45885f757f3fSDimitry Andric } 45898bcb0991SDimitry Andric unsigned WidestBitWidth = WidestTy->getScalarSizeInBits(); 45908bcb0991SDimitry Andric 45910b57cec5SDimitry Andric // Is the new shift amount smaller than the bit width? 45920b57cec5SDimitry Andric // FIXME: could also rely on ConstantRange. 45938bcb0991SDimitry Andric if (!match(NewShAmt, 45948bcb0991SDimitry Andric m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, 45958bcb0991SDimitry Andric APInt(WidestBitWidth, WidestBitWidth)))) 45960b57cec5SDimitry Andric return nullptr; 45978bcb0991SDimitry Andric 45988bcb0991SDimitry Andric // An extra legality check is needed if we had trunc-of-lshr. 45998bcb0991SDimitry Andric if (HadTrunc && match(WidestShift, m_LShr(m_Value(), m_Value()))) { 46008bcb0991SDimitry Andric auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ, 46018bcb0991SDimitry Andric WidestShift]() { 46028bcb0991SDimitry Andric // It isn't obvious whether it's worth it to analyze non-constants here. 46038bcb0991SDimitry Andric // Also, let's basically give up on non-splat cases, pessimizing vectors. 46048bcb0991SDimitry Andric // If *any* of these preconditions matches we can perform the fold. 46058bcb0991SDimitry Andric Constant *NewShAmtSplat = NewShAmt->getType()->isVectorTy() 46068bcb0991SDimitry Andric ? NewShAmt->getSplatValue() 46078bcb0991SDimitry Andric : NewShAmt; 46088bcb0991SDimitry Andric // If it's edge-case shift (by 0 or by WidestBitWidth-1) we can fold. 46098bcb0991SDimitry Andric if (NewShAmtSplat && 46108bcb0991SDimitry Andric (NewShAmtSplat->isNullValue() || 46118bcb0991SDimitry Andric NewShAmtSplat->getUniqueInteger() == WidestBitWidth - 1)) 46128bcb0991SDimitry Andric return true; 46138bcb0991SDimitry Andric // We consider *min* leading zeros so a single outlier 46148bcb0991SDimitry Andric // blocks the transform as opposed to allowing it. 46158bcb0991SDimitry Andric if (auto *C = dyn_cast<Constant>(NarrowestShift->getOperand(0))) { 46168bcb0991SDimitry Andric KnownBits Known = computeKnownBits(C, SQ.DL); 46178bcb0991SDimitry Andric unsigned MinLeadZero = Known.countMinLeadingZeros(); 46188bcb0991SDimitry Andric // If the value being shifted has at most lowest bit set we can fold. 46198bcb0991SDimitry Andric unsigned MaxActiveBits = Known.getBitWidth() - MinLeadZero; 46208bcb0991SDimitry Andric if (MaxActiveBits <= 1) 46218bcb0991SDimitry Andric return true; 46228bcb0991SDimitry Andric // Precondition: NewShAmt u<= countLeadingZeros(C) 46238bcb0991SDimitry Andric if (NewShAmtSplat && NewShAmtSplat->getUniqueInteger().ule(MinLeadZero)) 46248bcb0991SDimitry Andric return true; 46258bcb0991SDimitry Andric } 46268bcb0991SDimitry Andric if (auto *C = dyn_cast<Constant>(WidestShift->getOperand(0))) { 46278bcb0991SDimitry Andric KnownBits Known = computeKnownBits(C, SQ.DL); 46288bcb0991SDimitry Andric unsigned MinLeadZero = Known.countMinLeadingZeros(); 46298bcb0991SDimitry Andric // If the value being shifted has at most lowest bit set we can fold. 46308bcb0991SDimitry Andric unsigned MaxActiveBits = Known.getBitWidth() - MinLeadZero; 46318bcb0991SDimitry Andric if (MaxActiveBits <= 1) 46328bcb0991SDimitry Andric return true; 46338bcb0991SDimitry Andric // Precondition: ((WidestBitWidth-1)-NewShAmt) u<= countLeadingZeros(C) 46348bcb0991SDimitry Andric if (NewShAmtSplat) { 46358bcb0991SDimitry Andric APInt AdjNewShAmt = 46368bcb0991SDimitry Andric (WidestBitWidth - 1) - NewShAmtSplat->getUniqueInteger(); 46378bcb0991SDimitry Andric if (AdjNewShAmt.ule(MinLeadZero)) 46388bcb0991SDimitry Andric return true; 46398bcb0991SDimitry Andric } 46408bcb0991SDimitry Andric } 46418bcb0991SDimitry Andric return false; // Can't tell if it's ok. 46428bcb0991SDimitry Andric }; 46438bcb0991SDimitry Andric if (!CanFold()) 46448bcb0991SDimitry Andric return nullptr; 46458bcb0991SDimitry Andric } 46468bcb0991SDimitry Andric 46478bcb0991SDimitry Andric // All good, we can do this fold. 46488bcb0991SDimitry Andric X = Builder.CreateZExt(X, WidestTy); 46498bcb0991SDimitry Andric Y = Builder.CreateZExt(Y, WidestTy); 46508bcb0991SDimitry Andric // The shift is the same that was for X. 46510b57cec5SDimitry Andric Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr 46520b57cec5SDimitry Andric ? Builder.CreateLShr(X, NewShAmt) 46530b57cec5SDimitry Andric : Builder.CreateShl(X, NewShAmt); 46540b57cec5SDimitry Andric Value *T1 = Builder.CreateAnd(T0, Y); 46550b57cec5SDimitry Andric return Builder.CreateICmp(I.getPredicate(), T1, 46568bcb0991SDimitry Andric Constant::getNullValue(WidestTy)); 46578bcb0991SDimitry Andric } 46588bcb0991SDimitry Andric 46598bcb0991SDimitry Andric /// Fold 46608bcb0991SDimitry Andric /// (-1 u/ x) u< y 4661349cc55cSDimitry Andric /// ((x * y) ?/ x) != y 46628bcb0991SDimitry Andric /// to 4663349cc55cSDimitry Andric /// @llvm.?mul.with.overflow(x, y) plus extraction of overflow bit 46648bcb0991SDimitry Andric /// Note that the comparison is commutative, while inverted (u>=, ==) predicate 46658bcb0991SDimitry Andric /// will mean that we are looking for the opposite answer. 4666349cc55cSDimitry Andric Value *InstCombinerImpl::foldMultiplicationOverflowCheck(ICmpInst &I) { 46678bcb0991SDimitry Andric ICmpInst::Predicate Pred; 46688bcb0991SDimitry Andric Value *X, *Y; 46698bcb0991SDimitry Andric Instruction *Mul; 4670349cc55cSDimitry Andric Instruction *Div; 46718bcb0991SDimitry Andric bool NeedNegation; 46728bcb0991SDimitry Andric // Look for: (-1 u/ x) u</u>= y 46738bcb0991SDimitry Andric if (!I.isEquality() && 4674349cc55cSDimitry Andric match(&I, m_c_ICmp(Pred, 4675349cc55cSDimitry Andric m_CombineAnd(m_OneUse(m_UDiv(m_AllOnes(), m_Value(X))), 4676349cc55cSDimitry Andric m_Instruction(Div)), 46778bcb0991SDimitry Andric m_Value(Y)))) { 46788bcb0991SDimitry Andric Mul = nullptr; 46798bcb0991SDimitry Andric 46808bcb0991SDimitry Andric // Are we checking that overflow does not happen, or does happen? 46818bcb0991SDimitry Andric switch (Pred) { 46828bcb0991SDimitry Andric case ICmpInst::Predicate::ICMP_ULT: 46838bcb0991SDimitry Andric NeedNegation = false; 46848bcb0991SDimitry Andric break; // OK 46858bcb0991SDimitry Andric case ICmpInst::Predicate::ICMP_UGE: 46868bcb0991SDimitry Andric NeedNegation = true; 46878bcb0991SDimitry Andric break; // OK 46888bcb0991SDimitry Andric default: 46898bcb0991SDimitry Andric return nullptr; // Wrong predicate. 46908bcb0991SDimitry Andric } 4691349cc55cSDimitry Andric } else // Look for: ((x * y) / x) !=/== y 46928bcb0991SDimitry Andric if (I.isEquality() && 4693349cc55cSDimitry Andric match(&I, 4694349cc55cSDimitry Andric m_c_ICmp(Pred, m_Value(Y), 4695349cc55cSDimitry Andric m_CombineAnd( 4696349cc55cSDimitry Andric m_OneUse(m_IDiv(m_CombineAnd(m_c_Mul(m_Deferred(Y), 46978bcb0991SDimitry Andric m_Value(X)), 46988bcb0991SDimitry Andric m_Instruction(Mul)), 4699349cc55cSDimitry Andric m_Deferred(X))), 4700349cc55cSDimitry Andric m_Instruction(Div))))) { 47018bcb0991SDimitry Andric NeedNegation = Pred == ICmpInst::Predicate::ICMP_EQ; 47028bcb0991SDimitry Andric } else 47038bcb0991SDimitry Andric return nullptr; 47048bcb0991SDimitry Andric 47058bcb0991SDimitry Andric BuilderTy::InsertPointGuard Guard(Builder); 47068bcb0991SDimitry Andric // If the pattern included (x * y), we'll want to insert new instructions 47078bcb0991SDimitry Andric // right before that original multiplication so that we can replace it. 47088bcb0991SDimitry Andric bool MulHadOtherUses = Mul && !Mul->hasOneUse(); 47098bcb0991SDimitry Andric if (MulHadOtherUses) 47108bcb0991SDimitry Andric Builder.SetInsertPoint(Mul); 47118bcb0991SDimitry Andric 4712349cc55cSDimitry Andric Function *F = Intrinsic::getDeclaration(I.getModule(), 4713349cc55cSDimitry Andric Div->getOpcode() == Instruction::UDiv 4714349cc55cSDimitry Andric ? Intrinsic::umul_with_overflow 4715349cc55cSDimitry Andric : Intrinsic::smul_with_overflow, 4716349cc55cSDimitry Andric X->getType()); 4717349cc55cSDimitry Andric CallInst *Call = Builder.CreateCall(F, {X, Y}, "mul"); 47188bcb0991SDimitry Andric 47198bcb0991SDimitry Andric // If the multiplication was used elsewhere, to ensure that we don't leave 47208bcb0991SDimitry Andric // "duplicate" instructions, replace uses of that original multiplication 47218bcb0991SDimitry Andric // with the multiplication result from the with.overflow intrinsic. 47228bcb0991SDimitry Andric if (MulHadOtherUses) 4723349cc55cSDimitry Andric replaceInstUsesWith(*Mul, Builder.CreateExtractValue(Call, 0, "mul.val")); 47248bcb0991SDimitry Andric 4725349cc55cSDimitry Andric Value *Res = Builder.CreateExtractValue(Call, 1, "mul.ov"); 47268bcb0991SDimitry Andric if (NeedNegation) // This technically increases instruction count. 4727349cc55cSDimitry Andric Res = Builder.CreateNot(Res, "mul.not.ov"); 47288bcb0991SDimitry Andric 47295ffd83dbSDimitry Andric // If we replaced the mul, erase it. Do this after all uses of Builder, 47305ffd83dbSDimitry Andric // as the mul is used as insertion point. 47315ffd83dbSDimitry Andric if (MulHadOtherUses) 47325ffd83dbSDimitry Andric eraseInstFromFunction(*Mul); 47335ffd83dbSDimitry Andric 47348bcb0991SDimitry Andric return Res; 47350b57cec5SDimitry Andric } 47360b57cec5SDimitry Andric 473706c3fb27SDimitry Andric static Instruction *foldICmpXNegX(ICmpInst &I, 473806c3fb27SDimitry Andric InstCombiner::BuilderTy &Builder) { 4739e8d8bef9SDimitry Andric CmpInst::Predicate Pred; 4740e8d8bef9SDimitry Andric Value *X; 474106c3fb27SDimitry Andric if (match(&I, m_c_ICmp(Pred, m_NSWNeg(m_Value(X)), m_Deferred(X)))) { 4742e8d8bef9SDimitry Andric 4743e8d8bef9SDimitry Andric if (ICmpInst::isSigned(Pred)) 4744e8d8bef9SDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 4745e8d8bef9SDimitry Andric else if (ICmpInst::isUnsigned(Pred)) 4746e8d8bef9SDimitry Andric Pred = ICmpInst::getSignedPredicate(Pred); 4747e8d8bef9SDimitry Andric // else for equality-comparisons just keep the predicate. 4748e8d8bef9SDimitry Andric 4749e8d8bef9SDimitry Andric return ICmpInst::Create(Instruction::ICmp, Pred, X, 4750e8d8bef9SDimitry Andric Constant::getNullValue(X->getType()), I.getName()); 4751e8d8bef9SDimitry Andric } 4752e8d8bef9SDimitry Andric 475306c3fb27SDimitry Andric // A value is not equal to its negation unless that value is 0 or 475406c3fb27SDimitry Andric // MinSignedValue, ie: a != -a --> (a & MaxSignedVal) != 0 475506c3fb27SDimitry Andric if (match(&I, m_c_ICmp(Pred, m_OneUse(m_Neg(m_Value(X))), m_Deferred(X))) && 475606c3fb27SDimitry Andric ICmpInst::isEquality(Pred)) { 475706c3fb27SDimitry Andric Type *Ty = X->getType(); 475806c3fb27SDimitry Andric uint32_t BitWidth = Ty->getScalarSizeInBits(); 475906c3fb27SDimitry Andric Constant *MaxSignedVal = 476006c3fb27SDimitry Andric ConstantInt::get(Ty, APInt::getSignedMaxValue(BitWidth)); 476106c3fb27SDimitry Andric Value *And = Builder.CreateAnd(X, MaxSignedVal); 476206c3fb27SDimitry Andric Constant *Zero = Constant::getNullValue(Ty); 476306c3fb27SDimitry Andric return CmpInst::Create(Instruction::ICmp, Pred, And, Zero); 476406c3fb27SDimitry Andric } 476506c3fb27SDimitry Andric 476606c3fb27SDimitry Andric return nullptr; 476706c3fb27SDimitry Andric } 476806c3fb27SDimitry Andric 47695f757f3fSDimitry Andric static Instruction *foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q, 47705f757f3fSDimitry Andric InstCombinerImpl &IC) { 47715f757f3fSDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; 47725f757f3fSDimitry Andric // Normalize and operand as operand 0. 47735f757f3fSDimitry Andric CmpInst::Predicate Pred = I.getPredicate(); 47745f757f3fSDimitry Andric if (match(Op1, m_c_And(m_Specific(Op0), m_Value()))) { 47755f757f3fSDimitry Andric std::swap(Op0, Op1); 47765f757f3fSDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 47775f757f3fSDimitry Andric } 47785f757f3fSDimitry Andric 47795f757f3fSDimitry Andric if (!match(Op0, m_c_And(m_Specific(Op1), m_Value(A)))) 47805f757f3fSDimitry Andric return nullptr; 47815f757f3fSDimitry Andric 47825f757f3fSDimitry Andric // (icmp (X & Y) u< X --> (X & Y) != X 47835f757f3fSDimitry Andric if (Pred == ICmpInst::ICMP_ULT) 47845f757f3fSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); 47855f757f3fSDimitry Andric 47865f757f3fSDimitry Andric // (icmp (X & Y) u>= X --> (X & Y) == X 47875f757f3fSDimitry Andric if (Pred == ICmpInst::ICMP_UGE) 47885f757f3fSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); 47895f757f3fSDimitry Andric 4790*0fca6ea1SDimitry Andric if (ICmpInst::isEquality(Pred) && Op0->hasOneUse()) { 4791*0fca6ea1SDimitry Andric // icmp (X & Y) eq/ne Y --> (X | ~Y) eq/ne -1 if Y is freely invertible and 4792*0fca6ea1SDimitry Andric // Y is non-constant. If Y is constant the `X & C == C` form is preferable 4793*0fca6ea1SDimitry Andric // so don't do this fold. 4794*0fca6ea1SDimitry Andric if (!match(Op1, m_ImmConstant())) 4795*0fca6ea1SDimitry Andric if (auto *NotOp1 = 4796*0fca6ea1SDimitry Andric IC.getFreelyInverted(Op1, !Op1->hasNUsesOrMore(3), &IC.Builder)) 4797*0fca6ea1SDimitry Andric return new ICmpInst(Pred, IC.Builder.CreateOr(A, NotOp1), 4798*0fca6ea1SDimitry Andric Constant::getAllOnesValue(Op1->getType())); 4799*0fca6ea1SDimitry Andric // icmp (X & Y) eq/ne Y --> (~X & Y) eq/ne 0 if X is freely invertible. 4800*0fca6ea1SDimitry Andric if (auto *NotA = IC.getFreelyInverted(A, A->hasOneUse(), &IC.Builder)) 4801*0fca6ea1SDimitry Andric return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, NotA), 4802*0fca6ea1SDimitry Andric Constant::getNullValue(Op1->getType())); 4803*0fca6ea1SDimitry Andric } 4804*0fca6ea1SDimitry Andric 4805*0fca6ea1SDimitry Andric if (!ICmpInst::isSigned(Pred)) 4806*0fca6ea1SDimitry Andric return nullptr; 4807*0fca6ea1SDimitry Andric 4808*0fca6ea1SDimitry Andric KnownBits KnownY = IC.computeKnownBits(A, /*Depth=*/0, &I); 4809*0fca6ea1SDimitry Andric // (X & NegY) spred X --> (X & NegY) upred X 4810*0fca6ea1SDimitry Andric if (KnownY.isNegative()) 4811*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getUnsignedPredicate(Pred), Op0, Op1); 4812*0fca6ea1SDimitry Andric 4813*0fca6ea1SDimitry Andric if (Pred != ICmpInst::ICMP_SLE && Pred != ICmpInst::ICMP_SGT) 4814*0fca6ea1SDimitry Andric return nullptr; 4815*0fca6ea1SDimitry Andric 4816*0fca6ea1SDimitry Andric if (KnownY.isNonNegative()) 4817*0fca6ea1SDimitry Andric // (X & PosY) s<= X --> X s>= 0 4818*0fca6ea1SDimitry Andric // (X & PosY) s> X --> X s< 0 4819*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1, 4820*0fca6ea1SDimitry Andric Constant::getNullValue(Op1->getType())); 4821*0fca6ea1SDimitry Andric 4822*0fca6ea1SDimitry Andric if (isKnownNegative(Op1, IC.getSimplifyQuery().getWithInstruction(&I))) 4823*0fca6ea1SDimitry Andric // (NegX & Y) s<= NegX --> Y s< 0 4824*0fca6ea1SDimitry Andric // (NegX & Y) s> NegX --> Y s>= 0 4825*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getFlippedStrictnessPredicate(Pred), A, 4826*0fca6ea1SDimitry Andric Constant::getNullValue(A->getType())); 4827*0fca6ea1SDimitry Andric 48285f757f3fSDimitry Andric return nullptr; 48295f757f3fSDimitry Andric } 48305f757f3fSDimitry Andric 48315f757f3fSDimitry Andric static Instruction *foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, 48325f757f3fSDimitry Andric InstCombinerImpl &IC) { 48335f757f3fSDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; 48345f757f3fSDimitry Andric 48355f757f3fSDimitry Andric // Normalize or operand as operand 0. 48365f757f3fSDimitry Andric CmpInst::Predicate Pred = I.getPredicate(); 48375f757f3fSDimitry Andric if (match(Op1, m_c_Or(m_Specific(Op0), m_Value(A)))) { 48385f757f3fSDimitry Andric std::swap(Op0, Op1); 48395f757f3fSDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 48405f757f3fSDimitry Andric } else if (!match(Op0, m_c_Or(m_Specific(Op1), m_Value(A)))) { 48415f757f3fSDimitry Andric return nullptr; 48425f757f3fSDimitry Andric } 48435f757f3fSDimitry Andric 48445f757f3fSDimitry Andric // icmp (X | Y) u<= X --> (X | Y) == X 48455f757f3fSDimitry Andric if (Pred == ICmpInst::ICMP_ULE) 48465f757f3fSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); 48475f757f3fSDimitry Andric 48485f757f3fSDimitry Andric // icmp (X | Y) u> X --> (X | Y) != X 48495f757f3fSDimitry Andric if (Pred == ICmpInst::ICMP_UGT) 48505f757f3fSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); 48515f757f3fSDimitry Andric 48525f757f3fSDimitry Andric if (ICmpInst::isEquality(Pred) && Op0->hasOneUse()) { 48535f757f3fSDimitry Andric // icmp (X | Y) eq/ne Y --> (X & ~Y) eq/ne 0 if Y is freely invertible 48545f757f3fSDimitry Andric if (Value *NotOp1 = 4855*0fca6ea1SDimitry Andric IC.getFreelyInverted(Op1, !Op1->hasNUsesOrMore(3), &IC.Builder)) 48565f757f3fSDimitry Andric return new ICmpInst(Pred, IC.Builder.CreateAnd(A, NotOp1), 48575f757f3fSDimitry Andric Constant::getNullValue(Op1->getType())); 48585f757f3fSDimitry Andric // icmp (X | Y) eq/ne Y --> (~X | Y) eq/ne -1 if X is freely invertible. 48595f757f3fSDimitry Andric if (Value *NotA = IC.getFreelyInverted(A, A->hasOneUse(), &IC.Builder)) 48605f757f3fSDimitry Andric return new ICmpInst(Pred, IC.Builder.CreateOr(Op1, NotA), 48615f757f3fSDimitry Andric Constant::getAllOnesValue(Op1->getType())); 48625f757f3fSDimitry Andric } 48635f757f3fSDimitry Andric return nullptr; 48645f757f3fSDimitry Andric } 48655f757f3fSDimitry Andric 486606c3fb27SDimitry Andric static Instruction *foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, 486706c3fb27SDimitry Andric InstCombinerImpl &IC) { 486806c3fb27SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; 486906c3fb27SDimitry Andric // Normalize xor operand as operand 0. 487006c3fb27SDimitry Andric CmpInst::Predicate Pred = I.getPredicate(); 487106c3fb27SDimitry Andric if (match(Op1, m_c_Xor(m_Specific(Op0), m_Value()))) { 487206c3fb27SDimitry Andric std::swap(Op0, Op1); 487306c3fb27SDimitry Andric Pred = ICmpInst::getSwappedPredicate(Pred); 487406c3fb27SDimitry Andric } 487506c3fb27SDimitry Andric if (!match(Op0, m_c_Xor(m_Specific(Op1), m_Value(A)))) 487606c3fb27SDimitry Andric return nullptr; 487706c3fb27SDimitry Andric 487806c3fb27SDimitry Andric // icmp (X ^ Y_NonZero) u>= X --> icmp (X ^ Y_NonZero) u> X 487906c3fb27SDimitry Andric // icmp (X ^ Y_NonZero) u<= X --> icmp (X ^ Y_NonZero) u< X 488006c3fb27SDimitry Andric // icmp (X ^ Y_NonZero) s>= X --> icmp (X ^ Y_NonZero) s> X 488106c3fb27SDimitry Andric // icmp (X ^ Y_NonZero) s<= X --> icmp (X ^ Y_NonZero) s< X 488206c3fb27SDimitry Andric CmpInst::Predicate PredOut = CmpInst::getStrictPredicate(Pred); 4883*0fca6ea1SDimitry Andric if (PredOut != Pred && isKnownNonZero(A, Q)) 488406c3fb27SDimitry Andric return new ICmpInst(PredOut, Op0, Op1); 488506c3fb27SDimitry Andric 488606c3fb27SDimitry Andric return nullptr; 488706c3fb27SDimitry Andric } 488806c3fb27SDimitry Andric 48890b57cec5SDimitry Andric /// Try to fold icmp (binop), X or icmp X, (binop). 48900b57cec5SDimitry Andric /// TODO: A large part of this logic is duplicated in InstSimplify's 48910b57cec5SDimitry Andric /// simplifyICmpWithBinOp(). We should be able to share that and avoid the code 48920b57cec5SDimitry Andric /// duplication. 4893e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I, 4894e8d8bef9SDimitry Andric const SimplifyQuery &SQ) { 48958bcb0991SDimitry Andric const SimplifyQuery Q = SQ.getWithInstruction(&I); 48960b57cec5SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 48970b57cec5SDimitry Andric 48980b57cec5SDimitry Andric // Special logic for binary operators. 48990b57cec5SDimitry Andric BinaryOperator *BO0 = dyn_cast<BinaryOperator>(Op0); 49000b57cec5SDimitry Andric BinaryOperator *BO1 = dyn_cast<BinaryOperator>(Op1); 49010b57cec5SDimitry Andric if (!BO0 && !BO1) 49020b57cec5SDimitry Andric return nullptr; 49030b57cec5SDimitry Andric 490406c3fb27SDimitry Andric if (Instruction *NewICmp = foldICmpXNegX(I, Builder)) 4905e8d8bef9SDimitry Andric return NewICmp; 4906e8d8bef9SDimitry Andric 49070b57cec5SDimitry Andric const CmpInst::Predicate Pred = I.getPredicate(); 49080b57cec5SDimitry Andric Value *X; 49090b57cec5SDimitry Andric 49100b57cec5SDimitry Andric // Convert add-with-unsigned-overflow comparisons into a 'not' with compare. 49118bcb0991SDimitry Andric // (Op1 + X) u</u>= Op1 --> ~Op1 u</u>= X 49120b57cec5SDimitry Andric if (match(Op0, m_OneUse(m_c_Add(m_Specific(Op1), m_Value(X)))) && 49138bcb0991SDimitry Andric (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)) 49140b57cec5SDimitry Andric return new ICmpInst(Pred, Builder.CreateNot(Op1), X); 49158bcb0991SDimitry Andric // Op0 u>/u<= (Op0 + X) --> X u>/u<= ~Op0 49160b57cec5SDimitry Andric if (match(Op1, m_OneUse(m_c_Add(m_Specific(Op0), m_Value(X)))) && 49178bcb0991SDimitry Andric (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE)) 49180b57cec5SDimitry Andric return new ICmpInst(Pred, X, Builder.CreateNot(Op0)); 49190b57cec5SDimitry Andric 492004eeddc0SDimitry Andric { 492181ad6265SDimitry Andric // (Op1 + X) + C u</u>= Op1 --> ~C - X u</u>= Op1 492281ad6265SDimitry Andric Constant *C; 492381ad6265SDimitry Andric if (match(Op0, m_OneUse(m_Add(m_c_Add(m_Specific(Op1), m_Value(X)), 492481ad6265SDimitry Andric m_ImmConstant(C)))) && 492581ad6265SDimitry Andric (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)) { 492681ad6265SDimitry Andric Constant *C2 = ConstantExpr::getNot(C); 492781ad6265SDimitry Andric return new ICmpInst(Pred, Builder.CreateSub(C2, X), Op1); 492881ad6265SDimitry Andric } 492981ad6265SDimitry Andric // Op0 u>/u<= (Op0 + X) + C --> Op0 u>/u<= ~C - X 493081ad6265SDimitry Andric if (match(Op1, m_OneUse(m_Add(m_c_Add(m_Specific(Op0), m_Value(X)), 493181ad6265SDimitry Andric m_ImmConstant(C)))) && 493281ad6265SDimitry Andric (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE)) { 493381ad6265SDimitry Andric Constant *C2 = ConstantExpr::getNot(C); 493481ad6265SDimitry Andric return new ICmpInst(Pred, Op0, Builder.CreateSub(C2, X)); 493581ad6265SDimitry Andric } 493681ad6265SDimitry Andric } 493781ad6265SDimitry Andric 493881ad6265SDimitry Andric { 493904eeddc0SDimitry Andric // Similar to above: an unsigned overflow comparison may use offset + mask: 494004eeddc0SDimitry Andric // ((Op1 + C) & C) u< Op1 --> Op1 != 0 494104eeddc0SDimitry Andric // ((Op1 + C) & C) u>= Op1 --> Op1 == 0 494204eeddc0SDimitry Andric // Op0 u> ((Op0 + C) & C) --> Op0 != 0 494304eeddc0SDimitry Andric // Op0 u<= ((Op0 + C) & C) --> Op0 == 0 494404eeddc0SDimitry Andric BinaryOperator *BO; 494504eeddc0SDimitry Andric const APInt *C; 494604eeddc0SDimitry Andric if ((Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE) && 494704eeddc0SDimitry Andric match(Op0, m_And(m_BinOp(BO), m_LowBitMask(C))) && 4948*0fca6ea1SDimitry Andric match(BO, m_Add(m_Specific(Op1), m_SpecificIntAllowPoison(*C)))) { 494904eeddc0SDimitry Andric CmpInst::Predicate NewPred = 495004eeddc0SDimitry Andric Pred == ICmpInst::ICMP_ULT ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ; 495104eeddc0SDimitry Andric Constant *Zero = ConstantInt::getNullValue(Op1->getType()); 495204eeddc0SDimitry Andric return new ICmpInst(NewPred, Op1, Zero); 495304eeddc0SDimitry Andric } 495404eeddc0SDimitry Andric 495504eeddc0SDimitry Andric if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE) && 495604eeddc0SDimitry Andric match(Op1, m_And(m_BinOp(BO), m_LowBitMask(C))) && 4957*0fca6ea1SDimitry Andric match(BO, m_Add(m_Specific(Op0), m_SpecificIntAllowPoison(*C)))) { 495804eeddc0SDimitry Andric CmpInst::Predicate NewPred = 495904eeddc0SDimitry Andric Pred == ICmpInst::ICMP_UGT ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ; 496004eeddc0SDimitry Andric Constant *Zero = ConstantInt::getNullValue(Op1->getType()); 496104eeddc0SDimitry Andric return new ICmpInst(NewPred, Op0, Zero); 496204eeddc0SDimitry Andric } 496304eeddc0SDimitry Andric } 496404eeddc0SDimitry Andric 49650b57cec5SDimitry Andric bool NoOp0WrapProblem = false, NoOp1WrapProblem = false; 4966647cbc5dSDimitry Andric bool Op0HasNUW = false, Op1HasNUW = false; 4967647cbc5dSDimitry Andric bool Op0HasNSW = false, Op1HasNSW = false; 49680b57cec5SDimitry Andric // Analyze the case when either Op0 or Op1 is an add instruction. 49690b57cec5SDimitry Andric // Op0 = A + B (or A and B are null); Op1 = C + D (or C and D are null). 4970647cbc5dSDimitry Andric auto hasNoWrapProblem = [](const BinaryOperator &BO, CmpInst::Predicate Pred, 4971647cbc5dSDimitry Andric bool &HasNSW, bool &HasNUW) -> bool { 4972647cbc5dSDimitry Andric if (isa<OverflowingBinaryOperator>(BO)) { 4973647cbc5dSDimitry Andric HasNUW = BO.hasNoUnsignedWrap(); 4974647cbc5dSDimitry Andric HasNSW = BO.hasNoSignedWrap(); 4975647cbc5dSDimitry Andric return ICmpInst::isEquality(Pred) || 4976647cbc5dSDimitry Andric (CmpInst::isUnsigned(Pred) && HasNUW) || 4977647cbc5dSDimitry Andric (CmpInst::isSigned(Pred) && HasNSW); 4978647cbc5dSDimitry Andric } else if (BO.getOpcode() == Instruction::Or) { 4979647cbc5dSDimitry Andric HasNUW = true; 4980647cbc5dSDimitry Andric HasNSW = true; 4981647cbc5dSDimitry Andric return true; 4982647cbc5dSDimitry Andric } else { 4983647cbc5dSDimitry Andric return false; 49840b57cec5SDimitry Andric } 4985647cbc5dSDimitry Andric }; 4986647cbc5dSDimitry Andric Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr; 4987647cbc5dSDimitry Andric 4988647cbc5dSDimitry Andric if (BO0) { 4989647cbc5dSDimitry Andric match(BO0, m_AddLike(m_Value(A), m_Value(B))); 4990647cbc5dSDimitry Andric NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW); 4991647cbc5dSDimitry Andric } 4992647cbc5dSDimitry Andric if (BO1) { 4993647cbc5dSDimitry Andric match(BO1, m_AddLike(m_Value(C), m_Value(D))); 4994647cbc5dSDimitry Andric NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW); 49950b57cec5SDimitry Andric } 49960b57cec5SDimitry Andric 49978bcb0991SDimitry Andric // icmp (A+B), A -> icmp B, 0 for equalities or if there is no overflow. 49988bcb0991SDimitry Andric // icmp (A+B), B -> icmp A, 0 for equalities or if there is no overflow. 49990b57cec5SDimitry Andric if ((A == Op1 || B == Op1) && NoOp0WrapProblem) 50000b57cec5SDimitry Andric return new ICmpInst(Pred, A == Op1 ? B : A, 50010b57cec5SDimitry Andric Constant::getNullValue(Op1->getType())); 50020b57cec5SDimitry Andric 50038bcb0991SDimitry Andric // icmp C, (C+D) -> icmp 0, D for equalities or if there is no overflow. 50048bcb0991SDimitry Andric // icmp D, (C+D) -> icmp 0, C for equalities or if there is no overflow. 50050b57cec5SDimitry Andric if ((C == Op0 || D == Op0) && NoOp1WrapProblem) 50060b57cec5SDimitry Andric return new ICmpInst(Pred, Constant::getNullValue(Op0->getType()), 50070b57cec5SDimitry Andric C == Op0 ? D : C); 50080b57cec5SDimitry Andric 50098bcb0991SDimitry Andric // icmp (A+B), (A+D) -> icmp B, D for equalities or if there is no overflow. 50100b57cec5SDimitry Andric if (A && C && (A == C || A == D || B == C || B == D) && NoOp0WrapProblem && 50118bcb0991SDimitry Andric NoOp1WrapProblem) { 50120b57cec5SDimitry Andric // Determine Y and Z in the form icmp (X+Y), (X+Z). 50130b57cec5SDimitry Andric Value *Y, *Z; 50140b57cec5SDimitry Andric if (A == C) { 50150b57cec5SDimitry Andric // C + B == C + D -> B == D 50160b57cec5SDimitry Andric Y = B; 50170b57cec5SDimitry Andric Z = D; 50180b57cec5SDimitry Andric } else if (A == D) { 50190b57cec5SDimitry Andric // D + B == C + D -> B == C 50200b57cec5SDimitry Andric Y = B; 50210b57cec5SDimitry Andric Z = C; 50220b57cec5SDimitry Andric } else if (B == C) { 50230b57cec5SDimitry Andric // A + C == C + D -> A == D 50240b57cec5SDimitry Andric Y = A; 50250b57cec5SDimitry Andric Z = D; 50260b57cec5SDimitry Andric } else { 50270b57cec5SDimitry Andric assert(B == D); 50280b57cec5SDimitry Andric // A + D == C + D -> A == C 50290b57cec5SDimitry Andric Y = A; 50300b57cec5SDimitry Andric Z = C; 50310b57cec5SDimitry Andric } 50320b57cec5SDimitry Andric return new ICmpInst(Pred, Y, Z); 50330b57cec5SDimitry Andric } 50340b57cec5SDimitry Andric 50358bcb0991SDimitry Andric // icmp slt (A + -1), Op1 -> icmp sle A, Op1 50360b57cec5SDimitry Andric if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SLT && 50370b57cec5SDimitry Andric match(B, m_AllOnes())) 50380b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SLE, A, Op1); 50390b57cec5SDimitry Andric 50408bcb0991SDimitry Andric // icmp sge (A + -1), Op1 -> icmp sgt A, Op1 50410b57cec5SDimitry Andric if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SGE && 50420b57cec5SDimitry Andric match(B, m_AllOnes())) 50430b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SGT, A, Op1); 50440b57cec5SDimitry Andric 50458bcb0991SDimitry Andric // icmp sle (A + 1), Op1 -> icmp slt A, Op1 50460b57cec5SDimitry Andric if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SLE && match(B, m_One())) 50470b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SLT, A, Op1); 50480b57cec5SDimitry Andric 50498bcb0991SDimitry Andric // icmp sgt (A + 1), Op1 -> icmp sge A, Op1 50500b57cec5SDimitry Andric if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SGT && match(B, m_One())) 50510b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SGE, A, Op1); 50520b57cec5SDimitry Andric 50538bcb0991SDimitry Andric // icmp sgt Op0, (C + -1) -> icmp sge Op0, C 50540b57cec5SDimitry Andric if (C && NoOp1WrapProblem && Pred == CmpInst::ICMP_SGT && 50550b57cec5SDimitry Andric match(D, m_AllOnes())) 50560b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SGE, Op0, C); 50570b57cec5SDimitry Andric 50588bcb0991SDimitry Andric // icmp sle Op0, (C + -1) -> icmp slt Op0, C 50590b57cec5SDimitry Andric if (C && NoOp1WrapProblem && Pred == CmpInst::ICMP_SLE && 50600b57cec5SDimitry Andric match(D, m_AllOnes())) 50610b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SLT, Op0, C); 50620b57cec5SDimitry Andric 50638bcb0991SDimitry Andric // icmp sge Op0, (C + 1) -> icmp sgt Op0, C 50640b57cec5SDimitry Andric if (C && NoOp1WrapProblem && Pred == CmpInst::ICMP_SGE && match(D, m_One())) 50650b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SGT, Op0, C); 50660b57cec5SDimitry Andric 50678bcb0991SDimitry Andric // icmp slt Op0, (C + 1) -> icmp sle Op0, C 50680b57cec5SDimitry Andric if (C && NoOp1WrapProblem && Pred == CmpInst::ICMP_SLT && match(D, m_One())) 50690b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_SLE, Op0, C); 50700b57cec5SDimitry Andric 50710b57cec5SDimitry Andric // TODO: The subtraction-related identities shown below also hold, but 50720b57cec5SDimitry Andric // canonicalization from (X -nuw 1) to (X + -1) means that the combinations 50730b57cec5SDimitry Andric // wouldn't happen even if they were implemented. 50740b57cec5SDimitry Andric // 50758bcb0991SDimitry Andric // icmp ult (A - 1), Op1 -> icmp ule A, Op1 50768bcb0991SDimitry Andric // icmp uge (A - 1), Op1 -> icmp ugt A, Op1 50778bcb0991SDimitry Andric // icmp ugt Op0, (C - 1) -> icmp uge Op0, C 50788bcb0991SDimitry Andric // icmp ule Op0, (C - 1) -> icmp ult Op0, C 50790b57cec5SDimitry Andric 50808bcb0991SDimitry Andric // icmp ule (A + 1), Op0 -> icmp ult A, Op1 50810b57cec5SDimitry Andric if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_ULE && match(B, m_One())) 50820b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_ULT, A, Op1); 50830b57cec5SDimitry Andric 50848bcb0991SDimitry Andric // icmp ugt (A + 1), Op0 -> icmp uge A, Op1 50850b57cec5SDimitry Andric if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_UGT && match(B, m_One())) 50860b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_UGE, A, Op1); 50870b57cec5SDimitry Andric 50888bcb0991SDimitry Andric // icmp uge Op0, (C + 1) -> icmp ugt Op0, C 50890b57cec5SDimitry Andric if (C && NoOp1WrapProblem && Pred == CmpInst::ICMP_UGE && match(D, m_One())) 50900b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_UGT, Op0, C); 50910b57cec5SDimitry Andric 50928bcb0991SDimitry Andric // icmp ult Op0, (C + 1) -> icmp ule Op0, C 50930b57cec5SDimitry Andric if (C && NoOp1WrapProblem && Pred == CmpInst::ICMP_ULT && match(D, m_One())) 50940b57cec5SDimitry Andric return new ICmpInst(CmpInst::ICMP_ULE, Op0, C); 50950b57cec5SDimitry Andric 50960b57cec5SDimitry Andric // if C1 has greater magnitude than C2: 50978bcb0991SDimitry Andric // icmp (A + C1), (C + C2) -> icmp (A + C3), C 50980b57cec5SDimitry Andric // s.t. C3 = C1 - C2 50990b57cec5SDimitry Andric // 51000b57cec5SDimitry Andric // if C2 has greater magnitude than C1: 51018bcb0991SDimitry Andric // icmp (A + C1), (C + C2) -> icmp A, (C + C3) 51020b57cec5SDimitry Andric // s.t. C3 = C2 - C1 51030b57cec5SDimitry Andric if (A && C && NoOp0WrapProblem && NoOp1WrapProblem && 510481ad6265SDimitry Andric (BO0->hasOneUse() || BO1->hasOneUse()) && !I.isUnsigned()) { 510581ad6265SDimitry Andric const APInt *AP1, *AP2; 510681ad6265SDimitry Andric // TODO: Support non-uniform vectors. 5107*0fca6ea1SDimitry Andric // TODO: Allow poison passthrough if B or D's element is poison. 5108*0fca6ea1SDimitry Andric if (match(B, m_APIntAllowPoison(AP1)) && 5109*0fca6ea1SDimitry Andric match(D, m_APIntAllowPoison(AP2)) && 511081ad6265SDimitry Andric AP1->isNegative() == AP2->isNegative()) { 511181ad6265SDimitry Andric APInt AP1Abs = AP1->abs(); 511281ad6265SDimitry Andric APInt AP2Abs = AP2->abs(); 51130b57cec5SDimitry Andric if (AP1Abs.uge(AP2Abs)) { 511481ad6265SDimitry Andric APInt Diff = *AP1 - *AP2; 511581ad6265SDimitry Andric Constant *C3 = Constant::getIntegerValue(BO0->getType(), Diff); 5116647cbc5dSDimitry Andric Value *NewAdd = Builder.CreateAdd( 5117647cbc5dSDimitry Andric A, C3, "", Op0HasNUW && Diff.ule(*AP1), Op0HasNSW); 51180b57cec5SDimitry Andric return new ICmpInst(Pred, NewAdd, C); 51190b57cec5SDimitry Andric } else { 512081ad6265SDimitry Andric APInt Diff = *AP2 - *AP1; 512181ad6265SDimitry Andric Constant *C3 = Constant::getIntegerValue(BO0->getType(), Diff); 5122647cbc5dSDimitry Andric Value *NewAdd = Builder.CreateAdd( 5123647cbc5dSDimitry Andric C, C3, "", Op1HasNUW && Diff.ule(*AP2), Op1HasNSW); 51240b57cec5SDimitry Andric return new ICmpInst(Pred, A, NewAdd); 51250b57cec5SDimitry Andric } 51260b57cec5SDimitry Andric } 512781ad6265SDimitry Andric Constant *Cst1, *Cst2; 512881ad6265SDimitry Andric if (match(B, m_ImmConstant(Cst1)) && match(D, m_ImmConstant(Cst2)) && 512981ad6265SDimitry Andric ICmpInst::isEquality(Pred)) { 513081ad6265SDimitry Andric Constant *Diff = ConstantExpr::getSub(Cst2, Cst1); 513181ad6265SDimitry Andric Value *NewAdd = Builder.CreateAdd(C, Diff); 513281ad6265SDimitry Andric return new ICmpInst(Pred, A, NewAdd); 513381ad6265SDimitry Andric } 51340b57cec5SDimitry Andric } 51350b57cec5SDimitry Andric 51360b57cec5SDimitry Andric // Analyze the case when either Op0 or Op1 is a sub instruction. 51370b57cec5SDimitry Andric // Op0 = A - B (or A and B are null); Op1 = C - D (or C and D are null). 51380b57cec5SDimitry Andric A = nullptr; 51390b57cec5SDimitry Andric B = nullptr; 51400b57cec5SDimitry Andric C = nullptr; 51410b57cec5SDimitry Andric D = nullptr; 51420b57cec5SDimitry Andric if (BO0 && BO0->getOpcode() == Instruction::Sub) { 51430b57cec5SDimitry Andric A = BO0->getOperand(0); 51440b57cec5SDimitry Andric B = BO0->getOperand(1); 51450b57cec5SDimitry Andric } 51460b57cec5SDimitry Andric if (BO1 && BO1->getOpcode() == Instruction::Sub) { 51470b57cec5SDimitry Andric C = BO1->getOperand(0); 51480b57cec5SDimitry Andric D = BO1->getOperand(1); 51490b57cec5SDimitry Andric } 51500b57cec5SDimitry Andric 51518bcb0991SDimitry Andric // icmp (A-B), A -> icmp 0, B for equalities or if there is no overflow. 51520b57cec5SDimitry Andric if (A == Op1 && NoOp0WrapProblem) 51530b57cec5SDimitry Andric return new ICmpInst(Pred, Constant::getNullValue(Op1->getType()), B); 51548bcb0991SDimitry Andric // icmp C, (C-D) -> icmp D, 0 for equalities or if there is no overflow. 51550b57cec5SDimitry Andric if (C == Op0 && NoOp1WrapProblem) 51560b57cec5SDimitry Andric return new ICmpInst(Pred, D, Constant::getNullValue(Op0->getType())); 51570b57cec5SDimitry Andric 51588bcb0991SDimitry Andric // Convert sub-with-unsigned-overflow comparisons into a comparison of args. 51598bcb0991SDimitry Andric // (A - B) u>/u<= A --> B u>/u<= A 51608bcb0991SDimitry Andric if (A == Op1 && (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE)) 51618bcb0991SDimitry Andric return new ICmpInst(Pred, B, A); 51628bcb0991SDimitry Andric // C u</u>= (C - D) --> C u</u>= D 51638bcb0991SDimitry Andric if (C == Op0 && (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)) 51648bcb0991SDimitry Andric return new ICmpInst(Pred, C, D); 51658bcb0991SDimitry Andric // (A - B) u>=/u< A --> B u>/u<= A iff B != 0 51668bcb0991SDimitry Andric if (A == Op1 && (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_ULT) && 5167*0fca6ea1SDimitry Andric isKnownNonZero(B, Q)) 51688bcb0991SDimitry Andric return new ICmpInst(CmpInst::getFlippedStrictnessPredicate(Pred), B, A); 51698bcb0991SDimitry Andric // C u<=/u> (C - D) --> C u</u>= D iff B != 0 51708bcb0991SDimitry Andric if (C == Op0 && (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_UGT) && 5171*0fca6ea1SDimitry Andric isKnownNonZero(D, Q)) 51728bcb0991SDimitry Andric return new ICmpInst(CmpInst::getFlippedStrictnessPredicate(Pred), C, D); 51730b57cec5SDimitry Andric 51748bcb0991SDimitry Andric // icmp (A-B), (C-B) -> icmp A, C for equalities or if there is no overflow. 51758bcb0991SDimitry Andric if (B && D && B == D && NoOp0WrapProblem && NoOp1WrapProblem) 51760b57cec5SDimitry Andric return new ICmpInst(Pred, A, C); 51778bcb0991SDimitry Andric 51788bcb0991SDimitry Andric // icmp (A-B), (A-D) -> icmp D, B for equalities or if there is no overflow. 51798bcb0991SDimitry Andric if (A && C && A == C && NoOp0WrapProblem && NoOp1WrapProblem) 51800b57cec5SDimitry Andric return new ICmpInst(Pred, D, B); 51810b57cec5SDimitry Andric 51820b57cec5SDimitry Andric // icmp (0-X) < cst --> x > -cst 51830b57cec5SDimitry Andric if (NoOp0WrapProblem && ICmpInst::isSigned(Pred)) { 51840b57cec5SDimitry Andric Value *X; 51850b57cec5SDimitry Andric if (match(BO0, m_Neg(m_Value(X)))) 51860b57cec5SDimitry Andric if (Constant *RHSC = dyn_cast<Constant>(Op1)) 51870b57cec5SDimitry Andric if (RHSC->isNotMinSignedValue()) 51880b57cec5SDimitry Andric return new ICmpInst(I.getSwappedPredicate(), X, 51890b57cec5SDimitry Andric ConstantExpr::getNeg(RHSC)); 51900b57cec5SDimitry Andric } 51910b57cec5SDimitry Andric 519206c3fb27SDimitry Andric if (Instruction * R = foldICmpXorXX(I, Q, *this)) 519306c3fb27SDimitry Andric return R; 51945f757f3fSDimitry Andric if (Instruction *R = foldICmpOrXX(I, Q, *this)) 51955f757f3fSDimitry Andric return R; 519606c3fb27SDimitry Andric 5197e8d8bef9SDimitry Andric { 519806c3fb27SDimitry Andric // Try to remove shared multiplier from comparison: 519906c3fb27SDimitry Andric // X * Z u{lt/le/gt/ge}/eq/ne Y * Z 520006c3fb27SDimitry Andric Value *X, *Y, *Z; 520106c3fb27SDimitry Andric if (Pred == ICmpInst::getUnsignedPredicate(Pred) && 520206c3fb27SDimitry Andric ((match(Op0, m_Mul(m_Value(X), m_Value(Z))) && 520306c3fb27SDimitry Andric match(Op1, m_c_Mul(m_Specific(Z), m_Value(Y)))) || 520406c3fb27SDimitry Andric (match(Op0, m_Mul(m_Value(Z), m_Value(X))) && 520506c3fb27SDimitry Andric match(Op1, m_c_Mul(m_Specific(Z), m_Value(Y)))))) { 520606c3fb27SDimitry Andric bool NonZero; 520706c3fb27SDimitry Andric if (ICmpInst::isEquality(Pred)) { 520806c3fb27SDimitry Andric KnownBits ZKnown = computeKnownBits(Z, 0, &I); 520906c3fb27SDimitry Andric // if Z % 2 != 0 521006c3fb27SDimitry Andric // X * Z eq/ne Y * Z -> X eq/ne Y 521106c3fb27SDimitry Andric if (ZKnown.countMaxTrailingZeros() == 0) 5212e8d8bef9SDimitry Andric return new ICmpInst(Pred, X, Y); 5213*0fca6ea1SDimitry Andric NonZero = !ZKnown.One.isZero() || isKnownNonZero(Z, Q); 521406c3fb27SDimitry Andric // if Z != 0 and nsw(X * Z) and nsw(Y * Z) 521506c3fb27SDimitry Andric // X * Z eq/ne Y * Z -> X eq/ne Y 5216647cbc5dSDimitry Andric if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW) 521706c3fb27SDimitry Andric return new ICmpInst(Pred, X, Y); 521806c3fb27SDimitry Andric } else 5219*0fca6ea1SDimitry Andric NonZero = isKnownNonZero(Z, Q); 522006c3fb27SDimitry Andric 522106c3fb27SDimitry Andric // If Z != 0 and nuw(X * Z) and nuw(Y * Z) 522206c3fb27SDimitry Andric // X * Z u{lt/le/gt/ge}/eq/ne Y * Z -> X u{lt/le/gt/ge}/eq/ne Y 5223647cbc5dSDimitry Andric if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW) 522406c3fb27SDimitry Andric return new ICmpInst(Pred, X, Y); 522506c3fb27SDimitry Andric } 5226e8d8bef9SDimitry Andric } 5227e8d8bef9SDimitry Andric 52280b57cec5SDimitry Andric BinaryOperator *SRem = nullptr; 52290b57cec5SDimitry Andric // icmp (srem X, Y), Y 52300b57cec5SDimitry Andric if (BO0 && BO0->getOpcode() == Instruction::SRem && Op1 == BO0->getOperand(1)) 52310b57cec5SDimitry Andric SRem = BO0; 52320b57cec5SDimitry Andric // icmp Y, (srem X, Y) 52330b57cec5SDimitry Andric else if (BO1 && BO1->getOpcode() == Instruction::SRem && 52340b57cec5SDimitry Andric Op0 == BO1->getOperand(1)) 52350b57cec5SDimitry Andric SRem = BO1; 52360b57cec5SDimitry Andric if (SRem) { 52370b57cec5SDimitry Andric // We don't check hasOneUse to avoid increasing register pressure because 52380b57cec5SDimitry Andric // the value we use is the same value this instruction was already using. 52390b57cec5SDimitry Andric switch (SRem == BO0 ? ICmpInst::getSwappedPredicate(Pred) : Pred) { 52400b57cec5SDimitry Andric default: 52410b57cec5SDimitry Andric break; 52420b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: 52430b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 52440b57cec5SDimitry Andric case ICmpInst::ICMP_NE: 52450b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 52460b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: 52470b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: 52480b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, SRem->getOperand(1), 52490b57cec5SDimitry Andric Constant::getAllOnesValue(SRem->getType())); 52500b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: 52510b57cec5SDimitry Andric case ICmpInst::ICMP_SLE: 52520b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, SRem->getOperand(1), 52530b57cec5SDimitry Andric Constant::getNullValue(SRem->getType())); 52540b57cec5SDimitry Andric } 52550b57cec5SDimitry Andric } 52560b57cec5SDimitry Andric 52571db9f3b2SDimitry Andric if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() && 52581db9f3b2SDimitry Andric (BO0->hasOneUse() || BO1->hasOneUse()) && 52591db9f3b2SDimitry Andric BO0->getOperand(1) == BO1->getOperand(1)) { 52600b57cec5SDimitry Andric switch (BO0->getOpcode()) { 52610b57cec5SDimitry Andric default: 52620b57cec5SDimitry Andric break; 52630b57cec5SDimitry Andric case Instruction::Add: 52640b57cec5SDimitry Andric case Instruction::Sub: 52650b57cec5SDimitry Andric case Instruction::Xor: { 52660b57cec5SDimitry Andric if (I.isEquality()) // a+x icmp eq/ne b+x --> a icmp b 52670b57cec5SDimitry Andric return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); 52680b57cec5SDimitry Andric 52690b57cec5SDimitry Andric const APInt *C; 52700b57cec5SDimitry Andric if (match(BO0->getOperand(1), m_APInt(C))) { 52710b57cec5SDimitry Andric // icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b 52720b57cec5SDimitry Andric if (C->isSignMask()) { 5273e8d8bef9SDimitry Andric ICmpInst::Predicate NewPred = I.getFlippedSignednessPredicate(); 52740b57cec5SDimitry Andric return new ICmpInst(NewPred, BO0->getOperand(0), BO1->getOperand(0)); 52750b57cec5SDimitry Andric } 52760b57cec5SDimitry Andric 52770b57cec5SDimitry Andric // icmp u/s (a ^ maxsignval), (b ^ maxsignval) --> icmp s/u' a, b 52780b57cec5SDimitry Andric if (BO0->getOpcode() == Instruction::Xor && C->isMaxSignedValue()) { 5279e8d8bef9SDimitry Andric ICmpInst::Predicate NewPred = I.getFlippedSignednessPredicate(); 52800b57cec5SDimitry Andric NewPred = I.getSwappedPredicate(NewPred); 52810b57cec5SDimitry Andric return new ICmpInst(NewPred, BO0->getOperand(0), BO1->getOperand(0)); 52820b57cec5SDimitry Andric } 52830b57cec5SDimitry Andric } 52840b57cec5SDimitry Andric break; 52850b57cec5SDimitry Andric } 52860b57cec5SDimitry Andric case Instruction::Mul: { 52870b57cec5SDimitry Andric if (!I.isEquality()) 52880b57cec5SDimitry Andric break; 52890b57cec5SDimitry Andric 52900b57cec5SDimitry Andric const APInt *C; 5291349cc55cSDimitry Andric if (match(BO0->getOperand(1), m_APInt(C)) && !C->isZero() && 5292349cc55cSDimitry Andric !C->isOne()) { 52930b57cec5SDimitry Andric // icmp eq/ne (X * C), (Y * C) --> icmp (X & Mask), (Y & Mask) 52940b57cec5SDimitry Andric // Mask = -1 >> count-trailing-zeros(C). 529506c3fb27SDimitry Andric if (unsigned TZs = C->countr_zero()) { 52960b57cec5SDimitry Andric Constant *Mask = ConstantInt::get( 52970b57cec5SDimitry Andric BO0->getType(), 52980b57cec5SDimitry Andric APInt::getLowBitsSet(C->getBitWidth(), C->getBitWidth() - TZs)); 52990b57cec5SDimitry Andric Value *And1 = Builder.CreateAnd(BO0->getOperand(0), Mask); 53000b57cec5SDimitry Andric Value *And2 = Builder.CreateAnd(BO1->getOperand(0), Mask); 53010b57cec5SDimitry Andric return new ICmpInst(Pred, And1, And2); 53020b57cec5SDimitry Andric } 53030b57cec5SDimitry Andric } 53040b57cec5SDimitry Andric break; 53050b57cec5SDimitry Andric } 53060b57cec5SDimitry Andric case Instruction::UDiv: 53070b57cec5SDimitry Andric case Instruction::LShr: 53080b57cec5SDimitry Andric if (I.isSigned() || !BO0->isExact() || !BO1->isExact()) 53090b57cec5SDimitry Andric break; 53100b57cec5SDimitry Andric return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); 53110b57cec5SDimitry Andric 53120b57cec5SDimitry Andric case Instruction::SDiv: 5313647cbc5dSDimitry Andric if (!(I.isEquality() || match(BO0->getOperand(1), m_NonNegative())) || 5314647cbc5dSDimitry Andric !BO0->isExact() || !BO1->isExact()) 53150b57cec5SDimitry Andric break; 53160b57cec5SDimitry Andric return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); 53170b57cec5SDimitry Andric 53180b57cec5SDimitry Andric case Instruction::AShr: 53190b57cec5SDimitry Andric if (!BO0->isExact() || !BO1->isExact()) 53200b57cec5SDimitry Andric break; 53210b57cec5SDimitry Andric return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); 53220b57cec5SDimitry Andric 53230b57cec5SDimitry Andric case Instruction::Shl: { 5324647cbc5dSDimitry Andric bool NUW = Op0HasNUW && Op1HasNUW; 5325647cbc5dSDimitry Andric bool NSW = Op0HasNSW && Op1HasNSW; 53260b57cec5SDimitry Andric if (!NUW && !NSW) 53270b57cec5SDimitry Andric break; 53280b57cec5SDimitry Andric if (!NSW && I.isSigned()) 53290b57cec5SDimitry Andric break; 53300b57cec5SDimitry Andric return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); 53310b57cec5SDimitry Andric } 53320b57cec5SDimitry Andric } 53330b57cec5SDimitry Andric } 53340b57cec5SDimitry Andric 53350b57cec5SDimitry Andric if (BO0) { 53360b57cec5SDimitry Andric // Transform A & (L - 1) `ult` L --> L != 0 53370b57cec5SDimitry Andric auto LSubOne = m_Add(m_Specific(Op1), m_AllOnes()); 53380b57cec5SDimitry Andric auto BitwiseAnd = m_c_And(m_Value(), LSubOne); 53390b57cec5SDimitry Andric 53400b57cec5SDimitry Andric if (match(BO0, BitwiseAnd) && Pred == ICmpInst::ICMP_ULT) { 53410b57cec5SDimitry Andric auto *Zero = Constant::getNullValue(BO0->getType()); 53420b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op1, Zero); 53430b57cec5SDimitry Andric } 53440b57cec5SDimitry Andric } 53450b57cec5SDimitry Andric 5346bdd1243dSDimitry Andric // For unsigned predicates / eq / ne: 5347bdd1243dSDimitry Andric // icmp pred (x << 1), x --> icmp getSignedPredicate(pred) x, 0 5348bdd1243dSDimitry Andric // icmp pred x, (x << 1) --> icmp getSignedPredicate(pred) 0, x 5349bdd1243dSDimitry Andric if (!ICmpInst::isSigned(Pred)) { 5350bdd1243dSDimitry Andric if (match(Op0, m_Shl(m_Specific(Op1), m_One()))) 5351bdd1243dSDimitry Andric return new ICmpInst(ICmpInst::getSignedPredicate(Pred), Op1, 5352bdd1243dSDimitry Andric Constant::getNullValue(Op1->getType())); 5353bdd1243dSDimitry Andric else if (match(Op1, m_Shl(m_Specific(Op0), m_One()))) 5354bdd1243dSDimitry Andric return new ICmpInst(ICmpInst::getSignedPredicate(Pred), 5355bdd1243dSDimitry Andric Constant::getNullValue(Op0->getType()), Op0); 5356bdd1243dSDimitry Andric } 5357bdd1243dSDimitry Andric 5358349cc55cSDimitry Andric if (Value *V = foldMultiplicationOverflowCheck(I)) 53598bcb0991SDimitry Andric return replaceInstUsesWith(I, V); 53608bcb0991SDimitry Andric 53615f757f3fSDimitry Andric if (Instruction *R = foldICmpAndXX(I, Q, *this)) 53625f757f3fSDimitry Andric return R; 53635f757f3fSDimitry Andric 53640b57cec5SDimitry Andric if (Value *V = foldICmpWithTruncSignExtendedVal(I, Builder)) 53650b57cec5SDimitry Andric return replaceInstUsesWith(I, V); 53660b57cec5SDimitry Andric 53670b57cec5SDimitry Andric if (Value *V = foldShiftIntoShiftInAnotherHandOfAndInICmp(I, SQ, Builder)) 53680b57cec5SDimitry Andric return replaceInstUsesWith(I, V); 53690b57cec5SDimitry Andric 53700b57cec5SDimitry Andric return nullptr; 53710b57cec5SDimitry Andric } 53720b57cec5SDimitry Andric 53735f757f3fSDimitry Andric /// Fold icmp Pred min|max(X, Y), Z. 5374647cbc5dSDimitry Andric Instruction *InstCombinerImpl::foldICmpWithMinMax(Instruction &I, 5375647cbc5dSDimitry Andric MinMaxIntrinsic *MinMax, 5376647cbc5dSDimitry Andric Value *Z, 53775f757f3fSDimitry Andric ICmpInst::Predicate Pred) { 53785f757f3fSDimitry Andric Value *X = MinMax->getLHS(); 53795f757f3fSDimitry Andric Value *Y = MinMax->getRHS(); 53805f757f3fSDimitry Andric if (ICmpInst::isSigned(Pred) && !MinMax->isSigned()) 53815f757f3fSDimitry Andric return nullptr; 53821db9f3b2SDimitry Andric if (ICmpInst::isUnsigned(Pred) && MinMax->isSigned()) { 53831db9f3b2SDimitry Andric // Revert the transform signed pred -> unsigned pred 53841db9f3b2SDimitry Andric // TODO: We can flip the signedness of predicate if both operands of icmp 53851db9f3b2SDimitry Andric // are negative. 53861db9f3b2SDimitry Andric if (isKnownNonNegative(Z, SQ.getWithInstruction(&I)) && 53871db9f3b2SDimitry Andric isKnownNonNegative(MinMax, SQ.getWithInstruction(&I))) { 53881db9f3b2SDimitry Andric Pred = ICmpInst::getFlippedSignednessPredicate(Pred); 53891db9f3b2SDimitry Andric } else 53905f757f3fSDimitry Andric return nullptr; 53911db9f3b2SDimitry Andric } 53925f757f3fSDimitry Andric SimplifyQuery Q = SQ.getWithInstruction(&I); 53935f757f3fSDimitry Andric auto IsCondKnownTrue = [](Value *Val) -> std::optional<bool> { 53945f757f3fSDimitry Andric if (!Val) 53955f757f3fSDimitry Andric return std::nullopt; 53965f757f3fSDimitry Andric if (match(Val, m_One())) 53975f757f3fSDimitry Andric return true; 53985f757f3fSDimitry Andric if (match(Val, m_Zero())) 53995f757f3fSDimitry Andric return false; 54005f757f3fSDimitry Andric return std::nullopt; 54015f757f3fSDimitry Andric }; 54025f757f3fSDimitry Andric auto CmpXZ = IsCondKnownTrue(simplifyICmpInst(Pred, X, Z, Q)); 54035f757f3fSDimitry Andric auto CmpYZ = IsCondKnownTrue(simplifyICmpInst(Pred, Y, Z, Q)); 54045f757f3fSDimitry Andric if (!CmpXZ.has_value() && !CmpYZ.has_value()) 54055f757f3fSDimitry Andric return nullptr; 54065f757f3fSDimitry Andric if (!CmpXZ.has_value()) { 54075f757f3fSDimitry Andric std::swap(X, Y); 54085f757f3fSDimitry Andric std::swap(CmpXZ, CmpYZ); 54095f757f3fSDimitry Andric } 54105f757f3fSDimitry Andric 54115f757f3fSDimitry Andric auto FoldIntoCmpYZ = [&]() -> Instruction * { 54125f757f3fSDimitry Andric if (CmpYZ.has_value()) 54135f757f3fSDimitry Andric return replaceInstUsesWith(I, ConstantInt::getBool(I.getType(), *CmpYZ)); 54145f757f3fSDimitry Andric return ICmpInst::Create(Instruction::ICmp, Pred, Y, Z); 54155f757f3fSDimitry Andric }; 54165f757f3fSDimitry Andric 54175f757f3fSDimitry Andric switch (Pred) { 54185f757f3fSDimitry Andric case ICmpInst::ICMP_EQ: 54195f757f3fSDimitry Andric case ICmpInst::ICMP_NE: { 54205f757f3fSDimitry Andric // If X == Z: 54215f757f3fSDimitry Andric // Expr Result 54225f757f3fSDimitry Andric // min(X, Y) == Z X <= Y 54235f757f3fSDimitry Andric // max(X, Y) == Z X >= Y 54245f757f3fSDimitry Andric // min(X, Y) != Z X > Y 54255f757f3fSDimitry Andric // max(X, Y) != Z X < Y 54265f757f3fSDimitry Andric if ((Pred == ICmpInst::ICMP_EQ) == *CmpXZ) { 54275f757f3fSDimitry Andric ICmpInst::Predicate NewPred = 54285f757f3fSDimitry Andric ICmpInst::getNonStrictPredicate(MinMax->getPredicate()); 54295f757f3fSDimitry Andric if (Pred == ICmpInst::ICMP_NE) 54305f757f3fSDimitry Andric NewPred = ICmpInst::getInversePredicate(NewPred); 54315f757f3fSDimitry Andric return ICmpInst::Create(Instruction::ICmp, NewPred, X, Y); 54325f757f3fSDimitry Andric } 54335f757f3fSDimitry Andric // Otherwise (X != Z): 54345f757f3fSDimitry Andric ICmpInst::Predicate NewPred = MinMax->getPredicate(); 54355f757f3fSDimitry Andric auto MinMaxCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q)); 54365f757f3fSDimitry Andric if (!MinMaxCmpXZ.has_value()) { 54375f757f3fSDimitry Andric std::swap(X, Y); 54385f757f3fSDimitry Andric std::swap(CmpXZ, CmpYZ); 54395f757f3fSDimitry Andric // Re-check pre-condition X != Z 54405f757f3fSDimitry Andric if (!CmpXZ.has_value() || (Pred == ICmpInst::ICMP_EQ) == *CmpXZ) 54415f757f3fSDimitry Andric break; 54425f757f3fSDimitry Andric MinMaxCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q)); 54435f757f3fSDimitry Andric } 54445f757f3fSDimitry Andric if (!MinMaxCmpXZ.has_value()) 54455f757f3fSDimitry Andric break; 54465f757f3fSDimitry Andric if (*MinMaxCmpXZ) { 54475f757f3fSDimitry Andric // Expr Fact Result 54485f757f3fSDimitry Andric // min(X, Y) == Z X < Z false 54495f757f3fSDimitry Andric // max(X, Y) == Z X > Z false 54505f757f3fSDimitry Andric // min(X, Y) != Z X < Z true 54515f757f3fSDimitry Andric // max(X, Y) != Z X > Z true 54525f757f3fSDimitry Andric return replaceInstUsesWith( 54535f757f3fSDimitry Andric I, ConstantInt::getBool(I.getType(), Pred == ICmpInst::ICMP_NE)); 54545f757f3fSDimitry Andric } else { 54555f757f3fSDimitry Andric // Expr Fact Result 54565f757f3fSDimitry Andric // min(X, Y) == Z X > Z Y == Z 54575f757f3fSDimitry Andric // max(X, Y) == Z X < Z Y == Z 54585f757f3fSDimitry Andric // min(X, Y) != Z X > Z Y != Z 54595f757f3fSDimitry Andric // max(X, Y) != Z X < Z Y != Z 54605f757f3fSDimitry Andric return FoldIntoCmpYZ(); 54615f757f3fSDimitry Andric } 54625f757f3fSDimitry Andric break; 54635f757f3fSDimitry Andric } 54645f757f3fSDimitry Andric case ICmpInst::ICMP_SLT: 54655f757f3fSDimitry Andric case ICmpInst::ICMP_ULT: 54665f757f3fSDimitry Andric case ICmpInst::ICMP_SLE: 54675f757f3fSDimitry Andric case ICmpInst::ICMP_ULE: 54685f757f3fSDimitry Andric case ICmpInst::ICMP_SGT: 54695f757f3fSDimitry Andric case ICmpInst::ICMP_UGT: 54705f757f3fSDimitry Andric case ICmpInst::ICMP_SGE: 54715f757f3fSDimitry Andric case ICmpInst::ICMP_UGE: { 54725f757f3fSDimitry Andric bool IsSame = MinMax->getPredicate() == ICmpInst::getStrictPredicate(Pred); 54735f757f3fSDimitry Andric if (*CmpXZ) { 54745f757f3fSDimitry Andric if (IsSame) { 54755f757f3fSDimitry Andric // Expr Fact Result 54765f757f3fSDimitry Andric // min(X, Y) < Z X < Z true 54775f757f3fSDimitry Andric // min(X, Y) <= Z X <= Z true 54785f757f3fSDimitry Andric // max(X, Y) > Z X > Z true 54795f757f3fSDimitry Andric // max(X, Y) >= Z X >= Z true 54805f757f3fSDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 54815f757f3fSDimitry Andric } else { 54825f757f3fSDimitry Andric // Expr Fact Result 54835f757f3fSDimitry Andric // max(X, Y) < Z X < Z Y < Z 54845f757f3fSDimitry Andric // max(X, Y) <= Z X <= Z Y <= Z 54855f757f3fSDimitry Andric // min(X, Y) > Z X > Z Y > Z 54865f757f3fSDimitry Andric // min(X, Y) >= Z X >= Z Y >= Z 54875f757f3fSDimitry Andric return FoldIntoCmpYZ(); 54885f757f3fSDimitry Andric } 54895f757f3fSDimitry Andric } else { 54905f757f3fSDimitry Andric if (IsSame) { 54915f757f3fSDimitry Andric // Expr Fact Result 54925f757f3fSDimitry Andric // min(X, Y) < Z X >= Z Y < Z 54935f757f3fSDimitry Andric // min(X, Y) <= Z X > Z Y <= Z 54945f757f3fSDimitry Andric // max(X, Y) > Z X <= Z Y > Z 54955f757f3fSDimitry Andric // max(X, Y) >= Z X < Z Y >= Z 54965f757f3fSDimitry Andric return FoldIntoCmpYZ(); 54975f757f3fSDimitry Andric } else { 54985f757f3fSDimitry Andric // Expr Fact Result 54995f757f3fSDimitry Andric // max(X, Y) < Z X >= Z false 55005f757f3fSDimitry Andric // max(X, Y) <= Z X > Z false 55015f757f3fSDimitry Andric // min(X, Y) > Z X <= Z false 55025f757f3fSDimitry Andric // min(X, Y) >= Z X < Z false 55035f757f3fSDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 55045f757f3fSDimitry Andric } 55055f757f3fSDimitry Andric } 55065f757f3fSDimitry Andric break; 55075f757f3fSDimitry Andric } 55085f757f3fSDimitry Andric default: 55095f757f3fSDimitry Andric break; 55105f757f3fSDimitry Andric } 55115f757f3fSDimitry Andric 55125f757f3fSDimitry Andric return nullptr; 55135f757f3fSDimitry Andric } 55140b57cec5SDimitry Andric 551506c3fb27SDimitry Andric // Canonicalize checking for a power-of-2-or-zero value: 551606c3fb27SDimitry Andric static Instruction *foldICmpPow2Test(ICmpInst &I, 551706c3fb27SDimitry Andric InstCombiner::BuilderTy &Builder) { 551806c3fb27SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 551906c3fb27SDimitry Andric const CmpInst::Predicate Pred = I.getPredicate(); 552006c3fb27SDimitry Andric Value *A = nullptr; 552106c3fb27SDimitry Andric bool CheckIs; 552206c3fb27SDimitry Andric if (I.isEquality()) { 552306c3fb27SDimitry Andric // (A & (A-1)) == 0 --> ctpop(A) < 2 (two commuted variants) 552406c3fb27SDimitry Andric // ((A-1) & A) != 0 --> ctpop(A) > 1 (two commuted variants) 552506c3fb27SDimitry Andric if (!match(Op0, m_OneUse(m_c_And(m_Add(m_Value(A), m_AllOnes()), 552606c3fb27SDimitry Andric m_Deferred(A)))) || 552706c3fb27SDimitry Andric !match(Op1, m_ZeroInt())) 552806c3fb27SDimitry Andric A = nullptr; 552906c3fb27SDimitry Andric 553006c3fb27SDimitry Andric // (A & -A) == A --> ctpop(A) < 2 (four commuted variants) 553106c3fb27SDimitry Andric // (-A & A) != A --> ctpop(A) > 1 (four commuted variants) 553206c3fb27SDimitry Andric if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Specific(Op1)), m_Specific(Op1))))) 553306c3fb27SDimitry Andric A = Op1; 553406c3fb27SDimitry Andric else if (match(Op1, 553506c3fb27SDimitry Andric m_OneUse(m_c_And(m_Neg(m_Specific(Op0)), m_Specific(Op0))))) 553606c3fb27SDimitry Andric A = Op0; 553706c3fb27SDimitry Andric 553806c3fb27SDimitry Andric CheckIs = Pred == ICmpInst::ICMP_EQ; 553906c3fb27SDimitry Andric } else if (ICmpInst::isUnsigned(Pred)) { 554006c3fb27SDimitry Andric // (A ^ (A-1)) u>= A --> ctpop(A) < 2 (two commuted variants) 554106c3fb27SDimitry Andric // ((A-1) ^ A) u< A --> ctpop(A) > 1 (two commuted variants) 554206c3fb27SDimitry Andric 554306c3fb27SDimitry Andric if ((Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_ULT) && 554406c3fb27SDimitry Andric match(Op0, m_OneUse(m_c_Xor(m_Add(m_Specific(Op1), m_AllOnes()), 554506c3fb27SDimitry Andric m_Specific(Op1))))) { 554606c3fb27SDimitry Andric A = Op1; 554706c3fb27SDimitry Andric CheckIs = Pred == ICmpInst::ICMP_UGE; 554806c3fb27SDimitry Andric } else if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE) && 554906c3fb27SDimitry Andric match(Op1, m_OneUse(m_c_Xor(m_Add(m_Specific(Op0), m_AllOnes()), 555006c3fb27SDimitry Andric m_Specific(Op0))))) { 555106c3fb27SDimitry Andric A = Op0; 555206c3fb27SDimitry Andric CheckIs = Pred == ICmpInst::ICMP_ULE; 555306c3fb27SDimitry Andric } 555406c3fb27SDimitry Andric } 555506c3fb27SDimitry Andric 555606c3fb27SDimitry Andric if (A) { 555706c3fb27SDimitry Andric Type *Ty = A->getType(); 555806c3fb27SDimitry Andric CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A); 555906c3fb27SDimitry Andric return CheckIs ? new ICmpInst(ICmpInst::ICMP_ULT, CtPop, 556006c3fb27SDimitry Andric ConstantInt::get(Ty, 2)) 556106c3fb27SDimitry Andric : new ICmpInst(ICmpInst::ICMP_UGT, CtPop, 556206c3fb27SDimitry Andric ConstantInt::get(Ty, 1)); 556306c3fb27SDimitry Andric } 556406c3fb27SDimitry Andric 556506c3fb27SDimitry Andric return nullptr; 556606c3fb27SDimitry Andric } 556706c3fb27SDimitry Andric 5568e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) { 55690b57cec5SDimitry Andric if (!I.isEquality()) 55700b57cec5SDimitry Andric return nullptr; 55710b57cec5SDimitry Andric 55720b57cec5SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 55730b57cec5SDimitry Andric const CmpInst::Predicate Pred = I.getPredicate(); 55740b57cec5SDimitry Andric Value *A, *B, *C, *D; 55750b57cec5SDimitry Andric if (match(Op0, m_Xor(m_Value(A), m_Value(B)))) { 55760b57cec5SDimitry Andric if (A == Op1 || B == Op1) { // (A^B) == A -> B == 0 55770b57cec5SDimitry Andric Value *OtherVal = A == Op1 ? B : A; 55780b57cec5SDimitry Andric return new ICmpInst(Pred, OtherVal, Constant::getNullValue(A->getType())); 55790b57cec5SDimitry Andric } 55800b57cec5SDimitry Andric 55810b57cec5SDimitry Andric if (match(Op1, m_Xor(m_Value(C), m_Value(D)))) { 55820b57cec5SDimitry Andric // A^c1 == C^c2 --> A == C^(c1^c2) 55830b57cec5SDimitry Andric ConstantInt *C1, *C2; 55840b57cec5SDimitry Andric if (match(B, m_ConstantInt(C1)) && match(D, m_ConstantInt(C2)) && 55850b57cec5SDimitry Andric Op1->hasOneUse()) { 55860b57cec5SDimitry Andric Constant *NC = Builder.getInt(C1->getValue() ^ C2->getValue()); 55870b57cec5SDimitry Andric Value *Xor = Builder.CreateXor(C, NC); 55880b57cec5SDimitry Andric return new ICmpInst(Pred, A, Xor); 55890b57cec5SDimitry Andric } 55900b57cec5SDimitry Andric 55910b57cec5SDimitry Andric // A^B == A^D -> B == D 55920b57cec5SDimitry Andric if (A == C) 55930b57cec5SDimitry Andric return new ICmpInst(Pred, B, D); 55940b57cec5SDimitry Andric if (A == D) 55950b57cec5SDimitry Andric return new ICmpInst(Pred, B, C); 55960b57cec5SDimitry Andric if (B == C) 55970b57cec5SDimitry Andric return new ICmpInst(Pred, A, D); 55980b57cec5SDimitry Andric if (B == D) 55990b57cec5SDimitry Andric return new ICmpInst(Pred, A, C); 56000b57cec5SDimitry Andric } 56010b57cec5SDimitry Andric } 56020b57cec5SDimitry Andric 56030b57cec5SDimitry Andric if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && (A == Op0 || B == Op0)) { 56040b57cec5SDimitry Andric // A == (A^B) -> B == 0 56050b57cec5SDimitry Andric Value *OtherVal = A == Op0 ? B : A; 56060b57cec5SDimitry Andric return new ICmpInst(Pred, OtherVal, Constant::getNullValue(A->getType())); 56070b57cec5SDimitry Andric } 56080b57cec5SDimitry Andric 56090b57cec5SDimitry Andric // (X&Z) == (Y&Z) -> (X^Y) & Z == 0 5610*0fca6ea1SDimitry Andric if (match(Op0, m_And(m_Value(A), m_Value(B))) && 5611*0fca6ea1SDimitry Andric match(Op1, m_And(m_Value(C), m_Value(D)))) { 56120b57cec5SDimitry Andric Value *X = nullptr, *Y = nullptr, *Z = nullptr; 56130b57cec5SDimitry Andric 56140b57cec5SDimitry Andric if (A == C) { 56150b57cec5SDimitry Andric X = B; 56160b57cec5SDimitry Andric Y = D; 56170b57cec5SDimitry Andric Z = A; 56180b57cec5SDimitry Andric } else if (A == D) { 56190b57cec5SDimitry Andric X = B; 56200b57cec5SDimitry Andric Y = C; 56210b57cec5SDimitry Andric Z = A; 56220b57cec5SDimitry Andric } else if (B == C) { 56230b57cec5SDimitry Andric X = A; 56240b57cec5SDimitry Andric Y = D; 56250b57cec5SDimitry Andric Z = B; 56260b57cec5SDimitry Andric } else if (B == D) { 56270b57cec5SDimitry Andric X = A; 56280b57cec5SDimitry Andric Y = C; 56290b57cec5SDimitry Andric Z = B; 56300b57cec5SDimitry Andric } 56310b57cec5SDimitry Andric 5632*0fca6ea1SDimitry Andric if (X) { 5633*0fca6ea1SDimitry Andric // If X^Y is a negative power of two, then `icmp eq/ne (Z & NegP2), 0` 5634*0fca6ea1SDimitry Andric // will fold to `icmp ult/uge Z, -NegP2` incurringb no additional 5635*0fca6ea1SDimitry Andric // instructions. 5636*0fca6ea1SDimitry Andric const APInt *C0, *C1; 5637*0fca6ea1SDimitry Andric bool XorIsNegP2 = match(X, m_APInt(C0)) && match(Y, m_APInt(C1)) && 5638*0fca6ea1SDimitry Andric (*C0 ^ *C1).isNegatedPowerOf2(); 5639*0fca6ea1SDimitry Andric 5640*0fca6ea1SDimitry Andric // If either Op0/Op1 are both one use or X^Y will constant fold and one of 5641*0fca6ea1SDimitry Andric // Op0/Op1 are one use, proceed. In those cases we are instruction neutral 5642*0fca6ea1SDimitry Andric // but `icmp eq/ne A, 0` is easier to analyze than `icmp eq/ne A, B`. 5643*0fca6ea1SDimitry Andric int UseCnt = 5644*0fca6ea1SDimitry Andric int(Op0->hasOneUse()) + int(Op1->hasOneUse()) + 5645*0fca6ea1SDimitry Andric (int(match(X, m_ImmConstant()) && match(Y, m_ImmConstant()))); 5646*0fca6ea1SDimitry Andric if (XorIsNegP2 || UseCnt >= 2) { 5647*0fca6ea1SDimitry Andric // Build (X^Y) & Z 56480b57cec5SDimitry Andric Op1 = Builder.CreateXor(X, Y); 56490b57cec5SDimitry Andric Op1 = Builder.CreateAnd(Op1, Z); 56505ffd83dbSDimitry Andric return new ICmpInst(Pred, Op1, Constant::getNullValue(Op1->getType())); 56510b57cec5SDimitry Andric } 56520b57cec5SDimitry Andric } 5653*0fca6ea1SDimitry Andric } 56540b57cec5SDimitry Andric 5655349cc55cSDimitry Andric { 5656349cc55cSDimitry Andric // Similar to above, but specialized for constant because invert is needed: 5657349cc55cSDimitry Andric // (X | C) == (Y | C) --> (X ^ Y) & ~C == 0 5658349cc55cSDimitry Andric Value *X, *Y; 5659349cc55cSDimitry Andric Constant *C; 5660349cc55cSDimitry Andric if (match(Op0, m_OneUse(m_Or(m_Value(X), m_Constant(C)))) && 5661349cc55cSDimitry Andric match(Op1, m_OneUse(m_Or(m_Value(Y), m_Specific(C))))) { 5662349cc55cSDimitry Andric Value *Xor = Builder.CreateXor(X, Y); 5663349cc55cSDimitry Andric Value *And = Builder.CreateAnd(Xor, ConstantExpr::getNot(C)); 5664349cc55cSDimitry Andric return new ICmpInst(Pred, And, Constant::getNullValue(And->getType())); 5665349cc55cSDimitry Andric } 5666349cc55cSDimitry Andric } 5667349cc55cSDimitry Andric 5668bdd1243dSDimitry Andric if (match(Op1, m_ZExt(m_Value(A))) && 5669bdd1243dSDimitry Andric (Op0->hasOneUse() || Op1->hasOneUse())) { 5670bdd1243dSDimitry Andric // (B & (Pow2C-1)) == zext A --> A == trunc B 5671bdd1243dSDimitry Andric // (B & (Pow2C-1)) != zext A --> A != trunc B 5672bdd1243dSDimitry Andric const APInt *MaskC; 5673bdd1243dSDimitry Andric if (match(Op0, m_And(m_Value(B), m_LowBitMask(MaskC))) && 567406c3fb27SDimitry Andric MaskC->countr_one() == A->getType()->getScalarSizeInBits()) 56750b57cec5SDimitry Andric return new ICmpInst(Pred, A, Builder.CreateTrunc(B, A->getType())); 567606c3fb27SDimitry Andric } 5677bdd1243dSDimitry Andric 56780b57cec5SDimitry Andric // (A >> C) == (B >> C) --> (A^B) u< (1 << C) 56790b57cec5SDimitry Andric // For lshr and ashr pairs. 568081ad6265SDimitry Andric const APInt *AP1, *AP2; 5681*0fca6ea1SDimitry Andric if ((match(Op0, m_OneUse(m_LShr(m_Value(A), m_APIntAllowPoison(AP1)))) && 5682*0fca6ea1SDimitry Andric match(Op1, m_OneUse(m_LShr(m_Value(B), m_APIntAllowPoison(AP2))))) || 5683*0fca6ea1SDimitry Andric (match(Op0, m_OneUse(m_AShr(m_Value(A), m_APIntAllowPoison(AP1)))) && 5684*0fca6ea1SDimitry Andric match(Op1, m_OneUse(m_AShr(m_Value(B), m_APIntAllowPoison(AP2)))))) { 568581ad6265SDimitry Andric if (AP1 != AP2) 568681ad6265SDimitry Andric return nullptr; 568781ad6265SDimitry Andric unsigned TypeBits = AP1->getBitWidth(); 568881ad6265SDimitry Andric unsigned ShAmt = AP1->getLimitedValue(TypeBits); 56890b57cec5SDimitry Andric if (ShAmt < TypeBits && ShAmt != 0) { 56900b57cec5SDimitry Andric ICmpInst::Predicate NewPred = 56910b57cec5SDimitry Andric Pred == ICmpInst::ICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; 56920b57cec5SDimitry Andric Value *Xor = Builder.CreateXor(A, B, I.getName() + ".unshifted"); 56930b57cec5SDimitry Andric APInt CmpVal = APInt::getOneBitSet(TypeBits, ShAmt); 569481ad6265SDimitry Andric return new ICmpInst(NewPred, Xor, ConstantInt::get(A->getType(), CmpVal)); 56950b57cec5SDimitry Andric } 56960b57cec5SDimitry Andric } 56970b57cec5SDimitry Andric 56980b57cec5SDimitry Andric // (A << C) == (B << C) --> ((A^B) & (~0U >> C)) == 0 5699bdd1243dSDimitry Andric ConstantInt *Cst1; 57000b57cec5SDimitry Andric if (match(Op0, m_OneUse(m_Shl(m_Value(A), m_ConstantInt(Cst1)))) && 57010b57cec5SDimitry Andric match(Op1, m_OneUse(m_Shl(m_Value(B), m_Specific(Cst1))))) { 57020b57cec5SDimitry Andric unsigned TypeBits = Cst1->getBitWidth(); 57030b57cec5SDimitry Andric unsigned ShAmt = (unsigned)Cst1->getLimitedValue(TypeBits); 57040b57cec5SDimitry Andric if (ShAmt < TypeBits && ShAmt != 0) { 57050b57cec5SDimitry Andric Value *Xor = Builder.CreateXor(A, B, I.getName() + ".unshifted"); 57060b57cec5SDimitry Andric APInt AndVal = APInt::getLowBitsSet(TypeBits, TypeBits - ShAmt); 57070b57cec5SDimitry Andric Value *And = Builder.CreateAnd(Xor, Builder.getInt(AndVal), 57080b57cec5SDimitry Andric I.getName() + ".mask"); 57090b57cec5SDimitry Andric return new ICmpInst(Pred, And, Constant::getNullValue(Cst1->getType())); 57100b57cec5SDimitry Andric } 57110b57cec5SDimitry Andric } 57120b57cec5SDimitry Andric 57130b57cec5SDimitry Andric // Transform "icmp eq (trunc (lshr(X, cst1)), cst" to 57140b57cec5SDimitry Andric // "icmp (and X, mask), cst" 57150b57cec5SDimitry Andric uint64_t ShAmt = 0; 57160b57cec5SDimitry Andric if (Op0->hasOneUse() && 57170b57cec5SDimitry Andric match(Op0, m_Trunc(m_OneUse(m_LShr(m_Value(A), m_ConstantInt(ShAmt))))) && 57180b57cec5SDimitry Andric match(Op1, m_ConstantInt(Cst1)) && 57190b57cec5SDimitry Andric // Only do this when A has multiple uses. This is most important to do 57200b57cec5SDimitry Andric // when it exposes other optimizations. 57210b57cec5SDimitry Andric !A->hasOneUse()) { 57220b57cec5SDimitry Andric unsigned ASize = cast<IntegerType>(A->getType())->getPrimitiveSizeInBits(); 57230b57cec5SDimitry Andric 57240b57cec5SDimitry Andric if (ShAmt < ASize) { 57250b57cec5SDimitry Andric APInt MaskV = 57260b57cec5SDimitry Andric APInt::getLowBitsSet(ASize, Op0->getType()->getPrimitiveSizeInBits()); 57270b57cec5SDimitry Andric MaskV <<= ShAmt; 57280b57cec5SDimitry Andric 57290b57cec5SDimitry Andric APInt CmpV = Cst1->getValue().zext(ASize); 57300b57cec5SDimitry Andric CmpV <<= ShAmt; 57310b57cec5SDimitry Andric 57320b57cec5SDimitry Andric Value *Mask = Builder.CreateAnd(A, Builder.getInt(MaskV)); 57330b57cec5SDimitry Andric return new ICmpInst(Pred, Mask, Builder.getInt(CmpV)); 57340b57cec5SDimitry Andric } 57350b57cec5SDimitry Andric } 57360b57cec5SDimitry Andric 573706c3fb27SDimitry Andric if (Instruction *ICmp = foldICmpIntrinsicWithIntrinsic(I, Builder)) 5738349cc55cSDimitry Andric return ICmp; 57390b57cec5SDimitry Andric 5740349cc55cSDimitry Andric // Match icmp eq (trunc (lshr A, BW), (ashr (trunc A), BW-1)), which checks the 5741349cc55cSDimitry Andric // top BW/2 + 1 bits are all the same. Create "A >=s INT_MIN && A <=s INT_MAX", 5742349cc55cSDimitry Andric // which we generate as "icmp ult (add A, 2^(BW-1)), 2^BW" to skip a few steps 5743349cc55cSDimitry Andric // of instcombine. 5744349cc55cSDimitry Andric unsigned BitWidth = Op0->getType()->getScalarSizeInBits(); 5745349cc55cSDimitry Andric if (match(Op0, m_AShr(m_Trunc(m_Value(A)), m_SpecificInt(BitWidth - 1))) && 5746349cc55cSDimitry Andric match(Op1, m_Trunc(m_LShr(m_Specific(A), m_SpecificInt(BitWidth)))) && 5747349cc55cSDimitry Andric A->getType()->getScalarSizeInBits() == BitWidth * 2 && 5748349cc55cSDimitry Andric (I.getOperand(0)->hasOneUse() || I.getOperand(1)->hasOneUse())) { 5749349cc55cSDimitry Andric APInt C = APInt::getOneBitSet(BitWidth * 2, BitWidth - 1); 5750349cc55cSDimitry Andric Value *Add = Builder.CreateAdd(A, ConstantInt::get(A->getType(), C)); 5751349cc55cSDimitry Andric return new ICmpInst(Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_ULT 5752349cc55cSDimitry Andric : ICmpInst::ICMP_UGE, 5753349cc55cSDimitry Andric Add, ConstantInt::get(A->getType(), C.shl(1))); 5754349cc55cSDimitry Andric } 5755349cc55cSDimitry Andric 5756bdd1243dSDimitry Andric // Canonicalize: 5757bdd1243dSDimitry Andric // Assume B_Pow2 != 0 5758bdd1243dSDimitry Andric // 1. A & B_Pow2 != B_Pow2 -> A & B_Pow2 == 0 5759bdd1243dSDimitry Andric // 2. A & B_Pow2 == B_Pow2 -> A & B_Pow2 != 0 5760bdd1243dSDimitry Andric if (match(Op0, m_c_And(m_Specific(Op1), m_Value())) && 5761bdd1243dSDimitry Andric isKnownToBeAPowerOfTwo(Op1, /* OrZero */ false, 0, &I)) 5762bdd1243dSDimitry Andric return new ICmpInst(CmpInst::getInversePredicate(Pred), Op0, 5763bdd1243dSDimitry Andric ConstantInt::getNullValue(Op0->getType())); 5764bdd1243dSDimitry Andric 5765bdd1243dSDimitry Andric if (match(Op1, m_c_And(m_Specific(Op0), m_Value())) && 5766bdd1243dSDimitry Andric isKnownToBeAPowerOfTwo(Op0, /* OrZero */ false, 0, &I)) 5767bdd1243dSDimitry Andric return new ICmpInst(CmpInst::getInversePredicate(Pred), Op1, 5768bdd1243dSDimitry Andric ConstantInt::getNullValue(Op1->getType())); 5769bdd1243dSDimitry Andric 577006c3fb27SDimitry Andric // Canonicalize: 577106c3fb27SDimitry Andric // icmp eq/ne X, OneUse(rotate-right(X)) 577206c3fb27SDimitry Andric // -> icmp eq/ne X, rotate-left(X) 577306c3fb27SDimitry Andric // We generally try to convert rotate-right -> rotate-left, this just 577406c3fb27SDimitry Andric // canonicalizes another case. 577506c3fb27SDimitry Andric CmpInst::Predicate PredUnused = Pred; 577606c3fb27SDimitry Andric if (match(&I, m_c_ICmp(PredUnused, m_Value(A), 577706c3fb27SDimitry Andric m_OneUse(m_Intrinsic<Intrinsic::fshr>( 577806c3fb27SDimitry Andric m_Deferred(A), m_Deferred(A), m_Value(B)))))) 577906c3fb27SDimitry Andric return new ICmpInst( 578006c3fb27SDimitry Andric Pred, A, 578106c3fb27SDimitry Andric Builder.CreateIntrinsic(Op0->getType(), Intrinsic::fshl, {A, A, B})); 578206c3fb27SDimitry Andric 57835f757f3fSDimitry Andric // Canonicalize: 57845f757f3fSDimitry Andric // icmp eq/ne OneUse(A ^ Cst), B --> icmp eq/ne (A ^ B), Cst 57855f757f3fSDimitry Andric Constant *Cst; 57865f757f3fSDimitry Andric if (match(&I, m_c_ICmp(PredUnused, 57875f757f3fSDimitry Andric m_OneUse(m_Xor(m_Value(A), m_ImmConstant(Cst))), 57885f757f3fSDimitry Andric m_CombineAnd(m_Value(B), m_Unless(m_ImmConstant()))))) 57895f757f3fSDimitry Andric return new ICmpInst(Pred, Builder.CreateXor(A, B), Cst); 57905f757f3fSDimitry Andric 57915f757f3fSDimitry Andric { 57925f757f3fSDimitry Andric // (icmp eq/ne (and (add/sub/xor X, P2), P2), P2) 57935f757f3fSDimitry Andric auto m_Matcher = 57945f757f3fSDimitry Andric m_CombineOr(m_CombineOr(m_c_Add(m_Value(B), m_Deferred(A)), 57955f757f3fSDimitry Andric m_c_Xor(m_Value(B), m_Deferred(A))), 57965f757f3fSDimitry Andric m_Sub(m_Value(B), m_Deferred(A))); 57975f757f3fSDimitry Andric std::optional<bool> IsZero = std::nullopt; 57985f757f3fSDimitry Andric if (match(&I, m_c_ICmp(PredUnused, m_OneUse(m_c_And(m_Value(A), m_Matcher)), 57995f757f3fSDimitry Andric m_Deferred(A)))) 58005f757f3fSDimitry Andric IsZero = false; 58015f757f3fSDimitry Andric // (icmp eq/ne (and (add/sub/xor X, P2), P2), 0) 58025f757f3fSDimitry Andric else if (match(&I, 58035f757f3fSDimitry Andric m_ICmp(PredUnused, m_OneUse(m_c_And(m_Value(A), m_Matcher)), 58045f757f3fSDimitry Andric m_Zero()))) 58055f757f3fSDimitry Andric IsZero = true; 58065f757f3fSDimitry Andric 58075f757f3fSDimitry Andric if (IsZero && isKnownToBeAPowerOfTwo(A, /* OrZero */ true, /*Depth*/ 0, &I)) 58085f757f3fSDimitry Andric // (icmp eq/ne (and (add/sub/xor X, P2), P2), P2) 58095f757f3fSDimitry Andric // -> (icmp eq/ne (and X, P2), 0) 58105f757f3fSDimitry Andric // (icmp eq/ne (and (add/sub/xor X, P2), P2), 0) 58115f757f3fSDimitry Andric // -> (icmp eq/ne (and X, P2), P2) 58125f757f3fSDimitry Andric return new ICmpInst(Pred, Builder.CreateAnd(B, A), 58135f757f3fSDimitry Andric *IsZero ? A 58145f757f3fSDimitry Andric : ConstantInt::getNullValue(A->getType())); 58155f757f3fSDimitry Andric } 58165f757f3fSDimitry Andric 5817349cc55cSDimitry Andric return nullptr; 5818349cc55cSDimitry Andric } 5819349cc55cSDimitry Andric 582006c3fb27SDimitry Andric Instruction *InstCombinerImpl::foldICmpWithTrunc(ICmpInst &ICmp) { 58214824e7fdSDimitry Andric ICmpInst::Predicate Pred = ICmp.getPredicate(); 5822349cc55cSDimitry Andric Value *Op0 = ICmp.getOperand(0), *Op1 = ICmp.getOperand(1); 5823349cc55cSDimitry Andric 5824349cc55cSDimitry Andric // Try to canonicalize trunc + compare-to-constant into a mask + cmp. 5825349cc55cSDimitry Andric // The trunc masks high bits while the compare may effectively mask low bits. 5826349cc55cSDimitry Andric Value *X; 5827349cc55cSDimitry Andric const APInt *C; 5828349cc55cSDimitry Andric if (!match(Op0, m_OneUse(m_Trunc(m_Value(X)))) || !match(Op1, m_APInt(C))) 5829349cc55cSDimitry Andric return nullptr; 5830349cc55cSDimitry Andric 58314824e7fdSDimitry Andric // This matches patterns corresponding to tests of the signbit as well as: 5832349cc55cSDimitry Andric // (trunc X) u< C --> (X & -C) == 0 (are all masked-high-bits clear?) 58334824e7fdSDimitry Andric // (trunc X) u> C --> (X & ~C) != 0 (are any masked-high-bits set?) 58344824e7fdSDimitry Andric APInt Mask; 58354824e7fdSDimitry Andric if (decomposeBitTestICmp(Op0, Op1, Pred, X, Mask, true /* WithTrunc */)) { 58364824e7fdSDimitry Andric Value *And = Builder.CreateAnd(X, Mask); 5837349cc55cSDimitry Andric Constant *Zero = ConstantInt::getNullValue(X->getType()); 58384824e7fdSDimitry Andric return new ICmpInst(Pred, And, Zero); 5839349cc55cSDimitry Andric } 58404824e7fdSDimitry Andric 58414824e7fdSDimitry Andric unsigned SrcBits = X->getType()->getScalarSizeInBits(); 58424824e7fdSDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C->isNegatedPowerOf2()) { 5843349cc55cSDimitry Andric // If C is a negative power-of-2 (high-bit mask): 5844349cc55cSDimitry Andric // (trunc X) u< C --> (X & C) != C (are any masked-high-bits clear?) 5845349cc55cSDimitry Andric Constant *MaskC = ConstantInt::get(X->getType(), C->zext(SrcBits)); 5846349cc55cSDimitry Andric Value *And = Builder.CreateAnd(X, MaskC); 5847349cc55cSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, And, MaskC); 5848349cc55cSDimitry Andric } 5849349cc55cSDimitry Andric 58504824e7fdSDimitry Andric if (Pred == ICmpInst::ICMP_UGT && (~*C).isPowerOf2()) { 5851349cc55cSDimitry Andric // If C is not-of-power-of-2 (one clear bit): 5852349cc55cSDimitry Andric // (trunc X) u> C --> (X & (C+1)) == C+1 (are all masked-high-bits set?) 5853349cc55cSDimitry Andric Constant *MaskC = ConstantInt::get(X->getType(), (*C + 1).zext(SrcBits)); 5854349cc55cSDimitry Andric Value *And = Builder.CreateAnd(X, MaskC); 5855349cc55cSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, And, MaskC); 5856349cc55cSDimitry Andric } 5857349cc55cSDimitry Andric 585806c3fb27SDimitry Andric if (auto *II = dyn_cast<IntrinsicInst>(X)) { 585906c3fb27SDimitry Andric if (II->getIntrinsicID() == Intrinsic::cttz || 586006c3fb27SDimitry Andric II->getIntrinsicID() == Intrinsic::ctlz) { 586106c3fb27SDimitry Andric unsigned MaxRet = SrcBits; 586206c3fb27SDimitry Andric // If the "is_zero_poison" argument is set, then we know at least 586306c3fb27SDimitry Andric // one bit is set in the input, so the result is always at least one 586406c3fb27SDimitry Andric // less than the full bitwidth of that input. 586506c3fb27SDimitry Andric if (match(II->getArgOperand(1), m_One())) 586606c3fb27SDimitry Andric MaxRet--; 586706c3fb27SDimitry Andric 586806c3fb27SDimitry Andric // Make sure the destination is wide enough to hold the largest output of 586906c3fb27SDimitry Andric // the intrinsic. 587006c3fb27SDimitry Andric if (llvm::Log2_32(MaxRet) + 1 <= Op0->getType()->getScalarSizeInBits()) 587106c3fb27SDimitry Andric if (Instruction *I = 587206c3fb27SDimitry Andric foldICmpIntrinsicWithConstant(ICmp, II, C->zext(SrcBits))) 587306c3fb27SDimitry Andric return I; 587406c3fb27SDimitry Andric } 587506c3fb27SDimitry Andric } 587606c3fb27SDimitry Andric 58770b57cec5SDimitry Andric return nullptr; 58780b57cec5SDimitry Andric } 58790b57cec5SDimitry Andric 588081ad6265SDimitry Andric Instruction *InstCombinerImpl::foldICmpWithZextOrSext(ICmpInst &ICmp) { 58818bcb0991SDimitry Andric assert(isa<CastInst>(ICmp.getOperand(0)) && "Expected cast for operand 0"); 58828bcb0991SDimitry Andric auto *CastOp0 = cast<CastInst>(ICmp.getOperand(0)); 58838bcb0991SDimitry Andric Value *X; 58848bcb0991SDimitry Andric if (!match(CastOp0, m_ZExtOrSExt(m_Value(X)))) 58850b57cec5SDimitry Andric return nullptr; 58860b57cec5SDimitry Andric 58878bcb0991SDimitry Andric bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt; 58888bcb0991SDimitry Andric bool IsSignedCmp = ICmp.isSigned(); 588981ad6265SDimitry Andric 589081ad6265SDimitry Andric // icmp Pred (ext X), (ext Y) 589181ad6265SDimitry Andric Value *Y; 589281ad6265SDimitry Andric if (match(ICmp.getOperand(1), m_ZExtOrSExt(m_Value(Y)))) { 58935f757f3fSDimitry Andric bool IsZext0 = isa<ZExtInst>(ICmp.getOperand(0)); 58945f757f3fSDimitry Andric bool IsZext1 = isa<ZExtInst>(ICmp.getOperand(1)); 589581ad6265SDimitry Andric 589606c3fb27SDimitry Andric if (IsZext0 != IsZext1) { 589706c3fb27SDimitry Andric // If X and Y and both i1 589806c3fb27SDimitry Andric // (icmp eq/ne (zext X) (sext Y)) 589906c3fb27SDimitry Andric // eq -> (icmp eq (or X, Y), 0) 590006c3fb27SDimitry Andric // ne -> (icmp ne (or X, Y), 0) 590106c3fb27SDimitry Andric if (ICmp.isEquality() && X->getType()->isIntOrIntVectorTy(1) && 590206c3fb27SDimitry Andric Y->getType()->isIntOrIntVectorTy(1)) 590306c3fb27SDimitry Andric return new ICmpInst(ICmp.getPredicate(), Builder.CreateOr(X, Y), 590406c3fb27SDimitry Andric Constant::getNullValue(X->getType())); 590506c3fb27SDimitry Andric 59065f757f3fSDimitry Andric // If we have mismatched casts and zext has the nneg flag, we can 59075f757f3fSDimitry Andric // treat the "zext nneg" as "sext". Otherwise, we cannot fold and quit. 59085f757f3fSDimitry Andric 59095f757f3fSDimitry Andric auto *NonNegInst0 = dyn_cast<PossiblyNonNegInst>(ICmp.getOperand(0)); 59105f757f3fSDimitry Andric auto *NonNegInst1 = dyn_cast<PossiblyNonNegInst>(ICmp.getOperand(1)); 59115f757f3fSDimitry Andric 59125f757f3fSDimitry Andric bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg(); 59135f757f3fSDimitry Andric bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg(); 59145f757f3fSDimitry Andric 59155f757f3fSDimitry Andric if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1)) 591681ad6265SDimitry Andric IsSignedExt = true; 591781ad6265SDimitry Andric else 59180b57cec5SDimitry Andric return nullptr; 591981ad6265SDimitry Andric } 59200b57cec5SDimitry Andric 59218bcb0991SDimitry Andric // Not an extension from the same type? 59228bcb0991SDimitry Andric Type *XTy = X->getType(), *YTy = Y->getType(); 59238bcb0991SDimitry Andric if (XTy != YTy) { 59248bcb0991SDimitry Andric // One of the casts must have one use because we are creating a new cast. 592581ad6265SDimitry Andric if (!ICmp.getOperand(0)->hasOneUse() && !ICmp.getOperand(1)->hasOneUse()) 59268bcb0991SDimitry Andric return nullptr; 59278bcb0991SDimitry Andric // Extend the narrower operand to the type of the wider operand. 592881ad6265SDimitry Andric CastInst::CastOps CastOpcode = 592981ad6265SDimitry Andric IsSignedExt ? Instruction::SExt : Instruction::ZExt; 59308bcb0991SDimitry Andric if (XTy->getScalarSizeInBits() < YTy->getScalarSizeInBits()) 593181ad6265SDimitry Andric X = Builder.CreateCast(CastOpcode, X, YTy); 59328bcb0991SDimitry Andric else if (YTy->getScalarSizeInBits() < XTy->getScalarSizeInBits()) 593381ad6265SDimitry Andric Y = Builder.CreateCast(CastOpcode, Y, XTy); 59348bcb0991SDimitry Andric else 59358bcb0991SDimitry Andric return nullptr; 59368bcb0991SDimitry Andric } 59378bcb0991SDimitry Andric 59388bcb0991SDimitry Andric // (zext X) == (zext Y) --> X == Y 59398bcb0991SDimitry Andric // (sext X) == (sext Y) --> X == Y 59400b57cec5SDimitry Andric if (ICmp.isEquality()) 59418bcb0991SDimitry Andric return new ICmpInst(ICmp.getPredicate(), X, Y); 59420b57cec5SDimitry Andric 59430b57cec5SDimitry Andric // A signed comparison of sign extended values simplifies into a 59440b57cec5SDimitry Andric // signed comparison. 59458bcb0991SDimitry Andric if (IsSignedCmp && IsSignedExt) 59468bcb0991SDimitry Andric return new ICmpInst(ICmp.getPredicate(), X, Y); 59470b57cec5SDimitry Andric 59480b57cec5SDimitry Andric // The other three cases all fold into an unsigned comparison. 59498bcb0991SDimitry Andric return new ICmpInst(ICmp.getUnsignedPredicate(), X, Y); 59500b57cec5SDimitry Andric } 59510b57cec5SDimitry Andric 59528bcb0991SDimitry Andric // Below here, we are only folding a compare with constant. 59530b57cec5SDimitry Andric auto *C = dyn_cast<Constant>(ICmp.getOperand(1)); 59540b57cec5SDimitry Andric if (!C) 59550b57cec5SDimitry Andric return nullptr; 59560b57cec5SDimitry Andric 59575f757f3fSDimitry Andric // If a lossless truncate is possible... 59588bcb0991SDimitry Andric Type *SrcTy = CastOp0->getSrcTy(); 59595f757f3fSDimitry Andric Constant *Res = getLosslessTrunc(C, SrcTy, CastOp0->getOpcode()); 59605f757f3fSDimitry Andric if (Res) { 59610b57cec5SDimitry Andric if (ICmp.isEquality()) 59625f757f3fSDimitry Andric return new ICmpInst(ICmp.getPredicate(), X, Res); 59630b57cec5SDimitry Andric 59640b57cec5SDimitry Andric // A signed comparison of sign extended values simplifies into a 59650b57cec5SDimitry Andric // signed comparison. 59668bcb0991SDimitry Andric if (IsSignedExt && IsSignedCmp) 59675f757f3fSDimitry Andric return new ICmpInst(ICmp.getPredicate(), X, Res); 59680b57cec5SDimitry Andric 59690b57cec5SDimitry Andric // The other three cases all fold into an unsigned comparison. 59705f757f3fSDimitry Andric return new ICmpInst(ICmp.getUnsignedPredicate(), X, Res); 59710b57cec5SDimitry Andric } 59720b57cec5SDimitry Andric 59730b57cec5SDimitry Andric // The re-extended constant changed, partly changed (in the case of a vector), 59740b57cec5SDimitry Andric // or could not be determined to be equal (in the case of a constant 59750b57cec5SDimitry Andric // expression), so the constant cannot be represented in the shorter type. 59760b57cec5SDimitry Andric // All the cases that fold to true or false will have already been handled 597781ad6265SDimitry Andric // by simplifyICmpInst, so only deal with the tricky case. 59788bcb0991SDimitry Andric if (IsSignedCmp || !IsSignedExt || !isa<ConstantInt>(C)) 59790b57cec5SDimitry Andric return nullptr; 59800b57cec5SDimitry Andric 59818bcb0991SDimitry Andric // Is source op positive? 59828bcb0991SDimitry Andric // icmp ult (sext X), C --> icmp sgt X, -1 59830b57cec5SDimitry Andric if (ICmp.getPredicate() == ICmpInst::ICMP_ULT) 59848bcb0991SDimitry Andric return new ICmpInst(CmpInst::ICMP_SGT, X, Constant::getAllOnesValue(SrcTy)); 59850b57cec5SDimitry Andric 59868bcb0991SDimitry Andric // Is source op negative? 59878bcb0991SDimitry Andric // icmp ugt (sext X), C --> icmp slt X, 0 59880b57cec5SDimitry Andric assert(ICmp.getPredicate() == ICmpInst::ICMP_UGT && "ICmp should be folded!"); 59898bcb0991SDimitry Andric return new ICmpInst(CmpInst::ICMP_SLT, X, Constant::getNullValue(SrcTy)); 59908bcb0991SDimitry Andric } 59918bcb0991SDimitry Andric 59928bcb0991SDimitry Andric /// Handle icmp (cast x), (cast or constant). 5993e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpWithCastOp(ICmpInst &ICmp) { 5994fe6060f1SDimitry Andric // If any operand of ICmp is a inttoptr roundtrip cast then remove it as 5995fe6060f1SDimitry Andric // icmp compares only pointer's value. 5996fe6060f1SDimitry Andric // icmp (inttoptr (ptrtoint p1)), p2 --> icmp p1, p2. 5997fe6060f1SDimitry Andric Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.getOperand(0)); 5998fe6060f1SDimitry Andric Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.getOperand(1)); 5999fe6060f1SDimitry Andric if (SimplifiedOp0 || SimplifiedOp1) 6000fe6060f1SDimitry Andric return new ICmpInst(ICmp.getPredicate(), 6001fe6060f1SDimitry Andric SimplifiedOp0 ? SimplifiedOp0 : ICmp.getOperand(0), 6002fe6060f1SDimitry Andric SimplifiedOp1 ? SimplifiedOp1 : ICmp.getOperand(1)); 6003fe6060f1SDimitry Andric 60048bcb0991SDimitry Andric auto *CastOp0 = dyn_cast<CastInst>(ICmp.getOperand(0)); 60058bcb0991SDimitry Andric if (!CastOp0) 60068bcb0991SDimitry Andric return nullptr; 60078bcb0991SDimitry Andric if (!isa<Constant>(ICmp.getOperand(1)) && !isa<CastInst>(ICmp.getOperand(1))) 60088bcb0991SDimitry Andric return nullptr; 60098bcb0991SDimitry Andric 60108bcb0991SDimitry Andric Value *Op0Src = CastOp0->getOperand(0); 60118bcb0991SDimitry Andric Type *SrcTy = CastOp0->getSrcTy(); 60128bcb0991SDimitry Andric Type *DestTy = CastOp0->getDestTy(); 60138bcb0991SDimitry Andric 60148bcb0991SDimitry Andric // Turn icmp (ptrtoint x), (ptrtoint/c) into a compare of the input if the 60158bcb0991SDimitry Andric // integer type is the same size as the pointer type. 60168bcb0991SDimitry Andric auto CompatibleSizes = [&](Type *SrcTy, Type *DestTy) { 60178bcb0991SDimitry Andric if (isa<VectorType>(SrcTy)) { 60188bcb0991SDimitry Andric SrcTy = cast<VectorType>(SrcTy)->getElementType(); 60198bcb0991SDimitry Andric DestTy = cast<VectorType>(DestTy)->getElementType(); 60208bcb0991SDimitry Andric } 60218bcb0991SDimitry Andric return DL.getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth(); 60228bcb0991SDimitry Andric }; 60238bcb0991SDimitry Andric if (CastOp0->getOpcode() == Instruction::PtrToInt && 60248bcb0991SDimitry Andric CompatibleSizes(SrcTy, DestTy)) { 60258bcb0991SDimitry Andric Value *NewOp1 = nullptr; 60268bcb0991SDimitry Andric if (auto *PtrToIntOp1 = dyn_cast<PtrToIntOperator>(ICmp.getOperand(1))) { 60278bcb0991SDimitry Andric Value *PtrSrc = PtrToIntOp1->getOperand(0); 60285f757f3fSDimitry Andric if (PtrSrc->getType() == Op0Src->getType()) 60298bcb0991SDimitry Andric NewOp1 = PtrToIntOp1->getOperand(0); 60308bcb0991SDimitry Andric } else if (auto *RHSC = dyn_cast<Constant>(ICmp.getOperand(1))) { 60318bcb0991SDimitry Andric NewOp1 = ConstantExpr::getIntToPtr(RHSC, SrcTy); 60328bcb0991SDimitry Andric } 60338bcb0991SDimitry Andric 60348bcb0991SDimitry Andric if (NewOp1) 60358bcb0991SDimitry Andric return new ICmpInst(ICmp.getPredicate(), Op0Src, NewOp1); 60368bcb0991SDimitry Andric } 60378bcb0991SDimitry Andric 603806c3fb27SDimitry Andric if (Instruction *R = foldICmpWithTrunc(ICmp)) 6039349cc55cSDimitry Andric return R; 6040349cc55cSDimitry Andric 604181ad6265SDimitry Andric return foldICmpWithZextOrSext(ICmp); 60420b57cec5SDimitry Andric } 60430b57cec5SDimitry Andric 6044bdd1243dSDimitry Andric static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned) { 60450b57cec5SDimitry Andric switch (BinaryOp) { 60460b57cec5SDimitry Andric default: 60470b57cec5SDimitry Andric llvm_unreachable("Unsupported binary op"); 60480b57cec5SDimitry Andric case Instruction::Add: 60490b57cec5SDimitry Andric case Instruction::Sub: 60500b57cec5SDimitry Andric return match(RHS, m_Zero()); 60510b57cec5SDimitry Andric case Instruction::Mul: 6052bdd1243dSDimitry Andric return !(RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) && 6053bdd1243dSDimitry Andric match(RHS, m_One()); 60540b57cec5SDimitry Andric } 60550b57cec5SDimitry Andric } 60560b57cec5SDimitry Andric 6057e8d8bef9SDimitry Andric OverflowResult 6058e8d8bef9SDimitry Andric InstCombinerImpl::computeOverflow(Instruction::BinaryOps BinaryOp, 6059e8d8bef9SDimitry Andric bool IsSigned, Value *LHS, Value *RHS, 6060e8d8bef9SDimitry Andric Instruction *CxtI) const { 60610b57cec5SDimitry Andric switch (BinaryOp) { 60620b57cec5SDimitry Andric default: 60630b57cec5SDimitry Andric llvm_unreachable("Unsupported binary op"); 60640b57cec5SDimitry Andric case Instruction::Add: 60650b57cec5SDimitry Andric if (IsSigned) 60660b57cec5SDimitry Andric return computeOverflowForSignedAdd(LHS, RHS, CxtI); 60670b57cec5SDimitry Andric else 60680b57cec5SDimitry Andric return computeOverflowForUnsignedAdd(LHS, RHS, CxtI); 60690b57cec5SDimitry Andric case Instruction::Sub: 60700b57cec5SDimitry Andric if (IsSigned) 60710b57cec5SDimitry Andric return computeOverflowForSignedSub(LHS, RHS, CxtI); 60720b57cec5SDimitry Andric else 60730b57cec5SDimitry Andric return computeOverflowForUnsignedSub(LHS, RHS, CxtI); 60740b57cec5SDimitry Andric case Instruction::Mul: 60750b57cec5SDimitry Andric if (IsSigned) 60760b57cec5SDimitry Andric return computeOverflowForSignedMul(LHS, RHS, CxtI); 60770b57cec5SDimitry Andric else 60780b57cec5SDimitry Andric return computeOverflowForUnsignedMul(LHS, RHS, CxtI); 60790b57cec5SDimitry Andric } 60800b57cec5SDimitry Andric } 60810b57cec5SDimitry Andric 6082e8d8bef9SDimitry Andric bool InstCombinerImpl::OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp, 6083e8d8bef9SDimitry Andric bool IsSigned, Value *LHS, 6084e8d8bef9SDimitry Andric Value *RHS, Instruction &OrigI, 6085e8d8bef9SDimitry Andric Value *&Result, 6086e8d8bef9SDimitry Andric Constant *&Overflow) { 60870b57cec5SDimitry Andric if (OrigI.isCommutative() && isa<Constant>(LHS) && !isa<Constant>(RHS)) 60880b57cec5SDimitry Andric std::swap(LHS, RHS); 60890b57cec5SDimitry Andric 60900b57cec5SDimitry Andric // If the overflow check was an add followed by a compare, the insertion point 60910b57cec5SDimitry Andric // may be pointing to the compare. We want to insert the new instructions 60920b57cec5SDimitry Andric // before the add in case there are uses of the add between the add and the 60930b57cec5SDimitry Andric // compare. 60940b57cec5SDimitry Andric Builder.SetInsertPoint(&OrigI); 60950b57cec5SDimitry Andric 6096e8d8bef9SDimitry Andric Type *OverflowTy = Type::getInt1Ty(LHS->getContext()); 6097e8d8bef9SDimitry Andric if (auto *LHSTy = dyn_cast<VectorType>(LHS->getType())) 6098e8d8bef9SDimitry Andric OverflowTy = VectorType::get(OverflowTy, LHSTy->getElementCount()); 6099e8d8bef9SDimitry Andric 6100bdd1243dSDimitry Andric if (isNeutralValue(BinaryOp, RHS, IsSigned)) { 61010b57cec5SDimitry Andric Result = LHS; 6102e8d8bef9SDimitry Andric Overflow = ConstantInt::getFalse(OverflowTy); 61030b57cec5SDimitry Andric return true; 61040b57cec5SDimitry Andric } 61050b57cec5SDimitry Andric 61060b57cec5SDimitry Andric switch (computeOverflow(BinaryOp, IsSigned, LHS, RHS, &OrigI)) { 61070b57cec5SDimitry Andric case OverflowResult::MayOverflow: 61080b57cec5SDimitry Andric return false; 61090b57cec5SDimitry Andric case OverflowResult::AlwaysOverflowsLow: 61100b57cec5SDimitry Andric case OverflowResult::AlwaysOverflowsHigh: 61110b57cec5SDimitry Andric Result = Builder.CreateBinOp(BinaryOp, LHS, RHS); 61120b57cec5SDimitry Andric Result->takeName(&OrigI); 6113e8d8bef9SDimitry Andric Overflow = ConstantInt::getTrue(OverflowTy); 61140b57cec5SDimitry Andric return true; 61150b57cec5SDimitry Andric case OverflowResult::NeverOverflows: 61160b57cec5SDimitry Andric Result = Builder.CreateBinOp(BinaryOp, LHS, RHS); 61170b57cec5SDimitry Andric Result->takeName(&OrigI); 6118e8d8bef9SDimitry Andric Overflow = ConstantInt::getFalse(OverflowTy); 61190b57cec5SDimitry Andric if (auto *Inst = dyn_cast<Instruction>(Result)) { 61200b57cec5SDimitry Andric if (IsSigned) 61210b57cec5SDimitry Andric Inst->setHasNoSignedWrap(); 61220b57cec5SDimitry Andric else 61230b57cec5SDimitry Andric Inst->setHasNoUnsignedWrap(); 61240b57cec5SDimitry Andric } 61250b57cec5SDimitry Andric return true; 61260b57cec5SDimitry Andric } 61270b57cec5SDimitry Andric 61280b57cec5SDimitry Andric llvm_unreachable("Unexpected overflow result"); 61290b57cec5SDimitry Andric } 61300b57cec5SDimitry Andric 61310b57cec5SDimitry Andric /// Recognize and process idiom involving test for multiplication 61320b57cec5SDimitry Andric /// overflow. 61330b57cec5SDimitry Andric /// 61340b57cec5SDimitry Andric /// The caller has matched a pattern of the form: 61350b57cec5SDimitry Andric /// I = cmp u (mul(zext A, zext B), V 61360b57cec5SDimitry Andric /// The function checks if this is a test for overflow and if so replaces 61370b57cec5SDimitry Andric /// multiplication with call to 'mul.with.overflow' intrinsic. 61380b57cec5SDimitry Andric /// 61390b57cec5SDimitry Andric /// \param I Compare instruction. 61400b57cec5SDimitry Andric /// \param MulVal Result of 'mult' instruction. It is one of the arguments of 61410b57cec5SDimitry Andric /// the compare instruction. Must be of integer type. 61420b57cec5SDimitry Andric /// \param OtherVal The other argument of compare instruction. 61430b57cec5SDimitry Andric /// \returns Instruction which must replace the compare instruction, NULL if no 61440b57cec5SDimitry Andric /// replacement required. 61450b57cec5SDimitry Andric static Instruction *processUMulZExtIdiom(ICmpInst &I, Value *MulVal, 61465f757f3fSDimitry Andric const APInt *OtherVal, 6147e8d8bef9SDimitry Andric InstCombinerImpl &IC) { 61480b57cec5SDimitry Andric // Don't bother doing this transformation for pointers, don't do it for 61490b57cec5SDimitry Andric // vectors. 61500b57cec5SDimitry Andric if (!isa<IntegerType>(MulVal->getType())) 61510b57cec5SDimitry Andric return nullptr; 61520b57cec5SDimitry Andric 61530b57cec5SDimitry Andric auto *MulInstr = dyn_cast<Instruction>(MulVal); 61540b57cec5SDimitry Andric if (!MulInstr) 61550b57cec5SDimitry Andric return nullptr; 61560b57cec5SDimitry Andric assert(MulInstr->getOpcode() == Instruction::Mul); 61570b57cec5SDimitry Andric 61585f757f3fSDimitry Andric auto *LHS = cast<ZExtInst>(MulInstr->getOperand(0)), 61595f757f3fSDimitry Andric *RHS = cast<ZExtInst>(MulInstr->getOperand(1)); 61600b57cec5SDimitry Andric assert(LHS->getOpcode() == Instruction::ZExt); 61610b57cec5SDimitry Andric assert(RHS->getOpcode() == Instruction::ZExt); 61620b57cec5SDimitry Andric Value *A = LHS->getOperand(0), *B = RHS->getOperand(0); 61630b57cec5SDimitry Andric 61640b57cec5SDimitry Andric // Calculate type and width of the result produced by mul.with.overflow. 61650b57cec5SDimitry Andric Type *TyA = A->getType(), *TyB = B->getType(); 61660b57cec5SDimitry Andric unsigned WidthA = TyA->getPrimitiveSizeInBits(), 61670b57cec5SDimitry Andric WidthB = TyB->getPrimitiveSizeInBits(); 61680b57cec5SDimitry Andric unsigned MulWidth; 61690b57cec5SDimitry Andric Type *MulType; 61700b57cec5SDimitry Andric if (WidthB > WidthA) { 61710b57cec5SDimitry Andric MulWidth = WidthB; 61720b57cec5SDimitry Andric MulType = TyB; 61730b57cec5SDimitry Andric } else { 61740b57cec5SDimitry Andric MulWidth = WidthA; 61750b57cec5SDimitry Andric MulType = TyA; 61760b57cec5SDimitry Andric } 61770b57cec5SDimitry Andric 61780b57cec5SDimitry Andric // In order to replace the original mul with a narrower mul.with.overflow, 61790b57cec5SDimitry Andric // all uses must ignore upper bits of the product. The number of used low 61800b57cec5SDimitry Andric // bits must be not greater than the width of mul.with.overflow. 61810b57cec5SDimitry Andric if (MulVal->hasNUsesOrMore(2)) 61820b57cec5SDimitry Andric for (User *U : MulVal->users()) { 61830b57cec5SDimitry Andric if (U == &I) 61840b57cec5SDimitry Andric continue; 61850b57cec5SDimitry Andric if (TruncInst *TI = dyn_cast<TruncInst>(U)) { 61860b57cec5SDimitry Andric // Check if truncation ignores bits above MulWidth. 61870b57cec5SDimitry Andric unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits(); 61880b57cec5SDimitry Andric if (TruncWidth > MulWidth) 61890b57cec5SDimitry Andric return nullptr; 61900b57cec5SDimitry Andric } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U)) { 61910b57cec5SDimitry Andric // Check if AND ignores bits above MulWidth. 61920b57cec5SDimitry Andric if (BO->getOpcode() != Instruction::And) 61930b57cec5SDimitry Andric return nullptr; 61940b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) { 61950b57cec5SDimitry Andric const APInt &CVal = CI->getValue(); 619606c3fb27SDimitry Andric if (CVal.getBitWidth() - CVal.countl_zero() > MulWidth) 61970b57cec5SDimitry Andric return nullptr; 61980b57cec5SDimitry Andric } else { 61990b57cec5SDimitry Andric // In this case we could have the operand of the binary operation 62000b57cec5SDimitry Andric // being defined in another block, and performing the replacement 62010b57cec5SDimitry Andric // could break the dominance relation. 62020b57cec5SDimitry Andric return nullptr; 62030b57cec5SDimitry Andric } 62040b57cec5SDimitry Andric } else { 62050b57cec5SDimitry Andric // Other uses prohibit this transformation. 62060b57cec5SDimitry Andric return nullptr; 62070b57cec5SDimitry Andric } 62080b57cec5SDimitry Andric } 62090b57cec5SDimitry Andric 62100b57cec5SDimitry Andric // Recognize patterns 62110b57cec5SDimitry Andric switch (I.getPredicate()) { 62125f757f3fSDimitry Andric case ICmpInst::ICMP_UGT: { 62130b57cec5SDimitry Andric // Recognize pattern: 62140b57cec5SDimitry Andric // mulval = mul(zext A, zext B) 62150b57cec5SDimitry Andric // cmp ugt mulval, max 62160b57cec5SDimitry Andric APInt MaxVal = APInt::getMaxValue(MulWidth); 62175f757f3fSDimitry Andric MaxVal = MaxVal.zext(OtherVal->getBitWidth()); 62185f757f3fSDimitry Andric if (MaxVal.eq(*OtherVal)) 62190b57cec5SDimitry Andric break; // Recognized 62200b57cec5SDimitry Andric return nullptr; 62210b57cec5SDimitry Andric } 62220b57cec5SDimitry Andric 62235f757f3fSDimitry Andric case ICmpInst::ICMP_ULT: { 62240b57cec5SDimitry Andric // Recognize pattern: 62250b57cec5SDimitry Andric // mulval = mul(zext A, zext B) 62260b57cec5SDimitry Andric // cmp ule mulval, max + 1 62275f757f3fSDimitry Andric APInt MaxVal = APInt::getOneBitSet(OtherVal->getBitWidth(), MulWidth); 62285f757f3fSDimitry Andric if (MaxVal.eq(*OtherVal)) 62290b57cec5SDimitry Andric break; // Recognized 62300b57cec5SDimitry Andric return nullptr; 62315f757f3fSDimitry Andric } 62320b57cec5SDimitry Andric 62330b57cec5SDimitry Andric default: 62340b57cec5SDimitry Andric return nullptr; 62350b57cec5SDimitry Andric } 62360b57cec5SDimitry Andric 62370b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder = IC.Builder; 62380b57cec5SDimitry Andric Builder.SetInsertPoint(MulInstr); 62390b57cec5SDimitry Andric 62400b57cec5SDimitry Andric // Replace: mul(zext A, zext B) --> mul.with.overflow(A, B) 62410b57cec5SDimitry Andric Value *MulA = A, *MulB = B; 62420b57cec5SDimitry Andric if (WidthA < MulWidth) 62430b57cec5SDimitry Andric MulA = Builder.CreateZExt(A, MulType); 62440b57cec5SDimitry Andric if (WidthB < MulWidth) 62450b57cec5SDimitry Andric MulB = Builder.CreateZExt(B, MulType); 62460b57cec5SDimitry Andric Function *F = Intrinsic::getDeclaration( 62470b57cec5SDimitry Andric I.getModule(), Intrinsic::umul_with_overflow, MulType); 62480b57cec5SDimitry Andric CallInst *Call = Builder.CreateCall(F, {MulA, MulB}, "umul"); 6249e8d8bef9SDimitry Andric IC.addToWorklist(MulInstr); 62500b57cec5SDimitry Andric 62510b57cec5SDimitry Andric // If there are uses of mul result other than the comparison, we know that 62520b57cec5SDimitry Andric // they are truncation or binary AND. Change them to use result of 62530b57cec5SDimitry Andric // mul.with.overflow and adjust properly mask/size. 62540b57cec5SDimitry Andric if (MulVal->hasNUsesOrMore(2)) { 62550b57cec5SDimitry Andric Value *Mul = Builder.CreateExtractValue(Call, 0, "umul.value"); 6256e8d8bef9SDimitry Andric for (User *U : make_early_inc_range(MulVal->users())) { 62575f757f3fSDimitry Andric if (U == &I) 62580b57cec5SDimitry Andric continue; 62590b57cec5SDimitry Andric if (TruncInst *TI = dyn_cast<TruncInst>(U)) { 62600b57cec5SDimitry Andric if (TI->getType()->getPrimitiveSizeInBits() == MulWidth) 62610b57cec5SDimitry Andric IC.replaceInstUsesWith(*TI, Mul); 62620b57cec5SDimitry Andric else 62630b57cec5SDimitry Andric TI->setOperand(0, Mul); 62640b57cec5SDimitry Andric } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U)) { 62650b57cec5SDimitry Andric assert(BO->getOpcode() == Instruction::And); 62660b57cec5SDimitry Andric // Replace (mul & mask) --> zext (mul.with.overflow & short_mask) 62670b57cec5SDimitry Andric ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1)); 62680b57cec5SDimitry Andric APInt ShortMask = CI->getValue().trunc(MulWidth); 62690b57cec5SDimitry Andric Value *ShortAnd = Builder.CreateAnd(Mul, ShortMask); 62705ffd83dbSDimitry Andric Value *Zext = Builder.CreateZExt(ShortAnd, BO->getType()); 62710b57cec5SDimitry Andric IC.replaceInstUsesWith(*BO, Zext); 62720b57cec5SDimitry Andric } else { 62730b57cec5SDimitry Andric llvm_unreachable("Unexpected Binary operation"); 62740b57cec5SDimitry Andric } 6275e8d8bef9SDimitry Andric IC.addToWorklist(cast<Instruction>(U)); 62760b57cec5SDimitry Andric } 62770b57cec5SDimitry Andric } 62780b57cec5SDimitry Andric 62790b57cec5SDimitry Andric // The original icmp gets replaced with the overflow value, maybe inverted 62800b57cec5SDimitry Andric // depending on predicate. 62815f757f3fSDimitry Andric if (I.getPredicate() == ICmpInst::ICMP_ULT) { 62820b57cec5SDimitry Andric Value *Res = Builder.CreateExtractValue(Call, 1); 62830b57cec5SDimitry Andric return BinaryOperator::CreateNot(Res); 62840b57cec5SDimitry Andric } 62850b57cec5SDimitry Andric 62860b57cec5SDimitry Andric return ExtractValueInst::Create(Call, 1); 62870b57cec5SDimitry Andric } 62880b57cec5SDimitry Andric 62890b57cec5SDimitry Andric /// When performing a comparison against a constant, it is possible that not all 62900b57cec5SDimitry Andric /// the bits in the LHS are demanded. This helper method computes the mask that 62910b57cec5SDimitry Andric /// IS demanded. 62920b57cec5SDimitry Andric static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth) { 62930b57cec5SDimitry Andric const APInt *RHS; 62940b57cec5SDimitry Andric if (!match(I.getOperand(1), m_APInt(RHS))) 6295349cc55cSDimitry Andric return APInt::getAllOnes(BitWidth); 62960b57cec5SDimitry Andric 62970b57cec5SDimitry Andric // If this is a normal comparison, it demands all bits. If it is a sign bit 62980b57cec5SDimitry Andric // comparison, it only demands the sign bit. 62990b57cec5SDimitry Andric bool UnusedBit; 6300*0fca6ea1SDimitry Andric if (isSignBitCheck(I.getPredicate(), *RHS, UnusedBit)) 63010b57cec5SDimitry Andric return APInt::getSignMask(BitWidth); 63020b57cec5SDimitry Andric 63030b57cec5SDimitry Andric switch (I.getPredicate()) { 63040b57cec5SDimitry Andric // For a UGT comparison, we don't care about any bits that 63050b57cec5SDimitry Andric // correspond to the trailing ones of the comparand. The value of these 63060b57cec5SDimitry Andric // bits doesn't impact the outcome of the comparison, because any value 63070b57cec5SDimitry Andric // greater than the RHS must differ in a bit higher than these due to carry. 63080b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: 630906c3fb27SDimitry Andric return APInt::getBitsSetFrom(BitWidth, RHS->countr_one()); 63100b57cec5SDimitry Andric 63110b57cec5SDimitry Andric // Similarly, for a ULT comparison, we don't care about the trailing zeros. 63120b57cec5SDimitry Andric // Any value less than the RHS must differ in a higher bit because of carries. 63130b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: 631406c3fb27SDimitry Andric return APInt::getBitsSetFrom(BitWidth, RHS->countr_zero()); 63150b57cec5SDimitry Andric 63160b57cec5SDimitry Andric default: 6317349cc55cSDimitry Andric return APInt::getAllOnes(BitWidth); 63180b57cec5SDimitry Andric } 63190b57cec5SDimitry Andric } 63200b57cec5SDimitry Andric 63210b57cec5SDimitry Andric /// Check that one use is in the same block as the definition and all 63220b57cec5SDimitry Andric /// other uses are in blocks dominated by a given block. 63230b57cec5SDimitry Andric /// 63240b57cec5SDimitry Andric /// \param DI Definition 63250b57cec5SDimitry Andric /// \param UI Use 63260b57cec5SDimitry Andric /// \param DB Block that must dominate all uses of \p DI outside 63270b57cec5SDimitry Andric /// the parent block 63280b57cec5SDimitry Andric /// \return true when \p UI is the only use of \p DI in the parent block 63290b57cec5SDimitry Andric /// and all other uses of \p DI are in blocks dominated by \p DB. 63300b57cec5SDimitry Andric /// 6331e8d8bef9SDimitry Andric bool InstCombinerImpl::dominatesAllUses(const Instruction *DI, 63320b57cec5SDimitry Andric const Instruction *UI, 63330b57cec5SDimitry Andric const BasicBlock *DB) const { 63340b57cec5SDimitry Andric assert(DI && UI && "Instruction not defined\n"); 63350b57cec5SDimitry Andric // Ignore incomplete definitions. 63360b57cec5SDimitry Andric if (!DI->getParent()) 63370b57cec5SDimitry Andric return false; 63380b57cec5SDimitry Andric // DI and UI must be in the same block. 63390b57cec5SDimitry Andric if (DI->getParent() != UI->getParent()) 63400b57cec5SDimitry Andric return false; 63410b57cec5SDimitry Andric // Protect from self-referencing blocks. 63420b57cec5SDimitry Andric if (DI->getParent() == DB) 63430b57cec5SDimitry Andric return false; 63440b57cec5SDimitry Andric for (const User *U : DI->users()) { 63450b57cec5SDimitry Andric auto *Usr = cast<Instruction>(U); 63460b57cec5SDimitry Andric if (Usr != UI && !DT.dominates(DB, Usr->getParent())) 63470b57cec5SDimitry Andric return false; 63480b57cec5SDimitry Andric } 63490b57cec5SDimitry Andric return true; 63500b57cec5SDimitry Andric } 63510b57cec5SDimitry Andric 63520b57cec5SDimitry Andric /// Return true when the instruction sequence within a block is select-cmp-br. 63530b57cec5SDimitry Andric static bool isChainSelectCmpBranch(const SelectInst *SI) { 63540b57cec5SDimitry Andric const BasicBlock *BB = SI->getParent(); 63550b57cec5SDimitry Andric if (!BB) 63560b57cec5SDimitry Andric return false; 63570b57cec5SDimitry Andric auto *BI = dyn_cast_or_null<BranchInst>(BB->getTerminator()); 63580b57cec5SDimitry Andric if (!BI || BI->getNumSuccessors() != 2) 63590b57cec5SDimitry Andric return false; 63600b57cec5SDimitry Andric auto *IC = dyn_cast<ICmpInst>(BI->getCondition()); 63610b57cec5SDimitry Andric if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI)) 63620b57cec5SDimitry Andric return false; 63630b57cec5SDimitry Andric return true; 63640b57cec5SDimitry Andric } 63650b57cec5SDimitry Andric 63660b57cec5SDimitry Andric /// True when a select result is replaced by one of its operands 63670b57cec5SDimitry Andric /// in select-icmp sequence. This will eventually result in the elimination 63680b57cec5SDimitry Andric /// of the select. 63690b57cec5SDimitry Andric /// 63700b57cec5SDimitry Andric /// \param SI Select instruction 63710b57cec5SDimitry Andric /// \param Icmp Compare instruction 63720b57cec5SDimitry Andric /// \param SIOpd Operand that replaces the select 63730b57cec5SDimitry Andric /// 63740b57cec5SDimitry Andric /// Notes: 63750b57cec5SDimitry Andric /// - The replacement is global and requires dominator information 63760b57cec5SDimitry Andric /// - The caller is responsible for the actual replacement 63770b57cec5SDimitry Andric /// 63780b57cec5SDimitry Andric /// Example: 63790b57cec5SDimitry Andric /// 63800b57cec5SDimitry Andric /// entry: 63810b57cec5SDimitry Andric /// %4 = select i1 %3, %C* %0, %C* null 63820b57cec5SDimitry Andric /// %5 = icmp eq %C* %4, null 63830b57cec5SDimitry Andric /// br i1 %5, label %9, label %7 63840b57cec5SDimitry Andric /// ... 63850b57cec5SDimitry Andric /// ; <label>:7 ; preds = %entry 63860b57cec5SDimitry Andric /// %8 = getelementptr inbounds %C* %4, i64 0, i32 0 63870b57cec5SDimitry Andric /// ... 63880b57cec5SDimitry Andric /// 63890b57cec5SDimitry Andric /// can be transformed to 63900b57cec5SDimitry Andric /// 63910b57cec5SDimitry Andric /// %5 = icmp eq %C* %0, null 63920b57cec5SDimitry Andric /// %6 = select i1 %3, i1 %5, i1 true 63930b57cec5SDimitry Andric /// br i1 %6, label %9, label %7 63940b57cec5SDimitry Andric /// ... 63950b57cec5SDimitry Andric /// ; <label>:7 ; preds = %entry 63960b57cec5SDimitry Andric /// %8 = getelementptr inbounds %C* %0, i64 0, i32 0 // replace by %0! 63970b57cec5SDimitry Andric /// 63980b57cec5SDimitry Andric /// Similar when the first operand of the select is a constant or/and 63990b57cec5SDimitry Andric /// the compare is for not equal rather than equal. 64000b57cec5SDimitry Andric /// 64010b57cec5SDimitry Andric /// NOTE: The function is only called when the select and compare constants 64020b57cec5SDimitry Andric /// are equal, the optimization can work only for EQ predicates. This is not a 64030b57cec5SDimitry Andric /// major restriction since a NE compare should be 'normalized' to an equal 64040b57cec5SDimitry Andric /// compare, which usually happens in the combiner and test case 64050b57cec5SDimitry Andric /// select-cmp-br.ll checks for it. 6406e8d8bef9SDimitry Andric bool InstCombinerImpl::replacedSelectWithOperand(SelectInst *SI, 64070b57cec5SDimitry Andric const ICmpInst *Icmp, 64080b57cec5SDimitry Andric const unsigned SIOpd) { 64090b57cec5SDimitry Andric assert((SIOpd == 1 || SIOpd == 2) && "Invalid select operand!"); 64100b57cec5SDimitry Andric if (isChainSelectCmpBranch(SI) && Icmp->getPredicate() == ICmpInst::ICMP_EQ) { 64110b57cec5SDimitry Andric BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1); 64120b57cec5SDimitry Andric // The check for the single predecessor is not the best that can be 64130b57cec5SDimitry Andric // done. But it protects efficiently against cases like when SI's 64140b57cec5SDimitry Andric // home block has two successors, Succ and Succ1, and Succ1 predecessor 64150b57cec5SDimitry Andric // of Succ. Then SI can't be replaced by SIOpd because the use that gets 64160b57cec5SDimitry Andric // replaced can be reached on either path. So the uniqueness check 64170b57cec5SDimitry Andric // guarantees that the path all uses of SI (outside SI's parent) are on 64180b57cec5SDimitry Andric // is disjoint from all other paths out of SI. But that information 64190b57cec5SDimitry Andric // is more expensive to compute, and the trade-off here is in favor 64200b57cec5SDimitry Andric // of compile-time. It should also be noticed that we check for a single 64210b57cec5SDimitry Andric // predecessor and not only uniqueness. This to handle the situation when 64220b57cec5SDimitry Andric // Succ and Succ1 points to the same basic block. 64230b57cec5SDimitry Andric if (Succ->getSinglePredecessor() && dominatesAllUses(SI, Icmp, Succ)) { 64240b57cec5SDimitry Andric NumSel++; 64250b57cec5SDimitry Andric SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent()); 64260b57cec5SDimitry Andric return true; 64270b57cec5SDimitry Andric } 64280b57cec5SDimitry Andric } 64290b57cec5SDimitry Andric return false; 64300b57cec5SDimitry Andric } 64310b57cec5SDimitry Andric 64320b57cec5SDimitry Andric /// Try to fold the comparison based on range information we can get by checking 64330b57cec5SDimitry Andric /// whether bits are known to be zero or one in the inputs. 6434e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) { 64350b57cec5SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 64360b57cec5SDimitry Andric Type *Ty = Op0->getType(); 64370b57cec5SDimitry Andric ICmpInst::Predicate Pred = I.getPredicate(); 64380b57cec5SDimitry Andric 64390b57cec5SDimitry Andric // Get scalar or pointer size. 64400b57cec5SDimitry Andric unsigned BitWidth = Ty->isIntOrIntVectorTy() 64410b57cec5SDimitry Andric ? Ty->getScalarSizeInBits() 6442480093f4SDimitry Andric : DL.getPointerTypeSizeInBits(Ty->getScalarType()); 64430b57cec5SDimitry Andric 64440b57cec5SDimitry Andric if (!BitWidth) 64450b57cec5SDimitry Andric return nullptr; 64460b57cec5SDimitry Andric 64470b57cec5SDimitry Andric KnownBits Op0Known(BitWidth); 64480b57cec5SDimitry Andric KnownBits Op1Known(BitWidth); 64490b57cec5SDimitry Andric 64505f757f3fSDimitry Andric { 64515f757f3fSDimitry Andric // Don't use dominating conditions when folding icmp using known bits. This 64525f757f3fSDimitry Andric // may convert signed into unsigned predicates in ways that other passes 64535f757f3fSDimitry Andric // (especially IndVarSimplify) may not be able to reliably undo. 6454*0fca6ea1SDimitry Andric SimplifyQuery Q = SQ.getWithoutDomCondCache().getWithInstruction(&I); 64555f757f3fSDimitry Andric if (SimplifyDemandedBits(&I, 0, getDemandedBitsLHSMask(I, BitWidth), 6456*0fca6ea1SDimitry Andric Op0Known, /*Depth=*/0, Q)) 64570b57cec5SDimitry Andric return &I; 64580b57cec5SDimitry Andric 6459*0fca6ea1SDimitry Andric if (SimplifyDemandedBits(&I, 1, APInt::getAllOnes(BitWidth), Op1Known, 6460*0fca6ea1SDimitry Andric /*Depth=*/0, Q)) 64610b57cec5SDimitry Andric return &I; 64625f757f3fSDimitry Andric } 64630b57cec5SDimitry Andric 64640b57cec5SDimitry Andric // Given the known and unknown bits, compute a range that the LHS could be 64650b57cec5SDimitry Andric // in. Compute the Min, Max and RHS values based on the known bits. For the 64660b57cec5SDimitry Andric // EQ and NE we use unsigned values. 64670b57cec5SDimitry Andric APInt Op0Min(BitWidth, 0), Op0Max(BitWidth, 0); 64680b57cec5SDimitry Andric APInt Op1Min(BitWidth, 0), Op1Max(BitWidth, 0); 64690b57cec5SDimitry Andric if (I.isSigned()) { 6470e8d8bef9SDimitry Andric Op0Min = Op0Known.getSignedMinValue(); 6471e8d8bef9SDimitry Andric Op0Max = Op0Known.getSignedMaxValue(); 6472e8d8bef9SDimitry Andric Op1Min = Op1Known.getSignedMinValue(); 6473e8d8bef9SDimitry Andric Op1Max = Op1Known.getSignedMaxValue(); 64740b57cec5SDimitry Andric } else { 6475e8d8bef9SDimitry Andric Op0Min = Op0Known.getMinValue(); 6476e8d8bef9SDimitry Andric Op0Max = Op0Known.getMaxValue(); 6477e8d8bef9SDimitry Andric Op1Min = Op1Known.getMinValue(); 6478e8d8bef9SDimitry Andric Op1Max = Op1Known.getMaxValue(); 64790b57cec5SDimitry Andric } 64800b57cec5SDimitry Andric 64810b57cec5SDimitry Andric // If Min and Max are known to be the same, then SimplifyDemandedBits figured 64820b57cec5SDimitry Andric // out that the LHS or RHS is a constant. Constant fold this now, so that 64830b57cec5SDimitry Andric // code below can assume that Min != Max. 64840b57cec5SDimitry Andric if (!isa<Constant>(Op0) && Op0Min == Op0Max) 64850b57cec5SDimitry Andric return new ICmpInst(Pred, ConstantExpr::getIntegerValue(Ty, Op0Min), Op1); 64860b57cec5SDimitry Andric if (!isa<Constant>(Op1) && Op1Min == Op1Max) 64870b57cec5SDimitry Andric return new ICmpInst(Pred, Op0, ConstantExpr::getIntegerValue(Ty, Op1Min)); 64880b57cec5SDimitry Andric 64896e75b2fbSDimitry Andric // Don't break up a clamp pattern -- (min(max X, Y), Z) -- by replacing a 64906e75b2fbSDimitry Andric // min/max canonical compare with some other compare. That could lead to 64916e75b2fbSDimitry Andric // conflict with select canonicalization and infinite looping. 64926e75b2fbSDimitry Andric // FIXME: This constraint may go away if min/max intrinsics are canonical. 64936e75b2fbSDimitry Andric auto isMinMaxCmp = [&](Instruction &Cmp) { 64946e75b2fbSDimitry Andric if (!Cmp.hasOneUse()) 64956e75b2fbSDimitry Andric return false; 64966e75b2fbSDimitry Andric Value *A, *B; 64976e75b2fbSDimitry Andric SelectPatternFlavor SPF = matchSelectPattern(Cmp.user_back(), A, B).Flavor; 64986e75b2fbSDimitry Andric if (!SelectPatternResult::isMinOrMax(SPF)) 64996e75b2fbSDimitry Andric return false; 65006e75b2fbSDimitry Andric return match(Op0, m_MaxOrMin(m_Value(), m_Value())) || 65016e75b2fbSDimitry Andric match(Op1, m_MaxOrMin(m_Value(), m_Value())); 65026e75b2fbSDimitry Andric }; 65036e75b2fbSDimitry Andric if (!isMinMaxCmp(I)) { 65046e75b2fbSDimitry Andric switch (Pred) { 65056e75b2fbSDimitry Andric default: 65066e75b2fbSDimitry Andric break; 65076e75b2fbSDimitry Andric case ICmpInst::ICMP_ULT: { 65086e75b2fbSDimitry Andric if (Op1Min == Op0Max) // A <u B -> A != B if max(A) == min(B) 65096e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); 65106e75b2fbSDimitry Andric const APInt *CmpC; 65116e75b2fbSDimitry Andric if (match(Op1, m_APInt(CmpC))) { 65126e75b2fbSDimitry Andric // A <u C -> A == C-1 if min(A)+1 == C 65136e75b2fbSDimitry Andric if (*CmpC == Op0Min + 1) 65146e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, 65156e75b2fbSDimitry Andric ConstantInt::get(Op1->getType(), *CmpC - 1)); 65166e75b2fbSDimitry Andric // X <u C --> X == 0, if the number of zero bits in the bottom of X 65176e75b2fbSDimitry Andric // exceeds the log2 of C. 65186e75b2fbSDimitry Andric if (Op0Known.countMinTrailingZeros() >= CmpC->ceilLogBase2()) 65196e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, 65206e75b2fbSDimitry Andric Constant::getNullValue(Op1->getType())); 65216e75b2fbSDimitry Andric } 65226e75b2fbSDimitry Andric break; 65236e75b2fbSDimitry Andric } 65246e75b2fbSDimitry Andric case ICmpInst::ICMP_UGT: { 65256e75b2fbSDimitry Andric if (Op1Max == Op0Min) // A >u B -> A != B if min(A) == max(B) 65266e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); 65276e75b2fbSDimitry Andric const APInt *CmpC; 65286e75b2fbSDimitry Andric if (match(Op1, m_APInt(CmpC))) { 65296e75b2fbSDimitry Andric // A >u C -> A == C+1 if max(a)-1 == C 65306e75b2fbSDimitry Andric if (*CmpC == Op0Max - 1) 65316e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, 65326e75b2fbSDimitry Andric ConstantInt::get(Op1->getType(), *CmpC + 1)); 65336e75b2fbSDimitry Andric // X >u C --> X != 0, if the number of zero bits in the bottom of X 65346e75b2fbSDimitry Andric // exceeds the log2 of C. 65356e75b2fbSDimitry Andric if (Op0Known.countMinTrailingZeros() >= CmpC->getActiveBits()) 65366e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, 65376e75b2fbSDimitry Andric Constant::getNullValue(Op1->getType())); 65386e75b2fbSDimitry Andric } 65396e75b2fbSDimitry Andric break; 65406e75b2fbSDimitry Andric } 65416e75b2fbSDimitry Andric case ICmpInst::ICMP_SLT: { 65426e75b2fbSDimitry Andric if (Op1Min == Op0Max) // A <s B -> A != B if max(A) == min(B) 65436e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); 65446e75b2fbSDimitry Andric const APInt *CmpC; 65456e75b2fbSDimitry Andric if (match(Op1, m_APInt(CmpC))) { 65466e75b2fbSDimitry Andric if (*CmpC == Op0Min + 1) // A <s C -> A == C-1 if min(A)+1 == C 65476e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, 65486e75b2fbSDimitry Andric ConstantInt::get(Op1->getType(), *CmpC - 1)); 65496e75b2fbSDimitry Andric } 65506e75b2fbSDimitry Andric break; 65516e75b2fbSDimitry Andric } 65526e75b2fbSDimitry Andric case ICmpInst::ICMP_SGT: { 65536e75b2fbSDimitry Andric if (Op1Max == Op0Min) // A >s B -> A != B if min(A) == max(B) 65546e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); 65556e75b2fbSDimitry Andric const APInt *CmpC; 65566e75b2fbSDimitry Andric if (match(Op1, m_APInt(CmpC))) { 65576e75b2fbSDimitry Andric if (*CmpC == Op0Max - 1) // A >s C -> A == C+1 if max(A)-1 == C 65586e75b2fbSDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, 65596e75b2fbSDimitry Andric ConstantInt::get(Op1->getType(), *CmpC + 1)); 65606e75b2fbSDimitry Andric } 65616e75b2fbSDimitry Andric break; 65626e75b2fbSDimitry Andric } 65636e75b2fbSDimitry Andric } 65646e75b2fbSDimitry Andric } 65656e75b2fbSDimitry Andric 65660b57cec5SDimitry Andric // Based on the range information we know about the LHS, see if we can 65670b57cec5SDimitry Andric // simplify this comparison. For example, (x&4) < 8 is always true. 65680b57cec5SDimitry Andric switch (Pred) { 65690b57cec5SDimitry Andric default: 65700b57cec5SDimitry Andric llvm_unreachable("Unknown icmp opcode!"); 65710b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: 65720b57cec5SDimitry Andric case ICmpInst::ICMP_NE: { 6573e8d8bef9SDimitry Andric if (Op0Max.ult(Op1Min) || Op0Min.ugt(Op1Max)) 6574e8d8bef9SDimitry Andric return replaceInstUsesWith( 6575e8d8bef9SDimitry Andric I, ConstantInt::getBool(I.getType(), Pred == CmpInst::ICMP_NE)); 65760b57cec5SDimitry Andric 65770b57cec5SDimitry Andric // If all bits are known zero except for one, then we know at most one bit 65780b57cec5SDimitry Andric // is set. If the comparison is against zero, then this is a check to see if 65790b57cec5SDimitry Andric // *that* bit is set. 65800b57cec5SDimitry Andric APInt Op0KnownZeroInverted = ~Op0Known.Zero; 65810b57cec5SDimitry Andric if (Op1Known.isZero()) { 65820b57cec5SDimitry Andric // If the LHS is an AND with the same constant, look through it. 65830b57cec5SDimitry Andric Value *LHS = nullptr; 65840b57cec5SDimitry Andric const APInt *LHSC; 65850b57cec5SDimitry Andric if (!match(Op0, m_And(m_Value(LHS), m_APInt(LHSC))) || 65860b57cec5SDimitry Andric *LHSC != Op0KnownZeroInverted) 65870b57cec5SDimitry Andric LHS = Op0; 65880b57cec5SDimitry Andric 65890b57cec5SDimitry Andric Value *X; 659081ad6265SDimitry Andric const APInt *C1; 659181ad6265SDimitry Andric if (match(LHS, m_Shl(m_Power2(C1), m_Value(X)))) { 65920b57cec5SDimitry Andric Type *XTy = X->getType(); 659306c3fb27SDimitry Andric unsigned Log2C1 = C1->countr_zero(); 659481ad6265SDimitry Andric APInt C2 = Op0KnownZeroInverted; 659581ad6265SDimitry Andric APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1; 659681ad6265SDimitry Andric if (C2Pow2.isPowerOf2()) { 659781ad6265SDimitry Andric // iff (C1 is pow2) & ((C2 & ~(C1-1)) + C1) is pow2): 659881ad6265SDimitry Andric // ((C1 << X) & C2) == 0 -> X >= (Log2(C2+C1) - Log2(C1)) 659981ad6265SDimitry Andric // ((C1 << X) & C2) != 0 -> X < (Log2(C2+C1) - Log2(C1)) 660006c3fb27SDimitry Andric unsigned Log2C2 = C2Pow2.countr_zero(); 660181ad6265SDimitry Andric auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1); 66020b57cec5SDimitry Andric auto NewPred = 66030b57cec5SDimitry Andric Pred == CmpInst::ICMP_EQ ? CmpInst::ICMP_UGE : CmpInst::ICMP_ULT; 66040b57cec5SDimitry Andric return new ICmpInst(NewPred, X, CmpC); 66050b57cec5SDimitry Andric } 66060b57cec5SDimitry Andric } 66070b57cec5SDimitry Andric } 66081ac55f4cSDimitry Andric 66091ac55f4cSDimitry Andric // Op0 eq C_Pow2 -> Op0 ne 0 if Op0 is known to be C_Pow2 or zero. 66101ac55f4cSDimitry Andric if (Op1Known.isConstant() && Op1Known.getConstant().isPowerOf2() && 66111ac55f4cSDimitry Andric (Op0Known & Op1Known) == Op0Known) 66121ac55f4cSDimitry Andric return new ICmpInst(CmpInst::getInversePredicate(Pred), Op0, 66131ac55f4cSDimitry Andric ConstantInt::getNullValue(Op1->getType())); 66140b57cec5SDimitry Andric break; 66150b57cec5SDimitry Andric } 66160b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: { 66170b57cec5SDimitry Andric if (Op0Max.ult(Op1Min)) // A <u B -> true if max(A) < min(B) 66180b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66190b57cec5SDimitry Andric if (Op0Min.uge(Op1Max)) // A <u B -> false if min(A) >= max(B) 66200b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66210b57cec5SDimitry Andric break; 66220b57cec5SDimitry Andric } 66230b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: { 66240b57cec5SDimitry Andric if (Op0Min.ugt(Op1Max)) // A >u B -> true if min(A) > max(B) 66250b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66260b57cec5SDimitry Andric if (Op0Max.ule(Op1Min)) // A >u B -> false if max(A) <= max(B) 66270b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66280b57cec5SDimitry Andric break; 66290b57cec5SDimitry Andric } 66300b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: { 66310b57cec5SDimitry Andric if (Op0Max.slt(Op1Min)) // A <s B -> true if max(A) < min(C) 66320b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66330b57cec5SDimitry Andric if (Op0Min.sge(Op1Max)) // A <s B -> false if min(A) >= max(C) 66340b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66350b57cec5SDimitry Andric break; 66360b57cec5SDimitry Andric } 66370b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: { 66380b57cec5SDimitry Andric if (Op0Min.sgt(Op1Max)) // A >s B -> true if min(A) > max(B) 66390b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66400b57cec5SDimitry Andric if (Op0Max.sle(Op1Min)) // A >s B -> false if max(A) <= min(B) 66410b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66420b57cec5SDimitry Andric break; 66430b57cec5SDimitry Andric } 66440b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: 66450b57cec5SDimitry Andric assert(!isa<ConstantInt>(Op1) && "ICMP_SGE with ConstantInt not folded!"); 66460b57cec5SDimitry Andric if (Op0Min.sge(Op1Max)) // A >=s B -> true if min(A) >= max(B) 66470b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66480b57cec5SDimitry Andric if (Op0Max.slt(Op1Min)) // A >=s B -> false if max(A) < min(B) 66490b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66500b57cec5SDimitry Andric if (Op1Min == Op0Max) // A >=s B -> A == B if max(A) == min(B) 66510b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); 66520b57cec5SDimitry Andric break; 66530b57cec5SDimitry Andric case ICmpInst::ICMP_SLE: 66540b57cec5SDimitry Andric assert(!isa<ConstantInt>(Op1) && "ICMP_SLE with ConstantInt not folded!"); 66550b57cec5SDimitry Andric if (Op0Max.sle(Op1Min)) // A <=s B -> true if max(A) <= min(B) 66560b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66570b57cec5SDimitry Andric if (Op0Min.sgt(Op1Max)) // A <=s B -> false if min(A) > max(B) 66580b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66590b57cec5SDimitry Andric if (Op1Max == Op0Min) // A <=s B -> A == B if min(A) == max(B) 66600b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); 66610b57cec5SDimitry Andric break; 66620b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: 66630b57cec5SDimitry Andric assert(!isa<ConstantInt>(Op1) && "ICMP_UGE with ConstantInt not folded!"); 66640b57cec5SDimitry Andric if (Op0Min.uge(Op1Max)) // A >=u B -> true if min(A) >= max(B) 66650b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66660b57cec5SDimitry Andric if (Op0Max.ult(Op1Min)) // A >=u B -> false if max(A) < min(B) 66670b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66680b57cec5SDimitry Andric if (Op1Min == Op0Max) // A >=u B -> A == B if max(A) == min(B) 66690b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); 66700b57cec5SDimitry Andric break; 66710b57cec5SDimitry Andric case ICmpInst::ICMP_ULE: 66720b57cec5SDimitry Andric assert(!isa<ConstantInt>(Op1) && "ICMP_ULE with ConstantInt not folded!"); 66730b57cec5SDimitry Andric if (Op0Max.ule(Op1Min)) // A <=u B -> true if max(A) <= min(B) 66740b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 66750b57cec5SDimitry Andric if (Op0Min.ugt(Op1Max)) // A <=u B -> false if min(A) > max(B) 66760b57cec5SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 66770b57cec5SDimitry Andric if (Op1Max == Op0Min) // A <=u B -> A == B if min(A) == max(B) 66780b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); 66790b57cec5SDimitry Andric break; 66800b57cec5SDimitry Andric } 66810b57cec5SDimitry Andric 66820b57cec5SDimitry Andric // Turn a signed comparison into an unsigned one if both operands are known to 66830b57cec5SDimitry Andric // have the same sign. 66840b57cec5SDimitry Andric if (I.isSigned() && 66850b57cec5SDimitry Andric ((Op0Known.Zero.isNegative() && Op1Known.Zero.isNegative()) || 66860b57cec5SDimitry Andric (Op0Known.One.isNegative() && Op1Known.One.isNegative()))) 66870b57cec5SDimitry Andric return new ICmpInst(I.getUnsignedPredicate(), Op0, Op1); 66880b57cec5SDimitry Andric 66890b57cec5SDimitry Andric return nullptr; 66900b57cec5SDimitry Andric } 66910b57cec5SDimitry Andric 669281ad6265SDimitry Andric /// If one operand of an icmp is effectively a bool (value range of {0,1}), 669381ad6265SDimitry Andric /// then try to reduce patterns based on that limit. 669406c3fb27SDimitry Andric Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) { 669581ad6265SDimitry Andric Value *X, *Y; 669681ad6265SDimitry Andric ICmpInst::Predicate Pred; 669781ad6265SDimitry Andric 669881ad6265SDimitry Andric // X must be 0 and bool must be true for "ULT": 669981ad6265SDimitry Andric // X <u (zext i1 Y) --> (X == 0) & Y 670081ad6265SDimitry Andric if (match(&I, m_c_ICmp(Pred, m_Value(X), m_OneUse(m_ZExt(m_Value(Y))))) && 670181ad6265SDimitry Andric Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULT) 670281ad6265SDimitry Andric return BinaryOperator::CreateAnd(Builder.CreateIsNull(X), Y); 670381ad6265SDimitry Andric 670481ad6265SDimitry Andric // X must be 0 or bool must be true for "ULE": 670581ad6265SDimitry Andric // X <=u (sext i1 Y) --> (X == 0) | Y 670681ad6265SDimitry Andric if (match(&I, m_c_ICmp(Pred, m_Value(X), m_OneUse(m_SExt(m_Value(Y))))) && 670781ad6265SDimitry Andric Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE) 670881ad6265SDimitry Andric return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y); 670981ad6265SDimitry Andric 67105f757f3fSDimitry Andric // icmp eq/ne X, (zext/sext (icmp eq/ne X, C)) 67115f757f3fSDimitry Andric ICmpInst::Predicate Pred1, Pred2; 671206c3fb27SDimitry Andric const APInt *C; 67135f757f3fSDimitry Andric Instruction *ExtI; 67145f757f3fSDimitry Andric if (match(&I, m_c_ICmp(Pred1, m_Value(X), 67155f757f3fSDimitry Andric m_CombineAnd(m_Instruction(ExtI), 67165f757f3fSDimitry Andric m_ZExtOrSExt(m_ICmp(Pred2, m_Deferred(X), 67175f757f3fSDimitry Andric m_APInt(C)))))) && 67185f757f3fSDimitry Andric ICmpInst::isEquality(Pred1) && ICmpInst::isEquality(Pred2)) { 67195f757f3fSDimitry Andric bool IsSExt = ExtI->getOpcode() == Instruction::SExt; 67205f757f3fSDimitry Andric bool HasOneUse = ExtI->hasOneUse() && ExtI->getOperand(0)->hasOneUse(); 67215f757f3fSDimitry Andric auto CreateRangeCheck = [&] { 67225f757f3fSDimitry Andric Value *CmpV1 = 67235f757f3fSDimitry Andric Builder.CreateICmp(Pred1, X, Constant::getNullValue(X->getType())); 67245f757f3fSDimitry Andric Value *CmpV2 = Builder.CreateICmp( 67255f757f3fSDimitry Andric Pred1, X, ConstantInt::getSigned(X->getType(), IsSExt ? -1 : 1)); 67265f757f3fSDimitry Andric return BinaryOperator::Create( 67275f757f3fSDimitry Andric Pred1 == ICmpInst::ICMP_EQ ? Instruction::Or : Instruction::And, 67285f757f3fSDimitry Andric CmpV1, CmpV2); 67295f757f3fSDimitry Andric }; 67305f757f3fSDimitry Andric if (C->isZero()) { 67315f757f3fSDimitry Andric if (Pred2 == ICmpInst::ICMP_EQ) { 67325f757f3fSDimitry Andric // icmp eq X, (zext/sext (icmp eq X, 0)) --> false 67335f757f3fSDimitry Andric // icmp ne X, (zext/sext (icmp eq X, 0)) --> true 67345f757f3fSDimitry Andric return replaceInstUsesWith( 67355f757f3fSDimitry Andric I, ConstantInt::getBool(I.getType(), Pred1 == ICmpInst::ICMP_NE)); 67365f757f3fSDimitry Andric } else if (!IsSExt || HasOneUse) { 67375f757f3fSDimitry Andric // icmp eq X, (zext (icmp ne X, 0)) --> X == 0 || X == 1 67385f757f3fSDimitry Andric // icmp ne X, (zext (icmp ne X, 0)) --> X != 0 && X != 1 67395f757f3fSDimitry Andric // icmp eq X, (sext (icmp ne X, 0)) --> X == 0 || X == -1 67405f757f3fSDimitry Andric // icmp ne X, (sext (icmp ne X, 0)) --> X != 0 && X == -1 67415f757f3fSDimitry Andric return CreateRangeCheck(); 674206c3fb27SDimitry Andric } 67435f757f3fSDimitry Andric } else if (IsSExt ? C->isAllOnes() : C->isOne()) { 67445f757f3fSDimitry Andric if (Pred2 == ICmpInst::ICMP_NE) { 67455f757f3fSDimitry Andric // icmp eq X, (zext (icmp ne X, 1)) --> false 67465f757f3fSDimitry Andric // icmp ne X, (zext (icmp ne X, 1)) --> true 67475f757f3fSDimitry Andric // icmp eq X, (sext (icmp ne X, -1)) --> false 67485f757f3fSDimitry Andric // icmp ne X, (sext (icmp ne X, -1)) --> true 67495f757f3fSDimitry Andric return replaceInstUsesWith( 67505f757f3fSDimitry Andric I, ConstantInt::getBool(I.getType(), Pred1 == ICmpInst::ICMP_NE)); 67515f757f3fSDimitry Andric } else if (!IsSExt || HasOneUse) { 67525f757f3fSDimitry Andric // icmp eq X, (zext (icmp eq X, 1)) --> X == 0 || X == 1 67535f757f3fSDimitry Andric // icmp ne X, (zext (icmp eq X, 1)) --> X != 0 && X != 1 67545f757f3fSDimitry Andric // icmp eq X, (sext (icmp eq X, -1)) --> X == 0 || X == -1 67555f757f3fSDimitry Andric // icmp ne X, (sext (icmp eq X, -1)) --> X != 0 && X == -1 67565f757f3fSDimitry Andric return CreateRangeCheck(); 675706c3fb27SDimitry Andric } 67585f757f3fSDimitry Andric } else { 67595f757f3fSDimitry Andric // when C != 0 && C != 1: 67605f757f3fSDimitry Andric // icmp eq X, (zext (icmp eq X, C)) --> icmp eq X, 0 67615f757f3fSDimitry Andric // icmp eq X, (zext (icmp ne X, C)) --> icmp eq X, 1 67625f757f3fSDimitry Andric // icmp ne X, (zext (icmp eq X, C)) --> icmp ne X, 0 67635f757f3fSDimitry Andric // icmp ne X, (zext (icmp ne X, C)) --> icmp ne X, 1 67645f757f3fSDimitry Andric // when C != 0 && C != -1: 67655f757f3fSDimitry Andric // icmp eq X, (sext (icmp eq X, C)) --> icmp eq X, 0 67665f757f3fSDimitry Andric // icmp eq X, (sext (icmp ne X, C)) --> icmp eq X, -1 67675f757f3fSDimitry Andric // icmp ne X, (sext (icmp eq X, C)) --> icmp ne X, 0 67685f757f3fSDimitry Andric // icmp ne X, (sext (icmp ne X, C)) --> icmp ne X, -1 67695f757f3fSDimitry Andric return ICmpInst::Create( 67705f757f3fSDimitry Andric Instruction::ICmp, Pred1, X, 67715f757f3fSDimitry Andric ConstantInt::getSigned(X->getType(), Pred2 == ICmpInst::ICMP_NE 67725f757f3fSDimitry Andric ? (IsSExt ? -1 : 1) 67735f757f3fSDimitry Andric : 0)); 677406c3fb27SDimitry Andric } 677506c3fb27SDimitry Andric } 677606c3fb27SDimitry Andric 677781ad6265SDimitry Andric return nullptr; 677881ad6265SDimitry Andric } 677981ad6265SDimitry Andric 6780bdd1243dSDimitry Andric std::optional<std::pair<CmpInst::Predicate, Constant *>> 6781e8d8bef9SDimitry Andric InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, 67828bcb0991SDimitry Andric Constant *C) { 67838bcb0991SDimitry Andric assert(ICmpInst::isRelational(Pred) && ICmpInst::isIntPredicate(Pred) && 67848bcb0991SDimitry Andric "Only for relational integer predicates."); 67858bcb0991SDimitry Andric 67868bcb0991SDimitry Andric Type *Type = C->getType(); 67878bcb0991SDimitry Andric bool IsSigned = ICmpInst::isSigned(Pred); 67888bcb0991SDimitry Andric 67898bcb0991SDimitry Andric CmpInst::Predicate UnsignedPred = ICmpInst::getUnsignedPredicate(Pred); 67908bcb0991SDimitry Andric bool WillIncrement = 67918bcb0991SDimitry Andric UnsignedPred == ICmpInst::ICMP_ULE || UnsignedPred == ICmpInst::ICMP_UGT; 67928bcb0991SDimitry Andric 67938bcb0991SDimitry Andric // Check if the constant operand can be safely incremented/decremented 67948bcb0991SDimitry Andric // without overflowing/underflowing. 67958bcb0991SDimitry Andric auto ConstantIsOk = [WillIncrement, IsSigned](ConstantInt *C) { 67968bcb0991SDimitry Andric return WillIncrement ? !C->isMaxValue(IsSigned) : !C->isMinValue(IsSigned); 67978bcb0991SDimitry Andric }; 67988bcb0991SDimitry Andric 6799480093f4SDimitry Andric Constant *SafeReplacementConstant = nullptr; 68008bcb0991SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(C)) { 68018bcb0991SDimitry Andric // Bail out if the constant can't be safely incremented/decremented. 68028bcb0991SDimitry Andric if (!ConstantIsOk(CI)) 6803bdd1243dSDimitry Andric return std::nullopt; 6804e8d8bef9SDimitry Andric } else if (auto *FVTy = dyn_cast<FixedVectorType>(Type)) { 6805e8d8bef9SDimitry Andric unsigned NumElts = FVTy->getNumElements(); 68068bcb0991SDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 68078bcb0991SDimitry Andric Constant *Elt = C->getAggregateElement(i); 68088bcb0991SDimitry Andric if (!Elt) 6809bdd1243dSDimitry Andric return std::nullopt; 68108bcb0991SDimitry Andric 68118bcb0991SDimitry Andric if (isa<UndefValue>(Elt)) 68128bcb0991SDimitry Andric continue; 68138bcb0991SDimitry Andric 68148bcb0991SDimitry Andric // Bail out if we can't determine if this constant is min/max or if we 68158bcb0991SDimitry Andric // know that this constant is min/max. 68168bcb0991SDimitry Andric auto *CI = dyn_cast<ConstantInt>(Elt); 68178bcb0991SDimitry Andric if (!CI || !ConstantIsOk(CI)) 6818bdd1243dSDimitry Andric return std::nullopt; 6819480093f4SDimitry Andric 6820480093f4SDimitry Andric if (!SafeReplacementConstant) 6821480093f4SDimitry Andric SafeReplacementConstant = CI; 68228bcb0991SDimitry Andric } 6823439352acSDimitry Andric } else if (isa<VectorType>(C->getType())) { 6824439352acSDimitry Andric // Handle scalable splat 6825439352acSDimitry Andric Value *SplatC = C->getSplatValue(); 6826439352acSDimitry Andric auto *CI = dyn_cast_or_null<ConstantInt>(SplatC); 6827439352acSDimitry Andric // Bail out if the constant can't be safely incremented/decremented. 6828439352acSDimitry Andric if (!CI || !ConstantIsOk(CI)) 6829439352acSDimitry Andric return std::nullopt; 68308bcb0991SDimitry Andric } else { 68318bcb0991SDimitry Andric // ConstantExpr? 6832bdd1243dSDimitry Andric return std::nullopt; 68338bcb0991SDimitry Andric } 68348bcb0991SDimitry Andric 6835480093f4SDimitry Andric // It may not be safe to change a compare predicate in the presence of 6836480093f4SDimitry Andric // undefined elements, so replace those elements with the first safe constant 6837480093f4SDimitry Andric // that we found. 6838e8d8bef9SDimitry Andric // TODO: in case of poison, it is safe; let's replace undefs only. 6839e8d8bef9SDimitry Andric if (C->containsUndefOrPoisonElement()) { 6840480093f4SDimitry Andric assert(SafeReplacementConstant && "Replacement constant not set"); 6841480093f4SDimitry Andric C = Constant::replaceUndefsWith(C, SafeReplacementConstant); 6842480093f4SDimitry Andric } 6843480093f4SDimitry Andric 68448bcb0991SDimitry Andric CmpInst::Predicate NewPred = CmpInst::getFlippedStrictnessPredicate(Pred); 68458bcb0991SDimitry Andric 68468bcb0991SDimitry Andric // Increment or decrement the constant. 68478bcb0991SDimitry Andric Constant *OneOrNegOne = ConstantInt::get(Type, WillIncrement ? 1 : -1, true); 68488bcb0991SDimitry Andric Constant *NewC = ConstantExpr::getAdd(C, OneOrNegOne); 68498bcb0991SDimitry Andric 68508bcb0991SDimitry Andric return std::make_pair(NewPred, NewC); 68518bcb0991SDimitry Andric } 68528bcb0991SDimitry Andric 68530b57cec5SDimitry Andric /// If we have an icmp le or icmp ge instruction with a constant operand, turn 68540b57cec5SDimitry Andric /// it into the appropriate icmp lt or icmp gt instruction. This transform 68550b57cec5SDimitry Andric /// allows them to be folded in visitICmpInst. 68560b57cec5SDimitry Andric static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I) { 68570b57cec5SDimitry Andric ICmpInst::Predicate Pred = I.getPredicate(); 68588bcb0991SDimitry Andric if (ICmpInst::isEquality(Pred) || !ICmpInst::isIntPredicate(Pred) || 6859e8d8bef9SDimitry Andric InstCombiner::isCanonicalPredicate(Pred)) 68600b57cec5SDimitry Andric return nullptr; 68610b57cec5SDimitry Andric 68620b57cec5SDimitry Andric Value *Op0 = I.getOperand(0); 68630b57cec5SDimitry Andric Value *Op1 = I.getOperand(1); 68640b57cec5SDimitry Andric auto *Op1C = dyn_cast<Constant>(Op1); 68650b57cec5SDimitry Andric if (!Op1C) 68660b57cec5SDimitry Andric return nullptr; 68670b57cec5SDimitry Andric 6868e8d8bef9SDimitry Andric auto FlippedStrictness = 6869e8d8bef9SDimitry Andric InstCombiner::getFlippedStrictnessPredicateAndConstant(Pred, Op1C); 68708bcb0991SDimitry Andric if (!FlippedStrictness) 68710b57cec5SDimitry Andric return nullptr; 68720b57cec5SDimitry Andric 68738bcb0991SDimitry Andric return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second); 68740b57cec5SDimitry Andric } 68750b57cec5SDimitry Andric 68765ffd83dbSDimitry Andric /// If we have a comparison with a non-canonical predicate, if we can update 68775ffd83dbSDimitry Andric /// all the users, invert the predicate and adjust all the users. 6878e8d8bef9SDimitry Andric CmpInst *InstCombinerImpl::canonicalizeICmpPredicate(CmpInst &I) { 68795ffd83dbSDimitry Andric // Is the predicate already canonical? 68805ffd83dbSDimitry Andric CmpInst::Predicate Pred = I.getPredicate(); 6881e8d8bef9SDimitry Andric if (InstCombiner::isCanonicalPredicate(Pred)) 68825ffd83dbSDimitry Andric return nullptr; 68835ffd83dbSDimitry Andric 68845ffd83dbSDimitry Andric // Can all users be adjusted to predicate inversion? 6885e8d8bef9SDimitry Andric if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr)) 68865ffd83dbSDimitry Andric return nullptr; 68875ffd83dbSDimitry Andric 68885ffd83dbSDimitry Andric // Ok, we can canonicalize comparison! 68895ffd83dbSDimitry Andric // Let's first invert the comparison's predicate. 68905ffd83dbSDimitry Andric I.setPredicate(CmpInst::getInversePredicate(Pred)); 68915ffd83dbSDimitry Andric I.setName(I.getName() + ".not"); 68925ffd83dbSDimitry Andric 6893e8d8bef9SDimitry Andric // And, adapt users. 6894e8d8bef9SDimitry Andric freelyInvertAllUsersOf(&I); 68955ffd83dbSDimitry Andric 68965ffd83dbSDimitry Andric return &I; 68975ffd83dbSDimitry Andric } 68985ffd83dbSDimitry Andric 68990b57cec5SDimitry Andric /// Integer compare with boolean values can always be turned into bitwise ops. 69000b57cec5SDimitry Andric static Instruction *canonicalizeICmpBool(ICmpInst &I, 69010b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder) { 69020b57cec5SDimitry Andric Value *A = I.getOperand(0), *B = I.getOperand(1); 69030b57cec5SDimitry Andric assert(A->getType()->isIntOrIntVectorTy(1) && "Bools only"); 69040b57cec5SDimitry Andric 69050b57cec5SDimitry Andric // A boolean compared to true/false can be simplified to Op0/true/false in 69060b57cec5SDimitry Andric // 14 out of the 20 (10 predicates * 2 constants) possible combinations. 69070b57cec5SDimitry Andric // Cases not handled by InstSimplify are always 'not' of Op0. 69080b57cec5SDimitry Andric if (match(B, m_Zero())) { 69090b57cec5SDimitry Andric switch (I.getPredicate()) { 69100b57cec5SDimitry Andric case CmpInst::ICMP_EQ: // A == 0 -> !A 69110b57cec5SDimitry Andric case CmpInst::ICMP_ULE: // A <=u 0 -> !A 69120b57cec5SDimitry Andric case CmpInst::ICMP_SGE: // A >=s 0 -> !A 69130b57cec5SDimitry Andric return BinaryOperator::CreateNot(A); 69140b57cec5SDimitry Andric default: 69150b57cec5SDimitry Andric llvm_unreachable("ICmp i1 X, C not simplified as expected."); 69160b57cec5SDimitry Andric } 69170b57cec5SDimitry Andric } else if (match(B, m_One())) { 69180b57cec5SDimitry Andric switch (I.getPredicate()) { 69190b57cec5SDimitry Andric case CmpInst::ICMP_NE: // A != 1 -> !A 69200b57cec5SDimitry Andric case CmpInst::ICMP_ULT: // A <u 1 -> !A 69210b57cec5SDimitry Andric case CmpInst::ICMP_SGT: // A >s -1 -> !A 69220b57cec5SDimitry Andric return BinaryOperator::CreateNot(A); 69230b57cec5SDimitry Andric default: 69240b57cec5SDimitry Andric llvm_unreachable("ICmp i1 X, C not simplified as expected."); 69250b57cec5SDimitry Andric } 69260b57cec5SDimitry Andric } 69270b57cec5SDimitry Andric 69280b57cec5SDimitry Andric switch (I.getPredicate()) { 69290b57cec5SDimitry Andric default: 69300b57cec5SDimitry Andric llvm_unreachable("Invalid icmp instruction!"); 69310b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: 69320b57cec5SDimitry Andric // icmp eq i1 A, B -> ~(A ^ B) 69330b57cec5SDimitry Andric return BinaryOperator::CreateNot(Builder.CreateXor(A, B)); 69340b57cec5SDimitry Andric 69350b57cec5SDimitry Andric case ICmpInst::ICMP_NE: 69360b57cec5SDimitry Andric // icmp ne i1 A, B -> A ^ B 69370b57cec5SDimitry Andric return BinaryOperator::CreateXor(A, B); 69380b57cec5SDimitry Andric 69390b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: 69400b57cec5SDimitry Andric // icmp ugt -> icmp ult 69410b57cec5SDimitry Andric std::swap(A, B); 6942bdd1243dSDimitry Andric [[fallthrough]]; 69430b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: 69440b57cec5SDimitry Andric // icmp ult i1 A, B -> ~A & B 69450b57cec5SDimitry Andric return BinaryOperator::CreateAnd(Builder.CreateNot(A), B); 69460b57cec5SDimitry Andric 69470b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: 69480b57cec5SDimitry Andric // icmp sgt -> icmp slt 69490b57cec5SDimitry Andric std::swap(A, B); 6950bdd1243dSDimitry Andric [[fallthrough]]; 69510b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: 69520b57cec5SDimitry Andric // icmp slt i1 A, B -> A & ~B 69530b57cec5SDimitry Andric return BinaryOperator::CreateAnd(Builder.CreateNot(B), A); 69540b57cec5SDimitry Andric 69550b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: 69560b57cec5SDimitry Andric // icmp uge -> icmp ule 69570b57cec5SDimitry Andric std::swap(A, B); 6958bdd1243dSDimitry Andric [[fallthrough]]; 69590b57cec5SDimitry Andric case ICmpInst::ICMP_ULE: 69600b57cec5SDimitry Andric // icmp ule i1 A, B -> ~A | B 69610b57cec5SDimitry Andric return BinaryOperator::CreateOr(Builder.CreateNot(A), B); 69620b57cec5SDimitry Andric 69630b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: 69640b57cec5SDimitry Andric // icmp sge -> icmp sle 69650b57cec5SDimitry Andric std::swap(A, B); 6966bdd1243dSDimitry Andric [[fallthrough]]; 69670b57cec5SDimitry Andric case ICmpInst::ICMP_SLE: 69680b57cec5SDimitry Andric // icmp sle i1 A, B -> A | ~B 69690b57cec5SDimitry Andric return BinaryOperator::CreateOr(Builder.CreateNot(B), A); 69700b57cec5SDimitry Andric } 69710b57cec5SDimitry Andric } 69720b57cec5SDimitry Andric 69730b57cec5SDimitry Andric // Transform pattern like: 69740b57cec5SDimitry Andric // (1 << Y) u<= X or ~(-1 << Y) u< X or ((1 << Y)+(-1)) u< X 69750b57cec5SDimitry Andric // (1 << Y) u> X or ~(-1 << Y) u>= X or ((1 << Y)+(-1)) u>= X 69760b57cec5SDimitry Andric // Into: 69770b57cec5SDimitry Andric // (X l>> Y) != 0 69780b57cec5SDimitry Andric // (X l>> Y) == 0 69790b57cec5SDimitry Andric static Instruction *foldICmpWithHighBitMask(ICmpInst &Cmp, 69800b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder) { 69810b57cec5SDimitry Andric ICmpInst::Predicate Pred, NewPred; 69820b57cec5SDimitry Andric Value *X, *Y; 69830b57cec5SDimitry Andric if (match(&Cmp, 69840b57cec5SDimitry Andric m_c_ICmp(Pred, m_OneUse(m_Shl(m_One(), m_Value(Y))), m_Value(X)))) { 69850b57cec5SDimitry Andric switch (Pred) { 69860b57cec5SDimitry Andric case ICmpInst::ICMP_ULE: 69870b57cec5SDimitry Andric NewPred = ICmpInst::ICMP_NE; 69880b57cec5SDimitry Andric break; 69890b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: 69900b57cec5SDimitry Andric NewPred = ICmpInst::ICMP_EQ; 69910b57cec5SDimitry Andric break; 69920b57cec5SDimitry Andric default: 69930b57cec5SDimitry Andric return nullptr; 69940b57cec5SDimitry Andric } 69950b57cec5SDimitry Andric } else if (match(&Cmp, m_c_ICmp(Pred, 69960b57cec5SDimitry Andric m_OneUse(m_CombineOr( 69970b57cec5SDimitry Andric m_Not(m_Shl(m_AllOnes(), m_Value(Y))), 69980b57cec5SDimitry Andric m_Add(m_Shl(m_One(), m_Value(Y)), 69990b57cec5SDimitry Andric m_AllOnes()))), 70000b57cec5SDimitry Andric m_Value(X)))) { 70010b57cec5SDimitry Andric // The variant with 'add' is not canonical, (the variant with 'not' is) 70020b57cec5SDimitry Andric // we only get it because it has extra uses, and can't be canonicalized, 70030b57cec5SDimitry Andric 70040b57cec5SDimitry Andric switch (Pred) { 70050b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: 70060b57cec5SDimitry Andric NewPred = ICmpInst::ICMP_NE; 70070b57cec5SDimitry Andric break; 70080b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: 70090b57cec5SDimitry Andric NewPred = ICmpInst::ICMP_EQ; 70100b57cec5SDimitry Andric break; 70110b57cec5SDimitry Andric default: 70120b57cec5SDimitry Andric return nullptr; 70130b57cec5SDimitry Andric } 70140b57cec5SDimitry Andric } else 70150b57cec5SDimitry Andric return nullptr; 70160b57cec5SDimitry Andric 70170b57cec5SDimitry Andric Value *NewX = Builder.CreateLShr(X, Y, X->getName() + ".highbits"); 70180b57cec5SDimitry Andric Constant *Zero = Constant::getNullValue(NewX->getType()); 70190b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, NewPred, NewX, Zero); 70200b57cec5SDimitry Andric } 70210b57cec5SDimitry Andric 70220b57cec5SDimitry Andric static Instruction *foldVectorCmp(CmpInst &Cmp, 70230b57cec5SDimitry Andric InstCombiner::BuilderTy &Builder) { 70245ffd83dbSDimitry Andric const CmpInst::Predicate Pred = Cmp.getPredicate(); 70250b57cec5SDimitry Andric Value *LHS = Cmp.getOperand(0), *RHS = Cmp.getOperand(1); 70260b57cec5SDimitry Andric Value *V1, *V2; 7027bdd1243dSDimitry Andric 7028bdd1243dSDimitry Andric auto createCmpReverse = [&](CmpInst::Predicate Pred, Value *X, Value *Y) { 7029bdd1243dSDimitry Andric Value *V = Builder.CreateCmp(Pred, X, Y, Cmp.getName()); 7030bdd1243dSDimitry Andric if (auto *I = dyn_cast<Instruction>(V)) 7031bdd1243dSDimitry Andric I->copyIRFlags(&Cmp); 7032bdd1243dSDimitry Andric Module *M = Cmp.getModule(); 7033*0fca6ea1SDimitry Andric Function *F = 7034*0fca6ea1SDimitry Andric Intrinsic::getDeclaration(M, Intrinsic::vector_reverse, V->getType()); 7035bdd1243dSDimitry Andric return CallInst::Create(F, V); 7036bdd1243dSDimitry Andric }; 7037bdd1243dSDimitry Andric 7038bdd1243dSDimitry Andric if (match(LHS, m_VecReverse(m_Value(V1)))) { 7039bdd1243dSDimitry Andric // cmp Pred, rev(V1), rev(V2) --> rev(cmp Pred, V1, V2) 7040bdd1243dSDimitry Andric if (match(RHS, m_VecReverse(m_Value(V2))) && 7041bdd1243dSDimitry Andric (LHS->hasOneUse() || RHS->hasOneUse())) 7042bdd1243dSDimitry Andric return createCmpReverse(Pred, V1, V2); 7043bdd1243dSDimitry Andric 7044bdd1243dSDimitry Andric // cmp Pred, rev(V1), RHSSplat --> rev(cmp Pred, V1, RHSSplat) 7045bdd1243dSDimitry Andric if (LHS->hasOneUse() && isSplatValue(RHS)) 7046bdd1243dSDimitry Andric return createCmpReverse(Pred, V1, RHS); 7047bdd1243dSDimitry Andric } 7048bdd1243dSDimitry Andric // cmp Pred, LHSSplat, rev(V2) --> rev(cmp Pred, LHSSplat, V2) 7049bdd1243dSDimitry Andric else if (isSplatValue(LHS) && match(RHS, m_OneUse(m_VecReverse(m_Value(V2))))) 7050bdd1243dSDimitry Andric return createCmpReverse(Pred, LHS, V2); 7051bdd1243dSDimitry Andric 70525ffd83dbSDimitry Andric ArrayRef<int> M; 70535ffd83dbSDimitry Andric if (!match(LHS, m_Shuffle(m_Value(V1), m_Undef(), m_Mask(M)))) 70545ffd83dbSDimitry Andric return nullptr; 70555ffd83dbSDimitry Andric 70565ffd83dbSDimitry Andric // If both arguments of the cmp are shuffles that use the same mask and 70575ffd83dbSDimitry Andric // shuffle within a single vector, move the shuffle after the cmp: 70580b57cec5SDimitry Andric // cmp (shuffle V1, M), (shuffle V2, M) --> shuffle (cmp V1, V2), M 70595ffd83dbSDimitry Andric Type *V1Ty = V1->getType(); 70605ffd83dbSDimitry Andric if (match(RHS, m_Shuffle(m_Value(V2), m_Undef(), m_SpecificMask(M))) && 70615ffd83dbSDimitry Andric V1Ty == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse())) { 70625ffd83dbSDimitry Andric Value *NewCmp = Builder.CreateCmp(Pred, V1, V2); 7063349cc55cSDimitry Andric return new ShuffleVectorInst(NewCmp, M); 70640b57cec5SDimitry Andric } 70655ffd83dbSDimitry Andric 70665ffd83dbSDimitry Andric // Try to canonicalize compare with splatted operand and splat constant. 70675ffd83dbSDimitry Andric // TODO: We could generalize this for more than splats. See/use the code in 70685ffd83dbSDimitry Andric // InstCombiner::foldVectorBinop(). 70695ffd83dbSDimitry Andric Constant *C; 70705ffd83dbSDimitry Andric if (!LHS->hasOneUse() || !match(RHS, m_Constant(C))) 70715ffd83dbSDimitry Andric return nullptr; 70725ffd83dbSDimitry Andric 70735ffd83dbSDimitry Andric // Length-changing splats are ok, so adjust the constants as needed: 70745ffd83dbSDimitry Andric // cmp (shuffle V1, M), C --> shuffle (cmp V1, C'), M 7075*0fca6ea1SDimitry Andric Constant *ScalarC = C->getSplatValue(/* AllowPoison */ true); 70765ffd83dbSDimitry Andric int MaskSplatIndex; 7077*0fca6ea1SDimitry Andric if (ScalarC && match(M, m_SplatOrPoisonMask(MaskSplatIndex))) { 7078*0fca6ea1SDimitry Andric // We allow poison in matching, but this transform removes it for safety. 70795ffd83dbSDimitry Andric // Demanded elements analysis should be able to recover some/all of that. 70805ffd83dbSDimitry Andric C = ConstantVector::getSplat(cast<VectorType>(V1Ty)->getElementCount(), 70815ffd83dbSDimitry Andric ScalarC); 70825ffd83dbSDimitry Andric SmallVector<int, 8> NewM(M.size(), MaskSplatIndex); 70835ffd83dbSDimitry Andric Value *NewCmp = Builder.CreateCmp(Pred, V1, C); 7084349cc55cSDimitry Andric return new ShuffleVectorInst(NewCmp, NewM); 70855ffd83dbSDimitry Andric } 70865ffd83dbSDimitry Andric 70870b57cec5SDimitry Andric return nullptr; 70880b57cec5SDimitry Andric } 70890b57cec5SDimitry Andric 7090480093f4SDimitry Andric // extract(uadd.with.overflow(A, B), 0) ult A 7091480093f4SDimitry Andric // -> extract(uadd.with.overflow(A, B), 1) 7092480093f4SDimitry Andric static Instruction *foldICmpOfUAddOv(ICmpInst &I) { 7093480093f4SDimitry Andric CmpInst::Predicate Pred = I.getPredicate(); 7094480093f4SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 7095480093f4SDimitry Andric 7096480093f4SDimitry Andric Value *UAddOv; 7097480093f4SDimitry Andric Value *A, *B; 7098480093f4SDimitry Andric auto UAddOvResultPat = m_ExtractValue<0>( 7099480093f4SDimitry Andric m_Intrinsic<Intrinsic::uadd_with_overflow>(m_Value(A), m_Value(B))); 7100480093f4SDimitry Andric if (match(Op0, UAddOvResultPat) && 7101480093f4SDimitry Andric ((Pred == ICmpInst::ICMP_ULT && (Op1 == A || Op1 == B)) || 7102480093f4SDimitry Andric (Pred == ICmpInst::ICMP_EQ && match(Op1, m_ZeroInt()) && 7103480093f4SDimitry Andric (match(A, m_One()) || match(B, m_One()))) || 7104480093f4SDimitry Andric (Pred == ICmpInst::ICMP_NE && match(Op1, m_AllOnes()) && 7105480093f4SDimitry Andric (match(A, m_AllOnes()) || match(B, m_AllOnes()))))) 7106480093f4SDimitry Andric // extract(uadd.with.overflow(A, B), 0) < A 7107480093f4SDimitry Andric // extract(uadd.with.overflow(A, 1), 0) == 0 7108480093f4SDimitry Andric // extract(uadd.with.overflow(A, -1), 0) != -1 7109480093f4SDimitry Andric UAddOv = cast<ExtractValueInst>(Op0)->getAggregateOperand(); 7110480093f4SDimitry Andric else if (match(Op1, UAddOvResultPat) && 7111480093f4SDimitry Andric Pred == ICmpInst::ICMP_UGT && (Op0 == A || Op0 == B)) 7112480093f4SDimitry Andric // A > extract(uadd.with.overflow(A, B), 0) 7113480093f4SDimitry Andric UAddOv = cast<ExtractValueInst>(Op1)->getAggregateOperand(); 7114480093f4SDimitry Andric else 7115480093f4SDimitry Andric return nullptr; 7116480093f4SDimitry Andric 7117480093f4SDimitry Andric return ExtractValueInst::Create(UAddOv, 1); 7118480093f4SDimitry Andric } 7119480093f4SDimitry Andric 7120349cc55cSDimitry Andric static Instruction *foldICmpInvariantGroup(ICmpInst &I) { 7121349cc55cSDimitry Andric if (!I.getOperand(0)->getType()->isPointerTy() || 7122349cc55cSDimitry Andric NullPointerIsDefined( 7123349cc55cSDimitry Andric I.getParent()->getParent(), 7124349cc55cSDimitry Andric I.getOperand(0)->getType()->getPointerAddressSpace())) { 7125349cc55cSDimitry Andric return nullptr; 7126349cc55cSDimitry Andric } 7127349cc55cSDimitry Andric Instruction *Op; 7128349cc55cSDimitry Andric if (match(I.getOperand(0), m_Instruction(Op)) && 7129349cc55cSDimitry Andric match(I.getOperand(1), m_Zero()) && 7130349cc55cSDimitry Andric Op->isLaunderOrStripInvariantGroup()) { 7131349cc55cSDimitry Andric return ICmpInst::Create(Instruction::ICmp, I.getPredicate(), 7132349cc55cSDimitry Andric Op->getOperand(0), I.getOperand(1)); 7133349cc55cSDimitry Andric } 7134349cc55cSDimitry Andric return nullptr; 7135349cc55cSDimitry Andric } 7136349cc55cSDimitry Andric 71371fd87a68SDimitry Andric /// This function folds patterns produced by lowering of reduce idioms, such as 71381fd87a68SDimitry Andric /// llvm.vector.reduce.and which are lowered into instruction chains. This code 71391fd87a68SDimitry Andric /// attempts to generate fewer number of scalar comparisons instead of vector 71401fd87a68SDimitry Andric /// comparisons when possible. 71411fd87a68SDimitry Andric static Instruction *foldReductionIdiom(ICmpInst &I, 71421fd87a68SDimitry Andric InstCombiner::BuilderTy &Builder, 71431fd87a68SDimitry Andric const DataLayout &DL) { 71441fd87a68SDimitry Andric if (I.getType()->isVectorTy()) 71451fd87a68SDimitry Andric return nullptr; 71461fd87a68SDimitry Andric ICmpInst::Predicate OuterPred, InnerPred; 71471fd87a68SDimitry Andric Value *LHS, *RHS; 71481fd87a68SDimitry Andric 71491fd87a68SDimitry Andric // Match lowering of @llvm.vector.reduce.and. Turn 71501fd87a68SDimitry Andric /// %vec_ne = icmp ne <8 x i8> %lhs, %rhs 71511fd87a68SDimitry Andric /// %scalar_ne = bitcast <8 x i1> %vec_ne to i8 71521fd87a68SDimitry Andric /// %res = icmp <pred> i8 %scalar_ne, 0 71531fd87a68SDimitry Andric /// 71541fd87a68SDimitry Andric /// into 71551fd87a68SDimitry Andric /// 71561fd87a68SDimitry Andric /// %lhs.scalar = bitcast <8 x i8> %lhs to i64 71571fd87a68SDimitry Andric /// %rhs.scalar = bitcast <8 x i8> %rhs to i64 71581fd87a68SDimitry Andric /// %res = icmp <pred> i64 %lhs.scalar, %rhs.scalar 71591fd87a68SDimitry Andric /// 71601fd87a68SDimitry Andric /// for <pred> in {ne, eq}. 71611fd87a68SDimitry Andric if (!match(&I, m_ICmp(OuterPred, 71621fd87a68SDimitry Andric m_OneUse(m_BitCast(m_OneUse( 71631fd87a68SDimitry Andric m_ICmp(InnerPred, m_Value(LHS), m_Value(RHS))))), 71641fd87a68SDimitry Andric m_Zero()))) 71651fd87a68SDimitry Andric return nullptr; 71661fd87a68SDimitry Andric auto *LHSTy = dyn_cast<FixedVectorType>(LHS->getType()); 71671fd87a68SDimitry Andric if (!LHSTy || !LHSTy->getElementType()->isIntegerTy()) 71681fd87a68SDimitry Andric return nullptr; 71691fd87a68SDimitry Andric unsigned NumBits = 71701fd87a68SDimitry Andric LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth(); 71711fd87a68SDimitry Andric // TODO: Relax this to "not wider than max legal integer type"? 71721fd87a68SDimitry Andric if (!DL.isLegalInteger(NumBits)) 71731fd87a68SDimitry Andric return nullptr; 71741fd87a68SDimitry Andric 71751fd87a68SDimitry Andric if (ICmpInst::isEquality(OuterPred) && InnerPred == ICmpInst::ICMP_NE) { 71761fd87a68SDimitry Andric auto *ScalarTy = Builder.getIntNTy(NumBits); 71771fd87a68SDimitry Andric LHS = Builder.CreateBitCast(LHS, ScalarTy, LHS->getName() + ".scalar"); 71781fd87a68SDimitry Andric RHS = Builder.CreateBitCast(RHS, ScalarTy, RHS->getName() + ".scalar"); 71791fd87a68SDimitry Andric return ICmpInst::Create(Instruction::ICmp, OuterPred, LHS, RHS, 71801fd87a68SDimitry Andric I.getName()); 71811fd87a68SDimitry Andric } 71821fd87a68SDimitry Andric 71831fd87a68SDimitry Andric return nullptr; 71841fd87a68SDimitry Andric } 71851fd87a68SDimitry Andric 7186647cbc5dSDimitry Andric // This helper will be called with icmp operands in both orders. 7187647cbc5dSDimitry Andric Instruction *InstCombinerImpl::foldICmpCommutative(ICmpInst::Predicate Pred, 7188647cbc5dSDimitry Andric Value *Op0, Value *Op1, 7189647cbc5dSDimitry Andric ICmpInst &CxtI) { 7190647cbc5dSDimitry Andric // Try to optimize 'icmp GEP, P' or 'icmp P, GEP'. 7191647cbc5dSDimitry Andric if (auto *GEP = dyn_cast<GEPOperator>(Op0)) 7192647cbc5dSDimitry Andric if (Instruction *NI = foldGEPICmp(GEP, Op1, Pred, CxtI)) 7193647cbc5dSDimitry Andric return NI; 7194647cbc5dSDimitry Andric 7195647cbc5dSDimitry Andric if (auto *SI = dyn_cast<SelectInst>(Op0)) 7196647cbc5dSDimitry Andric if (Instruction *NI = foldSelectICmp(Pred, SI, Op1, CxtI)) 7197647cbc5dSDimitry Andric return NI; 7198647cbc5dSDimitry Andric 7199647cbc5dSDimitry Andric if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Op0)) 7200647cbc5dSDimitry Andric if (Instruction *Res = foldICmpWithMinMax(CxtI, MinMax, Op1, Pred)) 7201647cbc5dSDimitry Andric return Res; 7202647cbc5dSDimitry Andric 7203647cbc5dSDimitry Andric { 7204647cbc5dSDimitry Andric Value *X; 7205647cbc5dSDimitry Andric const APInt *C; 7206647cbc5dSDimitry Andric // icmp X+Cst, X 7207647cbc5dSDimitry Andric if (match(Op0, m_Add(m_Value(X), m_APInt(C))) && Op1 == X) 7208647cbc5dSDimitry Andric return foldICmpAddOpConst(X, *C, Pred); 7209647cbc5dSDimitry Andric } 7210647cbc5dSDimitry Andric 72111db9f3b2SDimitry Andric // abs(X) >= X --> true 72121db9f3b2SDimitry Andric // abs(X) u<= X --> true 72131db9f3b2SDimitry Andric // abs(X) < X --> false 72141db9f3b2SDimitry Andric // abs(X) u> X --> false 72151db9f3b2SDimitry Andric // abs(X) u>= X --> IsIntMinPosion ? `X > -1`: `X u<= INTMIN` 72161db9f3b2SDimitry Andric // abs(X) <= X --> IsIntMinPosion ? `X > -1`: `X u<= INTMIN` 72171db9f3b2SDimitry Andric // abs(X) == X --> IsIntMinPosion ? `X > -1`: `X u<= INTMIN` 72181db9f3b2SDimitry Andric // abs(X) u< X --> IsIntMinPosion ? `X < 0` : `X > INTMIN` 72191db9f3b2SDimitry Andric // abs(X) > X --> IsIntMinPosion ? `X < 0` : `X > INTMIN` 72201db9f3b2SDimitry Andric // abs(X) != X --> IsIntMinPosion ? `X < 0` : `X > INTMIN` 72211db9f3b2SDimitry Andric { 72221db9f3b2SDimitry Andric Value *X; 72231db9f3b2SDimitry Andric Constant *C; 72241db9f3b2SDimitry Andric if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X), m_Constant(C))) && 72251db9f3b2SDimitry Andric match(Op1, m_Specific(X))) { 72261db9f3b2SDimitry Andric Value *NullValue = Constant::getNullValue(X->getType()); 72271db9f3b2SDimitry Andric Value *AllOnesValue = Constant::getAllOnesValue(X->getType()); 72281db9f3b2SDimitry Andric const APInt SMin = 72291db9f3b2SDimitry Andric APInt::getSignedMinValue(X->getType()->getScalarSizeInBits()); 72301db9f3b2SDimitry Andric bool IsIntMinPosion = C->isAllOnesValue(); 72311db9f3b2SDimitry Andric switch (Pred) { 72321db9f3b2SDimitry Andric case CmpInst::ICMP_ULE: 72331db9f3b2SDimitry Andric case CmpInst::ICMP_SGE: 72341db9f3b2SDimitry Andric return replaceInstUsesWith(CxtI, ConstantInt::getTrue(CxtI.getType())); 72351db9f3b2SDimitry Andric case CmpInst::ICMP_UGT: 72361db9f3b2SDimitry Andric case CmpInst::ICMP_SLT: 72371db9f3b2SDimitry Andric return replaceInstUsesWith(CxtI, ConstantInt::getFalse(CxtI.getType())); 72381db9f3b2SDimitry Andric case CmpInst::ICMP_UGE: 72391db9f3b2SDimitry Andric case CmpInst::ICMP_SLE: 72401db9f3b2SDimitry Andric case CmpInst::ICMP_EQ: { 72411db9f3b2SDimitry Andric return replaceInstUsesWith( 72421db9f3b2SDimitry Andric CxtI, IsIntMinPosion 72431db9f3b2SDimitry Andric ? Builder.CreateICmpSGT(X, AllOnesValue) 72441db9f3b2SDimitry Andric : Builder.CreateICmpULT( 72451db9f3b2SDimitry Andric X, ConstantInt::get(X->getType(), SMin + 1))); 72461db9f3b2SDimitry Andric } 72471db9f3b2SDimitry Andric case CmpInst::ICMP_ULT: 72481db9f3b2SDimitry Andric case CmpInst::ICMP_SGT: 72491db9f3b2SDimitry Andric case CmpInst::ICMP_NE: { 72501db9f3b2SDimitry Andric return replaceInstUsesWith( 72511db9f3b2SDimitry Andric CxtI, IsIntMinPosion 72521db9f3b2SDimitry Andric ? Builder.CreateICmpSLT(X, NullValue) 72531db9f3b2SDimitry Andric : Builder.CreateICmpUGT( 72541db9f3b2SDimitry Andric X, ConstantInt::get(X->getType(), SMin))); 72551db9f3b2SDimitry Andric } 72561db9f3b2SDimitry Andric default: 72571db9f3b2SDimitry Andric llvm_unreachable("Invalid predicate!"); 72581db9f3b2SDimitry Andric } 72591db9f3b2SDimitry Andric } 72601db9f3b2SDimitry Andric } 72611db9f3b2SDimitry Andric 7262*0fca6ea1SDimitry Andric const SimplifyQuery Q = SQ.getWithInstruction(&CxtI); 7263*0fca6ea1SDimitry Andric if (Value *V = foldICmpWithLowBitMaskedVal(Pred, Op0, Op1, Q, *this)) 7264*0fca6ea1SDimitry Andric return replaceInstUsesWith(CxtI, V); 7265*0fca6ea1SDimitry Andric 7266*0fca6ea1SDimitry Andric // Folding (X / Y) pred X => X swap(pred) 0 for constant Y other than 0 or 1 7267*0fca6ea1SDimitry Andric auto CheckUGT1 = [](const APInt &Divisor) { return Divisor.ugt(1); }; 7268*0fca6ea1SDimitry Andric { 7269*0fca6ea1SDimitry Andric if (match(Op0, m_UDiv(m_Specific(Op1), m_CheckedInt(CheckUGT1)))) { 7270*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1, 7271*0fca6ea1SDimitry Andric Constant::getNullValue(Op1->getType())); 7272*0fca6ea1SDimitry Andric } 7273*0fca6ea1SDimitry Andric 7274*0fca6ea1SDimitry Andric if (!ICmpInst::isUnsigned(Pred) && 7275*0fca6ea1SDimitry Andric match(Op0, m_SDiv(m_Specific(Op1), m_CheckedInt(CheckUGT1)))) { 7276*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1, 7277*0fca6ea1SDimitry Andric Constant::getNullValue(Op1->getType())); 7278*0fca6ea1SDimitry Andric } 7279*0fca6ea1SDimitry Andric } 7280*0fca6ea1SDimitry Andric 7281*0fca6ea1SDimitry Andric // Another case of this fold is (X >> Y) pred X => X swap(pred) 0 if Y != 0 7282*0fca6ea1SDimitry Andric auto CheckNE0 = [](const APInt &Shift) { return !Shift.isZero(); }; 7283*0fca6ea1SDimitry Andric { 7284*0fca6ea1SDimitry Andric if (match(Op0, m_LShr(m_Specific(Op1), m_CheckedInt(CheckNE0)))) { 7285*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1, 7286*0fca6ea1SDimitry Andric Constant::getNullValue(Op1->getType())); 7287*0fca6ea1SDimitry Andric } 7288*0fca6ea1SDimitry Andric 7289*0fca6ea1SDimitry Andric if ((Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SGE) && 7290*0fca6ea1SDimitry Andric match(Op0, m_AShr(m_Specific(Op1), m_CheckedInt(CheckNE0)))) { 7291*0fca6ea1SDimitry Andric return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1, 7292*0fca6ea1SDimitry Andric Constant::getNullValue(Op1->getType())); 7293*0fca6ea1SDimitry Andric } 7294*0fca6ea1SDimitry Andric } 7295*0fca6ea1SDimitry Andric 7296647cbc5dSDimitry Andric return nullptr; 7297647cbc5dSDimitry Andric } 7298647cbc5dSDimitry Andric 7299e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) { 73000b57cec5SDimitry Andric bool Changed = false; 73018bcb0991SDimitry Andric const SimplifyQuery Q = SQ.getWithInstruction(&I); 73020b57cec5SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 73030b57cec5SDimitry Andric unsigned Op0Cplxity = getComplexity(Op0); 73040b57cec5SDimitry Andric unsigned Op1Cplxity = getComplexity(Op1); 73050b57cec5SDimitry Andric 73060b57cec5SDimitry Andric /// Orders the operands of the compare so that they are listed from most 73070b57cec5SDimitry Andric /// complex to least complex. This puts constants before unary operators, 73080b57cec5SDimitry Andric /// before binary operators. 730906c3fb27SDimitry Andric if (Op0Cplxity < Op1Cplxity) { 73100b57cec5SDimitry Andric I.swapOperands(); 73110b57cec5SDimitry Andric std::swap(Op0, Op1); 73120b57cec5SDimitry Andric Changed = true; 73130b57cec5SDimitry Andric } 73140b57cec5SDimitry Andric 731581ad6265SDimitry Andric if (Value *V = simplifyICmpInst(I.getPredicate(), Op0, Op1, Q)) 73160b57cec5SDimitry Andric return replaceInstUsesWith(I, V); 73170b57cec5SDimitry Andric 73180b57cec5SDimitry Andric // Comparing -val or val with non-zero is the same as just comparing val 73190b57cec5SDimitry Andric // ie, abs(val) != 0 -> val != 0 73200b57cec5SDimitry Andric if (I.getPredicate() == ICmpInst::ICMP_NE && match(Op1, m_Zero())) { 73210b57cec5SDimitry Andric Value *Cond, *SelectTrue, *SelectFalse; 73220b57cec5SDimitry Andric if (match(Op0, m_Select(m_Value(Cond), m_Value(SelectTrue), 73230b57cec5SDimitry Andric m_Value(SelectFalse)))) { 73240b57cec5SDimitry Andric if (Value *V = dyn_castNegVal(SelectTrue)) { 73250b57cec5SDimitry Andric if (V == SelectFalse) 73260b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, I.getPredicate(), V, Op1); 73270b57cec5SDimitry Andric } 73280b57cec5SDimitry Andric else if (Value *V = dyn_castNegVal(SelectFalse)) { 73290b57cec5SDimitry Andric if (V == SelectTrue) 73300b57cec5SDimitry Andric return CmpInst::Create(Instruction::ICmp, I.getPredicate(), V, Op1); 73310b57cec5SDimitry Andric } 73320b57cec5SDimitry Andric } 73330b57cec5SDimitry Andric } 73340b57cec5SDimitry Andric 73350b57cec5SDimitry Andric if (Op0->getType()->isIntOrIntVectorTy(1)) 73360b57cec5SDimitry Andric if (Instruction *Res = canonicalizeICmpBool(I, Builder)) 73370b57cec5SDimitry Andric return Res; 73380b57cec5SDimitry Andric 73395ffd83dbSDimitry Andric if (Instruction *Res = canonicalizeCmpWithConstant(I)) 73405ffd83dbSDimitry Andric return Res; 73415ffd83dbSDimitry Andric 73425ffd83dbSDimitry Andric if (Instruction *Res = canonicalizeICmpPredicate(I)) 73435ffd83dbSDimitry Andric return Res; 73440b57cec5SDimitry Andric 73450b57cec5SDimitry Andric if (Instruction *Res = foldICmpWithConstant(I)) 73460b57cec5SDimitry Andric return Res; 73470b57cec5SDimitry Andric 73480b57cec5SDimitry Andric if (Instruction *Res = foldICmpWithDominatingICmp(I)) 73490b57cec5SDimitry Andric return Res; 73500b57cec5SDimitry Andric 735106c3fb27SDimitry Andric if (Instruction *Res = foldICmpUsingBoolRange(I)) 735281ad6265SDimitry Andric return Res; 735381ad6265SDimitry Andric 73540b57cec5SDimitry Andric if (Instruction *Res = foldICmpUsingKnownBits(I)) 73550b57cec5SDimitry Andric return Res; 73560b57cec5SDimitry Andric 73575f757f3fSDimitry Andric if (Instruction *Res = foldICmpTruncWithTruncOrExt(I, Q)) 73585f757f3fSDimitry Andric return Res; 73595f757f3fSDimitry Andric 73600b57cec5SDimitry Andric // Test if the ICmpInst instruction is used exclusively by a select as 73610b57cec5SDimitry Andric // part of a minimum or maximum operation. If so, refrain from doing 73620b57cec5SDimitry Andric // any other folding. This helps out other analyses which understand 73630b57cec5SDimitry Andric // non-obfuscated minimum and maximum idioms, such as ScalarEvolution 73640b57cec5SDimitry Andric // and CodeGen. And in this case, at least one of the comparison 73650b57cec5SDimitry Andric // operands has at least one user besides the compare (the select), 73660b57cec5SDimitry Andric // which would often largely negate the benefit of folding anyway. 73670b57cec5SDimitry Andric // 73680b57cec5SDimitry Andric // Do the same for the other patterns recognized by matchSelectPattern. 73690b57cec5SDimitry Andric if (I.hasOneUse()) 73700b57cec5SDimitry Andric if (SelectInst *SI = dyn_cast<SelectInst>(I.user_back())) { 73710b57cec5SDimitry Andric Value *A, *B; 73720b57cec5SDimitry Andric SelectPatternResult SPR = matchSelectPattern(SI, A, B); 73730b57cec5SDimitry Andric if (SPR.Flavor != SPF_UNKNOWN) 73740b57cec5SDimitry Andric return nullptr; 73750b57cec5SDimitry Andric } 73760b57cec5SDimitry Andric 73770b57cec5SDimitry Andric // Do this after checking for min/max to prevent infinite looping. 73780b57cec5SDimitry Andric if (Instruction *Res = foldICmpWithZero(I)) 73790b57cec5SDimitry Andric return Res; 73800b57cec5SDimitry Andric 73810b57cec5SDimitry Andric // FIXME: We only do this after checking for min/max to prevent infinite 73820b57cec5SDimitry Andric // looping caused by a reverse canonicalization of these patterns for min/max. 73830b57cec5SDimitry Andric // FIXME: The organization of folds is a mess. These would naturally go into 73840b57cec5SDimitry Andric // canonicalizeCmpWithConstant(), but we can't move all of the above folds 73850b57cec5SDimitry Andric // down here after the min/max restriction. 73860b57cec5SDimitry Andric ICmpInst::Predicate Pred = I.getPredicate(); 73870b57cec5SDimitry Andric const APInt *C; 73880b57cec5SDimitry Andric if (match(Op1, m_APInt(C))) { 73890b57cec5SDimitry Andric // For i32: x >u 2147483647 -> x <s 0 -> true if sign bit set 73900b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_UGT && C->isMaxSignedValue()) { 73910b57cec5SDimitry Andric Constant *Zero = Constant::getNullValue(Op0->getType()); 73920b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, Op0, Zero); 73930b57cec5SDimitry Andric } 73940b57cec5SDimitry Andric 73950b57cec5SDimitry Andric // For i32: x <u 2147483648 -> x >s -1 -> true if sign bit clear 73960b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_ULT && C->isMinSignedValue()) { 73970b57cec5SDimitry Andric Constant *AllOnes = Constant::getAllOnesValue(Op0->getType()); 73980b57cec5SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SGT, Op0, AllOnes); 73990b57cec5SDimitry Andric } 74000b57cec5SDimitry Andric } 74010b57cec5SDimitry Andric 7402349cc55cSDimitry Andric // The folds in here may rely on wrapping flags and special constants, so 7403349cc55cSDimitry Andric // they can break up min/max idioms in some cases but not seemingly similar 7404349cc55cSDimitry Andric // patterns. 7405349cc55cSDimitry Andric // FIXME: It may be possible to enhance select folding to make this 7406349cc55cSDimitry Andric // unnecessary. It may also be moot if we canonicalize to min/max 7407349cc55cSDimitry Andric // intrinsics. 7408349cc55cSDimitry Andric if (Instruction *Res = foldICmpBinOp(I, Q)) 7409349cc55cSDimitry Andric return Res; 7410349cc55cSDimitry Andric 74110b57cec5SDimitry Andric if (Instruction *Res = foldICmpInstWithConstant(I)) 74120b57cec5SDimitry Andric return Res; 74130b57cec5SDimitry Andric 74148bcb0991SDimitry Andric // Try to match comparison as a sign bit test. Intentionally do this after 74158bcb0991SDimitry Andric // foldICmpInstWithConstant() to potentially let other folds to happen first. 74168bcb0991SDimitry Andric if (Instruction *New = foldSignBitTest(I)) 74178bcb0991SDimitry Andric return New; 74188bcb0991SDimitry Andric 74190b57cec5SDimitry Andric if (Instruction *Res = foldICmpInstWithConstantNotInt(I)) 74200b57cec5SDimitry Andric return Res; 74210b57cec5SDimitry Andric 7422647cbc5dSDimitry Andric if (Instruction *Res = foldICmpCommutative(I.getPredicate(), Op0, Op1, I)) 7423647cbc5dSDimitry Andric return Res; 7424647cbc5dSDimitry Andric if (Instruction *Res = 7425647cbc5dSDimitry Andric foldICmpCommutative(I.getSwappedPredicate(), Op1, Op0, I)) 7426647cbc5dSDimitry Andric return Res; 742781ad6265SDimitry Andric 7428*0fca6ea1SDimitry Andric if (I.isCommutative()) { 7429*0fca6ea1SDimitry Andric if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) { 7430*0fca6ea1SDimitry Andric replaceOperand(I, 0, Pair->first); 7431*0fca6ea1SDimitry Andric replaceOperand(I, 1, Pair->second); 7432*0fca6ea1SDimitry Andric return &I; 7433*0fca6ea1SDimitry Andric } 7434*0fca6ea1SDimitry Andric } 7435*0fca6ea1SDimitry Andric 743606c3fb27SDimitry Andric // In case of a comparison with two select instructions having the same 743706c3fb27SDimitry Andric // condition, check whether one of the resulting branches can be simplified. 743806c3fb27SDimitry Andric // If so, just compare the other branch and select the appropriate result. 743906c3fb27SDimitry Andric // For example: 744006c3fb27SDimitry Andric // %tmp1 = select i1 %cmp, i32 %y, i32 %x 744106c3fb27SDimitry Andric // %tmp2 = select i1 %cmp, i32 %z, i32 %x 744206c3fb27SDimitry Andric // %cmp2 = icmp slt i32 %tmp2, %tmp1 744306c3fb27SDimitry Andric // The icmp will result false for the false value of selects and the result 744406c3fb27SDimitry Andric // will depend upon the comparison of true values of selects if %cmp is 744506c3fb27SDimitry Andric // true. Thus, transform this into: 744606c3fb27SDimitry Andric // %cmp = icmp slt i32 %y, %z 744706c3fb27SDimitry Andric // %sel = select i1 %cond, i1 %cmp, i1 false 744806c3fb27SDimitry Andric // This handles similar cases to transform. 744906c3fb27SDimitry Andric { 745006c3fb27SDimitry Andric Value *Cond, *A, *B, *C, *D; 745106c3fb27SDimitry Andric if (match(Op0, m_Select(m_Value(Cond), m_Value(A), m_Value(B))) && 745206c3fb27SDimitry Andric match(Op1, m_Select(m_Specific(Cond), m_Value(C), m_Value(D))) && 745306c3fb27SDimitry Andric (Op0->hasOneUse() || Op1->hasOneUse())) { 745406c3fb27SDimitry Andric // Check whether comparison of TrueValues can be simplified 745506c3fb27SDimitry Andric if (Value *Res = simplifyICmpInst(Pred, A, C, SQ)) { 745606c3fb27SDimitry Andric Value *NewICMP = Builder.CreateICmp(Pred, B, D); 745706c3fb27SDimitry Andric return SelectInst::Create(Cond, Res, NewICMP); 745806c3fb27SDimitry Andric } 745906c3fb27SDimitry Andric // Check whether comparison of FalseValues can be simplified 746006c3fb27SDimitry Andric if (Value *Res = simplifyICmpInst(Pred, B, D, SQ)) { 746106c3fb27SDimitry Andric Value *NewICMP = Builder.CreateICmp(Pred, A, C); 746206c3fb27SDimitry Andric return SelectInst::Create(Cond, NewICMP, Res); 746306c3fb27SDimitry Andric } 746406c3fb27SDimitry Andric } 746506c3fb27SDimitry Andric } 746606c3fb27SDimitry Andric 74670b57cec5SDimitry Andric // Try to optimize equality comparisons against alloca-based pointers. 74680b57cec5SDimitry Andric if (Op0->getType()->isPointerTy() && I.isEquality()) { 74690b57cec5SDimitry Andric assert(Op1->getType()->isPointerTy() && "Comparing pointer with non-pointer?"); 7470e8d8bef9SDimitry Andric if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(Op0))) 747106c3fb27SDimitry Andric if (foldAllocaCmp(Alloca)) 747206c3fb27SDimitry Andric return nullptr; 7473e8d8bef9SDimitry Andric if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(Op1))) 747406c3fb27SDimitry Andric if (foldAllocaCmp(Alloca)) 747506c3fb27SDimitry Andric return nullptr; 74760b57cec5SDimitry Andric } 74770b57cec5SDimitry Andric 7478349cc55cSDimitry Andric if (Instruction *Res = foldICmpBitCast(I)) 74790b57cec5SDimitry Andric return Res; 74800b57cec5SDimitry Andric 74815ffd83dbSDimitry Andric // TODO: Hoist this above the min/max bailout. 74828bcb0991SDimitry Andric if (Instruction *R = foldICmpWithCastOp(I)) 74830b57cec5SDimitry Andric return R; 74840b57cec5SDimitry Andric 74850b57cec5SDimitry Andric { 74865f757f3fSDimitry Andric Value *X, *Y; 74875f757f3fSDimitry Andric // Transform (X & ~Y) == 0 --> (X & Y) != 0 74885f757f3fSDimitry Andric // and (X & ~Y) != 0 --> (X & Y) == 0 74890b57cec5SDimitry Andric // if A is a power of 2. 74905f757f3fSDimitry Andric if (match(Op0, m_And(m_Value(X), m_Not(m_Value(Y)))) && 74915f757f3fSDimitry Andric match(Op1, m_Zero()) && isKnownToBeAPowerOfTwo(X, false, 0, &I) && 74925f757f3fSDimitry Andric I.isEquality()) 74935f757f3fSDimitry Andric return new ICmpInst(I.getInversePredicate(), Builder.CreateAnd(X, Y), 74940b57cec5SDimitry Andric Op1); 74950b57cec5SDimitry Andric 74965f757f3fSDimitry Andric // Op0 pred Op1 -> ~Op1 pred ~Op0, if this allows us to drop an instruction. 74975f757f3fSDimitry Andric if (Op0->getType()->isIntOrIntVectorTy()) { 74985f757f3fSDimitry Andric bool ConsumesOp0, ConsumesOp1; 74995f757f3fSDimitry Andric if (isFreeToInvert(Op0, Op0->hasOneUse(), ConsumesOp0) && 75005f757f3fSDimitry Andric isFreeToInvert(Op1, Op1->hasOneUse(), ConsumesOp1) && 75015f757f3fSDimitry Andric (ConsumesOp0 || ConsumesOp1)) { 75025f757f3fSDimitry Andric Value *InvOp0 = getFreelyInverted(Op0, Op0->hasOneUse(), &Builder); 75035f757f3fSDimitry Andric Value *InvOp1 = getFreelyInverted(Op1, Op1->hasOneUse(), &Builder); 75045f757f3fSDimitry Andric assert(InvOp0 && InvOp1 && 75055f757f3fSDimitry Andric "Mismatch between isFreeToInvert and getFreelyInverted"); 75065f757f3fSDimitry Andric return new ICmpInst(I.getSwappedPredicate(), InvOp0, InvOp1); 75075f757f3fSDimitry Andric } 75080b57cec5SDimitry Andric } 75090b57cec5SDimitry Andric 75100b57cec5SDimitry Andric Instruction *AddI = nullptr; 75115f757f3fSDimitry Andric if (match(&I, m_UAddWithOverflow(m_Value(X), m_Value(Y), 75120b57cec5SDimitry Andric m_Instruction(AddI))) && 75135f757f3fSDimitry Andric isa<IntegerType>(X->getType())) { 75140b57cec5SDimitry Andric Value *Result; 75150b57cec5SDimitry Andric Constant *Overflow; 75165ffd83dbSDimitry Andric // m_UAddWithOverflow can match patterns that do not include an explicit 75175ffd83dbSDimitry Andric // "add" instruction, so check the opcode of the matched op. 75185ffd83dbSDimitry Andric if (AddI->getOpcode() == Instruction::Add && 75195f757f3fSDimitry Andric OptimizeOverflowCheck(Instruction::Add, /*Signed*/ false, X, Y, *AddI, 75205ffd83dbSDimitry Andric Result, Overflow)) { 75210b57cec5SDimitry Andric replaceInstUsesWith(*AddI, Result); 75225ffd83dbSDimitry Andric eraseInstFromFunction(*AddI); 75230b57cec5SDimitry Andric return replaceInstUsesWith(I, Overflow); 75240b57cec5SDimitry Andric } 75250b57cec5SDimitry Andric } 75260b57cec5SDimitry Andric 75275f757f3fSDimitry Andric // (zext X) * (zext Y) --> llvm.umul.with.overflow. 75285f757f3fSDimitry Andric if (match(Op0, m_NUWMul(m_ZExt(m_Value(X)), m_ZExt(m_Value(Y)))) && 75295f757f3fSDimitry Andric match(Op1, m_APInt(C))) { 75305f757f3fSDimitry Andric if (Instruction *R = processUMulZExtIdiom(I, Op0, C, *this)) 75310b57cec5SDimitry Andric return R; 75320b57cec5SDimitry Andric } 75335f757f3fSDimitry Andric 75345f757f3fSDimitry Andric // Signbit test folds 75355f757f3fSDimitry Andric // Fold (X u>> BitWidth - 1 Pred ZExt(i1)) --> X s< 0 Pred i1 75365f757f3fSDimitry Andric // Fold (X s>> BitWidth - 1 Pred SExt(i1)) --> X s< 0 Pred i1 75375f757f3fSDimitry Andric Instruction *ExtI; 75385f757f3fSDimitry Andric if ((I.isUnsigned() || I.isEquality()) && 75395f757f3fSDimitry Andric match(Op1, 75405f757f3fSDimitry Andric m_CombineAnd(m_Instruction(ExtI), m_ZExtOrSExt(m_Value(Y)))) && 75415f757f3fSDimitry Andric Y->getType()->getScalarSizeInBits() == 1 && 75425f757f3fSDimitry Andric (Op0->hasOneUse() || Op1->hasOneUse())) { 75435f757f3fSDimitry Andric unsigned OpWidth = Op0->getType()->getScalarSizeInBits(); 75445f757f3fSDimitry Andric Instruction *ShiftI; 75455f757f3fSDimitry Andric if (match(Op0, m_CombineAnd(m_Instruction(ShiftI), 7546*0fca6ea1SDimitry Andric m_Shr(m_Value(X), m_SpecificIntAllowPoison( 75475f757f3fSDimitry Andric OpWidth - 1))))) { 75485f757f3fSDimitry Andric unsigned ExtOpc = ExtI->getOpcode(); 75495f757f3fSDimitry Andric unsigned ShiftOpc = ShiftI->getOpcode(); 75505f757f3fSDimitry Andric if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) || 75515f757f3fSDimitry Andric (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) { 75525f757f3fSDimitry Andric Value *SLTZero = 75535f757f3fSDimitry Andric Builder.CreateICmpSLT(X, Constant::getNullValue(X->getType())); 75545f757f3fSDimitry Andric Value *Cmp = Builder.CreateICmp(Pred, SLTZero, Y, I.getName()); 75555f757f3fSDimitry Andric return replaceInstUsesWith(I, Cmp); 75565f757f3fSDimitry Andric } 75575f757f3fSDimitry Andric } 75580b57cec5SDimitry Andric } 75590b57cec5SDimitry Andric } 75600b57cec5SDimitry Andric 75610b57cec5SDimitry Andric if (Instruction *Res = foldICmpEquality(I)) 75620b57cec5SDimitry Andric return Res; 75630b57cec5SDimitry Andric 756406c3fb27SDimitry Andric if (Instruction *Res = foldICmpPow2Test(I, Builder)) 756506c3fb27SDimitry Andric return Res; 756606c3fb27SDimitry Andric 7567480093f4SDimitry Andric if (Instruction *Res = foldICmpOfUAddOv(I)) 7568480093f4SDimitry Andric return Res; 7569480093f4SDimitry Andric 75700b57cec5SDimitry Andric // The 'cmpxchg' instruction returns an aggregate containing the old value and 75710b57cec5SDimitry Andric // an i1 which indicates whether or not we successfully did the swap. 75720b57cec5SDimitry Andric // 75730b57cec5SDimitry Andric // Replace comparisons between the old value and the expected value with the 75740b57cec5SDimitry Andric // indicator that 'cmpxchg' returns. 75750b57cec5SDimitry Andric // 75760b57cec5SDimitry Andric // N.B. This transform is only valid when the 'cmpxchg' is not permitted to 75770b57cec5SDimitry Andric // spuriously fail. In those cases, the old value may equal the expected 75780b57cec5SDimitry Andric // value but it is possible for the swap to not occur. 75790b57cec5SDimitry Andric if (I.getPredicate() == ICmpInst::ICMP_EQ) 75800b57cec5SDimitry Andric if (auto *EVI = dyn_cast<ExtractValueInst>(Op0)) 75810b57cec5SDimitry Andric if (auto *ACXI = dyn_cast<AtomicCmpXchgInst>(EVI->getAggregateOperand())) 75820b57cec5SDimitry Andric if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 && 75830b57cec5SDimitry Andric !ACXI->isWeak()) 75840b57cec5SDimitry Andric return ExtractValueInst::Create(ACXI, 1); 75850b57cec5SDimitry Andric 75860b57cec5SDimitry Andric if (Instruction *Res = foldICmpWithHighBitMask(I, Builder)) 75870b57cec5SDimitry Andric return Res; 75880b57cec5SDimitry Andric 75890b57cec5SDimitry Andric if (I.getType()->isVectorTy()) 75900b57cec5SDimitry Andric if (Instruction *Res = foldVectorCmp(I, Builder)) 75910b57cec5SDimitry Andric return Res; 75920b57cec5SDimitry Andric 7593349cc55cSDimitry Andric if (Instruction *Res = foldICmpInvariantGroup(I)) 7594349cc55cSDimitry Andric return Res; 7595349cc55cSDimitry Andric 75961fd87a68SDimitry Andric if (Instruction *Res = foldReductionIdiom(I, Builder, DL)) 75971fd87a68SDimitry Andric return Res; 75981fd87a68SDimitry Andric 75990b57cec5SDimitry Andric return Changed ? &I : nullptr; 76000b57cec5SDimitry Andric } 76010b57cec5SDimitry Andric 76020b57cec5SDimitry Andric /// Fold fcmp ([us]itofp x, cst) if possible. 7603e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I, 7604e8d8bef9SDimitry Andric Instruction *LHSI, 76050b57cec5SDimitry Andric Constant *RHSC) { 7606*0fca6ea1SDimitry Andric const APFloat *RHS; 7607*0fca6ea1SDimitry Andric if (!match(RHSC, m_APFloat(RHS))) 7608*0fca6ea1SDimitry Andric return nullptr; 76090b57cec5SDimitry Andric 76100b57cec5SDimitry Andric // Get the width of the mantissa. We don't want to hack on conversions that 76110b57cec5SDimitry Andric // might lose information from the integer, e.g. "i64 -> float" 76120b57cec5SDimitry Andric int MantissaWidth = LHSI->getType()->getFPMantissaWidth(); 76130b57cec5SDimitry Andric if (MantissaWidth == -1) return nullptr; // Unknown. 76140b57cec5SDimitry Andric 7615*0fca6ea1SDimitry Andric Type *IntTy = LHSI->getOperand(0)->getType(); 7616*0fca6ea1SDimitry Andric unsigned IntWidth = IntTy->getScalarSizeInBits(); 76170b57cec5SDimitry Andric bool LHSUnsigned = isa<UIToFPInst>(LHSI); 76180b57cec5SDimitry Andric 76190b57cec5SDimitry Andric if (I.isEquality()) { 76200b57cec5SDimitry Andric FCmpInst::Predicate P = I.getPredicate(); 76210b57cec5SDimitry Andric bool IsExact = false; 7622*0fca6ea1SDimitry Andric APSInt RHSCvt(IntWidth, LHSUnsigned); 7623*0fca6ea1SDimitry Andric RHS->convertToInteger(RHSCvt, APFloat::rmNearestTiesToEven, &IsExact); 76240b57cec5SDimitry Andric 76250b57cec5SDimitry Andric // If the floating point constant isn't an integer value, we know if we will 76260b57cec5SDimitry Andric // ever compare equal / not equal to it. 76270b57cec5SDimitry Andric if (!IsExact) { 76280b57cec5SDimitry Andric // TODO: Can never be -0.0 and other non-representable values 7629*0fca6ea1SDimitry Andric APFloat RHSRoundInt(*RHS); 76300b57cec5SDimitry Andric RHSRoundInt.roundToIntegral(APFloat::rmNearestTiesToEven); 7631*0fca6ea1SDimitry Andric if (*RHS != RHSRoundInt) { 76320b57cec5SDimitry Andric if (P == FCmpInst::FCMP_OEQ || P == FCmpInst::FCMP_UEQ) 7633*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 76340b57cec5SDimitry Andric 76350b57cec5SDimitry Andric assert(P == FCmpInst::FCMP_ONE || P == FCmpInst::FCMP_UNE); 7636*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 76370b57cec5SDimitry Andric } 76380b57cec5SDimitry Andric } 76390b57cec5SDimitry Andric 76400b57cec5SDimitry Andric // TODO: If the constant is exactly representable, is it always OK to do 76410b57cec5SDimitry Andric // equality compares as integer? 76420b57cec5SDimitry Andric } 76430b57cec5SDimitry Andric 76440b57cec5SDimitry Andric // Check to see that the input is converted from an integer type that is small 76450b57cec5SDimitry Andric // enough that preserves all bits. TODO: check here for "known" sign bits. 76460b57cec5SDimitry Andric // This would allow us to handle (fptosi (x >>s 62) to float) if x is i64 f.e. 76470b57cec5SDimitry Andric 7648*0fca6ea1SDimitry Andric // Following test does NOT adjust IntWidth downwards for signed inputs, 76490b57cec5SDimitry Andric // because the most negative value still requires all the mantissa bits 76500b57cec5SDimitry Andric // to distinguish it from one less than that value. 7651*0fca6ea1SDimitry Andric if ((int)IntWidth > MantissaWidth) { 76520b57cec5SDimitry Andric // Conversion would lose accuracy. Check if loss can impact comparison. 7653*0fca6ea1SDimitry Andric int Exp = ilogb(*RHS); 76540b57cec5SDimitry Andric if (Exp == APFloat::IEK_Inf) { 7655*0fca6ea1SDimitry Andric int MaxExponent = ilogb(APFloat::getLargest(RHS->getSemantics())); 7656*0fca6ea1SDimitry Andric if (MaxExponent < (int)IntWidth - !LHSUnsigned) 76570b57cec5SDimitry Andric // Conversion could create infinity. 76580b57cec5SDimitry Andric return nullptr; 76590b57cec5SDimitry Andric } else { 76600b57cec5SDimitry Andric // Note that if RHS is zero or NaN, then Exp is negative 76610b57cec5SDimitry Andric // and first condition is trivially false. 7662*0fca6ea1SDimitry Andric if (MantissaWidth <= Exp && Exp <= (int)IntWidth - !LHSUnsigned) 76630b57cec5SDimitry Andric // Conversion could affect comparison. 76640b57cec5SDimitry Andric return nullptr; 76650b57cec5SDimitry Andric } 76660b57cec5SDimitry Andric } 76670b57cec5SDimitry Andric 76680b57cec5SDimitry Andric // Otherwise, we can potentially simplify the comparison. We know that it 76690b57cec5SDimitry Andric // will always come through as an integer value and we know the constant is 76700b57cec5SDimitry Andric // not a NAN (it would have been previously simplified). 7671*0fca6ea1SDimitry Andric assert(!RHS->isNaN() && "NaN comparison not already folded!"); 76720b57cec5SDimitry Andric 76730b57cec5SDimitry Andric ICmpInst::Predicate Pred; 76740b57cec5SDimitry Andric switch (I.getPredicate()) { 76750b57cec5SDimitry Andric default: llvm_unreachable("Unexpected predicate!"); 76760b57cec5SDimitry Andric case FCmpInst::FCMP_UEQ: 76770b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: 76780b57cec5SDimitry Andric Pred = ICmpInst::ICMP_EQ; 76790b57cec5SDimitry Andric break; 76800b57cec5SDimitry Andric case FCmpInst::FCMP_UGT: 76810b57cec5SDimitry Andric case FCmpInst::FCMP_OGT: 76820b57cec5SDimitry Andric Pred = LHSUnsigned ? ICmpInst::ICMP_UGT : ICmpInst::ICMP_SGT; 76830b57cec5SDimitry Andric break; 76840b57cec5SDimitry Andric case FCmpInst::FCMP_UGE: 76850b57cec5SDimitry Andric case FCmpInst::FCMP_OGE: 76860b57cec5SDimitry Andric Pred = LHSUnsigned ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_SGE; 76870b57cec5SDimitry Andric break; 76880b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: 76890b57cec5SDimitry Andric case FCmpInst::FCMP_OLT: 76900b57cec5SDimitry Andric Pred = LHSUnsigned ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_SLT; 76910b57cec5SDimitry Andric break; 76920b57cec5SDimitry Andric case FCmpInst::FCMP_ULE: 76930b57cec5SDimitry Andric case FCmpInst::FCMP_OLE: 76940b57cec5SDimitry Andric Pred = LHSUnsigned ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_SLE; 76950b57cec5SDimitry Andric break; 76960b57cec5SDimitry Andric case FCmpInst::FCMP_UNE: 76970b57cec5SDimitry Andric case FCmpInst::FCMP_ONE: 76980b57cec5SDimitry Andric Pred = ICmpInst::ICMP_NE; 76990b57cec5SDimitry Andric break; 77000b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: 7701*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 77020b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: 7703*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77040b57cec5SDimitry Andric } 77050b57cec5SDimitry Andric 77060b57cec5SDimitry Andric // Now we know that the APFloat is a normal number, zero or inf. 77070b57cec5SDimitry Andric 77080b57cec5SDimitry Andric // See if the FP constant is too large for the integer. For example, 77090b57cec5SDimitry Andric // comparing an i8 to 300.0. 77100b57cec5SDimitry Andric if (!LHSUnsigned) { 77110b57cec5SDimitry Andric // If the RHS value is > SignedMax, fold the comparison. This handles +INF 77120b57cec5SDimitry Andric // and large values. 7713*0fca6ea1SDimitry Andric APFloat SMax(RHS->getSemantics()); 77140b57cec5SDimitry Andric SMax.convertFromAPInt(APInt::getSignedMaxValue(IntWidth), true, 77150b57cec5SDimitry Andric APFloat::rmNearestTiesToEven); 7716*0fca6ea1SDimitry Andric if (SMax < *RHS) { // smax < 13123.0 77170b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SLT || 77180b57cec5SDimitry Andric Pred == ICmpInst::ICMP_SLE) 7719*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 7720*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77210b57cec5SDimitry Andric } 77220b57cec5SDimitry Andric } else { 77230b57cec5SDimitry Andric // If the RHS value is > UnsignedMax, fold the comparison. This handles 77240b57cec5SDimitry Andric // +INF and large values. 7725*0fca6ea1SDimitry Andric APFloat UMax(RHS->getSemantics()); 77260b57cec5SDimitry Andric UMax.convertFromAPInt(APInt::getMaxValue(IntWidth), false, 77270b57cec5SDimitry Andric APFloat::rmNearestTiesToEven); 7728*0fca6ea1SDimitry Andric if (UMax < *RHS) { // umax < 13123.0 77290b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_ULT || 77300b57cec5SDimitry Andric Pred == ICmpInst::ICMP_ULE) 7731*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 7732*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77330b57cec5SDimitry Andric } 77340b57cec5SDimitry Andric } 77350b57cec5SDimitry Andric 77360b57cec5SDimitry Andric if (!LHSUnsigned) { 77370b57cec5SDimitry Andric // See if the RHS value is < SignedMin. 7738*0fca6ea1SDimitry Andric APFloat SMin(RHS->getSemantics()); 77390b57cec5SDimitry Andric SMin.convertFromAPInt(APInt::getSignedMinValue(IntWidth), true, 77400b57cec5SDimitry Andric APFloat::rmNearestTiesToEven); 7741*0fca6ea1SDimitry Andric if (SMin > *RHS) { // smin > 12312.0 77420b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SGT || 77430b57cec5SDimitry Andric Pred == ICmpInst::ICMP_SGE) 7744*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 7745*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77460b57cec5SDimitry Andric } 77470b57cec5SDimitry Andric } else { 77480b57cec5SDimitry Andric // See if the RHS value is < UnsignedMin. 7749*0fca6ea1SDimitry Andric APFloat UMin(RHS->getSemantics()); 77505ffd83dbSDimitry Andric UMin.convertFromAPInt(APInt::getMinValue(IntWidth), false, 77510b57cec5SDimitry Andric APFloat::rmNearestTiesToEven); 7752*0fca6ea1SDimitry Andric if (UMin > *RHS) { // umin > 12312.0 77530b57cec5SDimitry Andric if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_UGT || 77540b57cec5SDimitry Andric Pred == ICmpInst::ICMP_UGE) 7755*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 7756*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77570b57cec5SDimitry Andric } 77580b57cec5SDimitry Andric } 77590b57cec5SDimitry Andric 77600b57cec5SDimitry Andric // Okay, now we know that the FP constant fits in the range [SMIN, SMAX] or 77615f757f3fSDimitry Andric // [0, UMAX], but it may still be fractional. Check whether this is the case 77625f757f3fSDimitry Andric // using the IsExact flag. 77630b57cec5SDimitry Andric // Don't do this for zero, because -0.0 is not fractional. 77645f757f3fSDimitry Andric APSInt RHSInt(IntWidth, LHSUnsigned); 77655f757f3fSDimitry Andric bool IsExact; 7766*0fca6ea1SDimitry Andric RHS->convertToInteger(RHSInt, APFloat::rmTowardZero, &IsExact); 7767*0fca6ea1SDimitry Andric if (!RHS->isZero()) { 77685f757f3fSDimitry Andric if (!IsExact) { 77690b57cec5SDimitry Andric // If we had a comparison against a fractional value, we have to adjust 77700b57cec5SDimitry Andric // the compare predicate and sometimes the value. RHSC is rounded towards 77710b57cec5SDimitry Andric // zero at this point. 77720b57cec5SDimitry Andric switch (Pred) { 77730b57cec5SDimitry Andric default: llvm_unreachable("Unexpected integer comparison!"); 77740b57cec5SDimitry Andric case ICmpInst::ICMP_NE: // (float)int != 4.4 --> true 7775*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 77760b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: // (float)int == 4.4 --> false 7777*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77780b57cec5SDimitry Andric case ICmpInst::ICMP_ULE: 77790b57cec5SDimitry Andric // (float)int <= 4.4 --> int <= 4 77800b57cec5SDimitry Andric // (float)int <= -4.4 --> false 7781*0fca6ea1SDimitry Andric if (RHS->isNegative()) 7782*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77830b57cec5SDimitry Andric break; 77840b57cec5SDimitry Andric case ICmpInst::ICMP_SLE: 77850b57cec5SDimitry Andric // (float)int <= 4.4 --> int <= 4 77860b57cec5SDimitry Andric // (float)int <= -4.4 --> int < -4 7787*0fca6ea1SDimitry Andric if (RHS->isNegative()) 77880b57cec5SDimitry Andric Pred = ICmpInst::ICMP_SLT; 77890b57cec5SDimitry Andric break; 77900b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: 77910b57cec5SDimitry Andric // (float)int < -4.4 --> false 77920b57cec5SDimitry Andric // (float)int < 4.4 --> int <= 4 7793*0fca6ea1SDimitry Andric if (RHS->isNegative()) 7794*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 77950b57cec5SDimitry Andric Pred = ICmpInst::ICMP_ULE; 77960b57cec5SDimitry Andric break; 77970b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: 77980b57cec5SDimitry Andric // (float)int < -4.4 --> int < -4 77990b57cec5SDimitry Andric // (float)int < 4.4 --> int <= 4 7800*0fca6ea1SDimitry Andric if (!RHS->isNegative()) 78010b57cec5SDimitry Andric Pred = ICmpInst::ICMP_SLE; 78020b57cec5SDimitry Andric break; 78030b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: 78040b57cec5SDimitry Andric // (float)int > 4.4 --> int > 4 78050b57cec5SDimitry Andric // (float)int > -4.4 --> true 7806*0fca6ea1SDimitry Andric if (RHS->isNegative()) 7807*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 78080b57cec5SDimitry Andric break; 78090b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: 78100b57cec5SDimitry Andric // (float)int > 4.4 --> int > 4 78110b57cec5SDimitry Andric // (float)int > -4.4 --> int >= -4 7812*0fca6ea1SDimitry Andric if (RHS->isNegative()) 78130b57cec5SDimitry Andric Pred = ICmpInst::ICMP_SGE; 78140b57cec5SDimitry Andric break; 78150b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: 78160b57cec5SDimitry Andric // (float)int >= -4.4 --> true 78170b57cec5SDimitry Andric // (float)int >= 4.4 --> int > 4 7818*0fca6ea1SDimitry Andric if (RHS->isNegative()) 7819*0fca6ea1SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 78200b57cec5SDimitry Andric Pred = ICmpInst::ICMP_UGT; 78210b57cec5SDimitry Andric break; 78220b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: 78230b57cec5SDimitry Andric // (float)int >= -4.4 --> int >= -4 78240b57cec5SDimitry Andric // (float)int >= 4.4 --> int > 4 7825*0fca6ea1SDimitry Andric if (!RHS->isNegative()) 78260b57cec5SDimitry Andric Pred = ICmpInst::ICMP_SGT; 78270b57cec5SDimitry Andric break; 78280b57cec5SDimitry Andric } 78290b57cec5SDimitry Andric } 78300b57cec5SDimitry Andric } 78310b57cec5SDimitry Andric 78320b57cec5SDimitry Andric // Lower this FP comparison into an appropriate integer version of the 78330b57cec5SDimitry Andric // comparison. 7834*0fca6ea1SDimitry Andric return new ICmpInst(Pred, LHSI->getOperand(0), 7835*0fca6ea1SDimitry Andric ConstantInt::get(LHSI->getOperand(0)->getType(), RHSInt)); 78360b57cec5SDimitry Andric } 78370b57cec5SDimitry Andric 78380b57cec5SDimitry Andric /// Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary. 78390b57cec5SDimitry Andric static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI, 78400b57cec5SDimitry Andric Constant *RHSC) { 78410b57cec5SDimitry Andric // When C is not 0.0 and infinities are not allowed: 78420b57cec5SDimitry Andric // (C / X) < 0.0 is a sign-bit test of X 78430b57cec5SDimitry Andric // (C / X) < 0.0 --> X < 0.0 (if C is positive) 78440b57cec5SDimitry Andric // (C / X) < 0.0 --> X > 0.0 (if C is negative, swap the predicate) 78450b57cec5SDimitry Andric // 78460b57cec5SDimitry Andric // Proof: 78470b57cec5SDimitry Andric // Multiply (C / X) < 0.0 by X * X / C. 78480b57cec5SDimitry Andric // - X is non zero, if it is the flag 'ninf' is violated. 78490b57cec5SDimitry Andric // - C defines the sign of X * X * C. Thus it also defines whether to swap 78500b57cec5SDimitry Andric // the predicate. C is also non zero by definition. 78510b57cec5SDimitry Andric // 78520b57cec5SDimitry Andric // Thus X * X / C is non zero and the transformation is valid. [qed] 78530b57cec5SDimitry Andric 78540b57cec5SDimitry Andric FCmpInst::Predicate Pred = I.getPredicate(); 78550b57cec5SDimitry Andric 78560b57cec5SDimitry Andric // Check that predicates are valid. 78570b57cec5SDimitry Andric if ((Pred != FCmpInst::FCMP_OGT) && (Pred != FCmpInst::FCMP_OLT) && 78580b57cec5SDimitry Andric (Pred != FCmpInst::FCMP_OGE) && (Pred != FCmpInst::FCMP_OLE)) 78590b57cec5SDimitry Andric return nullptr; 78600b57cec5SDimitry Andric 78610b57cec5SDimitry Andric // Check that RHS operand is zero. 78620b57cec5SDimitry Andric if (!match(RHSC, m_AnyZeroFP())) 78630b57cec5SDimitry Andric return nullptr; 78640b57cec5SDimitry Andric 78650b57cec5SDimitry Andric // Check fastmath flags ('ninf'). 78660b57cec5SDimitry Andric if (!LHSI->hasNoInfs() || !I.hasNoInfs()) 78670b57cec5SDimitry Andric return nullptr; 78680b57cec5SDimitry Andric 78690b57cec5SDimitry Andric // Check the properties of the dividend. It must not be zero to avoid a 78700b57cec5SDimitry Andric // division by zero (see Proof). 78710b57cec5SDimitry Andric const APFloat *C; 78720b57cec5SDimitry Andric if (!match(LHSI->getOperand(0), m_APFloat(C))) 78730b57cec5SDimitry Andric return nullptr; 78740b57cec5SDimitry Andric 78750b57cec5SDimitry Andric if (C->isZero()) 78760b57cec5SDimitry Andric return nullptr; 78770b57cec5SDimitry Andric 78780b57cec5SDimitry Andric // Get swapped predicate if necessary. 78790b57cec5SDimitry Andric if (C->isNegative()) 78800b57cec5SDimitry Andric Pred = I.getSwappedPredicate(); 78810b57cec5SDimitry Andric 78820b57cec5SDimitry Andric return new FCmpInst(Pred, LHSI->getOperand(1), RHSC, "", &I); 78830b57cec5SDimitry Andric } 78840b57cec5SDimitry Andric 78850b57cec5SDimitry Andric /// Optimize fabs(X) compared with zero. 7886e8d8bef9SDimitry Andric static Instruction *foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC) { 78870b57cec5SDimitry Andric Value *X; 7888bdd1243dSDimitry Andric if (!match(I.getOperand(0), m_FAbs(m_Value(X)))) 78890b57cec5SDimitry Andric return nullptr; 78900b57cec5SDimitry Andric 7891bdd1243dSDimitry Andric const APFloat *C; 7892bdd1243dSDimitry Andric if (!match(I.getOperand(1), m_APFloat(C))) 7893bdd1243dSDimitry Andric return nullptr; 7894bdd1243dSDimitry Andric 7895bdd1243dSDimitry Andric if (!C->isPosZero()) { 7896bdd1243dSDimitry Andric if (!C->isSmallestNormalized()) 7897bdd1243dSDimitry Andric return nullptr; 7898bdd1243dSDimitry Andric 7899bdd1243dSDimitry Andric const Function *F = I.getFunction(); 7900bdd1243dSDimitry Andric DenormalMode Mode = F->getDenormalMode(C->getSemantics()); 7901bdd1243dSDimitry Andric if (Mode.Input == DenormalMode::PreserveSign || 7902bdd1243dSDimitry Andric Mode.Input == DenormalMode::PositiveZero) { 7903bdd1243dSDimitry Andric 7904bdd1243dSDimitry Andric auto replaceFCmp = [](FCmpInst *I, FCmpInst::Predicate P, Value *X) { 790506c3fb27SDimitry Andric Constant *Zero = ConstantFP::getZero(X->getType()); 7906bdd1243dSDimitry Andric return new FCmpInst(P, X, Zero, "", I); 7907bdd1243dSDimitry Andric }; 7908bdd1243dSDimitry Andric 7909bdd1243dSDimitry Andric switch (I.getPredicate()) { 7910bdd1243dSDimitry Andric case FCmpInst::FCMP_OLT: 7911bdd1243dSDimitry Andric // fcmp olt fabs(x), smallest_normalized_number -> fcmp oeq x, 0.0 7912bdd1243dSDimitry Andric return replaceFCmp(&I, FCmpInst::FCMP_OEQ, X); 7913bdd1243dSDimitry Andric case FCmpInst::FCMP_UGE: 7914bdd1243dSDimitry Andric // fcmp uge fabs(x), smallest_normalized_number -> fcmp une x, 0.0 7915bdd1243dSDimitry Andric return replaceFCmp(&I, FCmpInst::FCMP_UNE, X); 7916bdd1243dSDimitry Andric case FCmpInst::FCMP_OGE: 7917bdd1243dSDimitry Andric // fcmp oge fabs(x), smallest_normalized_number -> fcmp one x, 0.0 7918bdd1243dSDimitry Andric return replaceFCmp(&I, FCmpInst::FCMP_ONE, X); 7919bdd1243dSDimitry Andric case FCmpInst::FCMP_ULT: 7920bdd1243dSDimitry Andric // fcmp ult fabs(x), smallest_normalized_number -> fcmp ueq x, 0.0 7921bdd1243dSDimitry Andric return replaceFCmp(&I, FCmpInst::FCMP_UEQ, X); 7922bdd1243dSDimitry Andric default: 7923bdd1243dSDimitry Andric break; 7924bdd1243dSDimitry Andric } 7925bdd1243dSDimitry Andric } 7926bdd1243dSDimitry Andric 7927bdd1243dSDimitry Andric return nullptr; 7928bdd1243dSDimitry Andric } 7929bdd1243dSDimitry Andric 79305ffd83dbSDimitry Andric auto replacePredAndOp0 = [&IC](FCmpInst *I, FCmpInst::Predicate P, Value *X) { 79310b57cec5SDimitry Andric I->setPredicate(P); 79325ffd83dbSDimitry Andric return IC.replaceOperand(*I, 0, X); 79330b57cec5SDimitry Andric }; 79340b57cec5SDimitry Andric 79350b57cec5SDimitry Andric switch (I.getPredicate()) { 79360b57cec5SDimitry Andric case FCmpInst::FCMP_UGE: 79370b57cec5SDimitry Andric case FCmpInst::FCMP_OLT: 79380b57cec5SDimitry Andric // fabs(X) >= 0.0 --> true 79390b57cec5SDimitry Andric // fabs(X) < 0.0 --> false 79400b57cec5SDimitry Andric llvm_unreachable("fcmp should have simplified"); 79410b57cec5SDimitry Andric 79420b57cec5SDimitry Andric case FCmpInst::FCMP_OGT: 79430b57cec5SDimitry Andric // fabs(X) > 0.0 --> X != 0.0 79440b57cec5SDimitry Andric return replacePredAndOp0(&I, FCmpInst::FCMP_ONE, X); 79450b57cec5SDimitry Andric 79460b57cec5SDimitry Andric case FCmpInst::FCMP_UGT: 79470b57cec5SDimitry Andric // fabs(X) u> 0.0 --> X u!= 0.0 79480b57cec5SDimitry Andric return replacePredAndOp0(&I, FCmpInst::FCMP_UNE, X); 79490b57cec5SDimitry Andric 79500b57cec5SDimitry Andric case FCmpInst::FCMP_OLE: 79510b57cec5SDimitry Andric // fabs(X) <= 0.0 --> X == 0.0 79520b57cec5SDimitry Andric return replacePredAndOp0(&I, FCmpInst::FCMP_OEQ, X); 79530b57cec5SDimitry Andric 79540b57cec5SDimitry Andric case FCmpInst::FCMP_ULE: 79550b57cec5SDimitry Andric // fabs(X) u<= 0.0 --> X u== 0.0 79560b57cec5SDimitry Andric return replacePredAndOp0(&I, FCmpInst::FCMP_UEQ, X); 79570b57cec5SDimitry Andric 79580b57cec5SDimitry Andric case FCmpInst::FCMP_OGE: 79590b57cec5SDimitry Andric // fabs(X) >= 0.0 --> !isnan(X) 79600b57cec5SDimitry Andric assert(!I.hasNoNaNs() && "fcmp should have simplified"); 79610b57cec5SDimitry Andric return replacePredAndOp0(&I, FCmpInst::FCMP_ORD, X); 79620b57cec5SDimitry Andric 79630b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: 79640b57cec5SDimitry Andric // fabs(X) u< 0.0 --> isnan(X) 79650b57cec5SDimitry Andric assert(!I.hasNoNaNs() && "fcmp should have simplified"); 79660b57cec5SDimitry Andric return replacePredAndOp0(&I, FCmpInst::FCMP_UNO, X); 79670b57cec5SDimitry Andric 79680b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: 79690b57cec5SDimitry Andric case FCmpInst::FCMP_UEQ: 79700b57cec5SDimitry Andric case FCmpInst::FCMP_ONE: 79710b57cec5SDimitry Andric case FCmpInst::FCMP_UNE: 79720b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: 79730b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: 79740b57cec5SDimitry Andric // Look through the fabs() because it doesn't change anything but the sign. 79750b57cec5SDimitry Andric // fabs(X) == 0.0 --> X == 0.0, 79760b57cec5SDimitry Andric // fabs(X) != 0.0 --> X != 0.0 79770b57cec5SDimitry Andric // isnan(fabs(X)) --> isnan(X) 79780b57cec5SDimitry Andric // !isnan(fabs(X) --> !isnan(X) 79790b57cec5SDimitry Andric return replacePredAndOp0(&I, I.getPredicate(), X); 79800b57cec5SDimitry Andric 79810b57cec5SDimitry Andric default: 79820b57cec5SDimitry Andric return nullptr; 79830b57cec5SDimitry Andric } 79840b57cec5SDimitry Andric } 79850b57cec5SDimitry Andric 798681ad6265SDimitry Andric static Instruction *foldFCmpFNegCommonOp(FCmpInst &I) { 798781ad6265SDimitry Andric CmpInst::Predicate Pred = I.getPredicate(); 798881ad6265SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 798981ad6265SDimitry Andric 799081ad6265SDimitry Andric // Canonicalize fneg as Op1. 799181ad6265SDimitry Andric if (match(Op0, m_FNeg(m_Value())) && !match(Op1, m_FNeg(m_Value()))) { 799281ad6265SDimitry Andric std::swap(Op0, Op1); 799381ad6265SDimitry Andric Pred = I.getSwappedPredicate(); 799481ad6265SDimitry Andric } 799581ad6265SDimitry Andric 799681ad6265SDimitry Andric if (!match(Op1, m_FNeg(m_Specific(Op0)))) 799781ad6265SDimitry Andric return nullptr; 799881ad6265SDimitry Andric 799981ad6265SDimitry Andric // Replace the negated operand with 0.0: 800081ad6265SDimitry Andric // fcmp Pred Op0, -Op0 --> fcmp Pred Op0, 0.0 800106c3fb27SDimitry Andric Constant *Zero = ConstantFP::getZero(Op0->getType()); 800281ad6265SDimitry Andric return new FCmpInst(Pred, Op0, Zero, "", &I); 800381ad6265SDimitry Andric } 800481ad6265SDimitry Andric 8005*0fca6ea1SDimitry Andric static Instruction *foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI, 8006*0fca6ea1SDimitry Andric Constant *RHSC, InstCombinerImpl &CI) { 8007*0fca6ea1SDimitry Andric const CmpInst::Predicate Pred = I.getPredicate(); 8008*0fca6ea1SDimitry Andric Value *X = LHSI->getOperand(0); 8009*0fca6ea1SDimitry Andric Value *Y = LHSI->getOperand(1); 8010*0fca6ea1SDimitry Andric switch (Pred) { 8011*0fca6ea1SDimitry Andric default: 8012*0fca6ea1SDimitry Andric break; 8013*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UGT: 8014*0fca6ea1SDimitry Andric case FCmpInst::FCMP_ULT: 8015*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UNE: 8016*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OEQ: 8017*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OGE: 8018*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OLE: 8019*0fca6ea1SDimitry Andric // The optimization is not valid if X and Y are infinities of the same 8020*0fca6ea1SDimitry Andric // sign, i.e. the inf - inf = nan case. If the fsub has the ninf or nnan 8021*0fca6ea1SDimitry Andric // flag then we can assume we do not have that case. Otherwise we might be 8022*0fca6ea1SDimitry Andric // able to prove that either X or Y is not infinity. 8023*0fca6ea1SDimitry Andric if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() && 8024*0fca6ea1SDimitry Andric !isKnownNeverInfinity(Y, /*Depth=*/0, 8025*0fca6ea1SDimitry Andric CI.getSimplifyQuery().getWithInstruction(&I)) && 8026*0fca6ea1SDimitry Andric !isKnownNeverInfinity(X, /*Depth=*/0, 8027*0fca6ea1SDimitry Andric CI.getSimplifyQuery().getWithInstruction(&I))) 8028*0fca6ea1SDimitry Andric break; 8029*0fca6ea1SDimitry Andric 8030*0fca6ea1SDimitry Andric [[fallthrough]]; 8031*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OGT: 8032*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OLT: 8033*0fca6ea1SDimitry Andric case FCmpInst::FCMP_ONE: 8034*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UEQ: 8035*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UGE: 8036*0fca6ea1SDimitry Andric case FCmpInst::FCMP_ULE: 8037*0fca6ea1SDimitry Andric // fcmp pred (x - y), 0 --> fcmp pred x, y 8038*0fca6ea1SDimitry Andric if (match(RHSC, m_AnyZeroFP()) && 8039*0fca6ea1SDimitry Andric I.getFunction()->getDenormalMode( 8040*0fca6ea1SDimitry Andric LHSI->getType()->getScalarType()->getFltSemantics()) == 8041*0fca6ea1SDimitry Andric DenormalMode::getIEEE()) { 8042*0fca6ea1SDimitry Andric CI.replaceOperand(I, 0, X); 8043*0fca6ea1SDimitry Andric CI.replaceOperand(I, 1, Y); 8044*0fca6ea1SDimitry Andric return &I; 8045*0fca6ea1SDimitry Andric } 8046*0fca6ea1SDimitry Andric break; 8047*0fca6ea1SDimitry Andric } 8048*0fca6ea1SDimitry Andric 8049*0fca6ea1SDimitry Andric return nullptr; 8050*0fca6ea1SDimitry Andric } 8051*0fca6ea1SDimitry Andric 8052e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) { 80530b57cec5SDimitry Andric bool Changed = false; 80540b57cec5SDimitry Andric 80550b57cec5SDimitry Andric /// Orders the operands of the compare so that they are listed from most 80560b57cec5SDimitry Andric /// complex to least complex. This puts constants before unary operators, 80570b57cec5SDimitry Andric /// before binary operators. 80580b57cec5SDimitry Andric if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1))) { 80590b57cec5SDimitry Andric I.swapOperands(); 80600b57cec5SDimitry Andric Changed = true; 80610b57cec5SDimitry Andric } 80620b57cec5SDimitry Andric 80630b57cec5SDimitry Andric const CmpInst::Predicate Pred = I.getPredicate(); 80640b57cec5SDimitry Andric Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 806581ad6265SDimitry Andric if (Value *V = simplifyFCmpInst(Pred, Op0, Op1, I.getFastMathFlags(), 80660b57cec5SDimitry Andric SQ.getWithInstruction(&I))) 80670b57cec5SDimitry Andric return replaceInstUsesWith(I, V); 80680b57cec5SDimitry Andric 80690b57cec5SDimitry Andric // Simplify 'fcmp pred X, X' 80700b57cec5SDimitry Andric Type *OpType = Op0->getType(); 80710b57cec5SDimitry Andric assert(OpType == Op1->getType() && "fcmp with different-typed operands?"); 80720b57cec5SDimitry Andric if (Op0 == Op1) { 80730b57cec5SDimitry Andric switch (Pred) { 80740b57cec5SDimitry Andric default: break; 80750b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: // True if unordered: isnan(X) | isnan(Y) 80760b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: // True if unordered or less than 80770b57cec5SDimitry Andric case FCmpInst::FCMP_UGT: // True if unordered or greater than 80780b57cec5SDimitry Andric case FCmpInst::FCMP_UNE: // True if unordered or not equal 80790b57cec5SDimitry Andric // Canonicalize these to be 'fcmp uno %X, 0.0'. 80800b57cec5SDimitry Andric I.setPredicate(FCmpInst::FCMP_UNO); 80810b57cec5SDimitry Andric I.setOperand(1, Constant::getNullValue(OpType)); 80820b57cec5SDimitry Andric return &I; 80830b57cec5SDimitry Andric 80840b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: // True if ordered (no nans) 80850b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: // True if ordered and equal 80860b57cec5SDimitry Andric case FCmpInst::FCMP_OGE: // True if ordered and greater than or equal 80870b57cec5SDimitry Andric case FCmpInst::FCMP_OLE: // True if ordered and less than or equal 80880b57cec5SDimitry Andric // Canonicalize these to be 'fcmp ord %X, 0.0'. 80890b57cec5SDimitry Andric I.setPredicate(FCmpInst::FCMP_ORD); 80900b57cec5SDimitry Andric I.setOperand(1, Constant::getNullValue(OpType)); 80910b57cec5SDimitry Andric return &I; 80920b57cec5SDimitry Andric } 80930b57cec5SDimitry Andric } 80940b57cec5SDimitry Andric 8095*0fca6ea1SDimitry Andric if (I.isCommutative()) { 8096*0fca6ea1SDimitry Andric if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) { 8097*0fca6ea1SDimitry Andric replaceOperand(I, 0, Pair->first); 8098*0fca6ea1SDimitry Andric replaceOperand(I, 1, Pair->second); 8099*0fca6ea1SDimitry Andric return &I; 8100*0fca6ea1SDimitry Andric } 8101*0fca6ea1SDimitry Andric } 8102*0fca6ea1SDimitry Andric 81030b57cec5SDimitry Andric // If we're just checking for a NaN (ORD/UNO) and have a non-NaN operand, 81040b57cec5SDimitry Andric // then canonicalize the operand to 0.0. 81050b57cec5SDimitry Andric if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) { 8106*0fca6ea1SDimitry Andric if (!match(Op0, m_PosZeroFP()) && 8107*0fca6ea1SDimitry Andric isKnownNeverNaN(Op0, 0, getSimplifyQuery().getWithInstruction(&I))) 810806c3fb27SDimitry Andric return replaceOperand(I, 0, ConstantFP::getZero(OpType)); 81095ffd83dbSDimitry Andric 811006c3fb27SDimitry Andric if (!match(Op1, m_PosZeroFP()) && 8111*0fca6ea1SDimitry Andric isKnownNeverNaN(Op1, 0, getSimplifyQuery().getWithInstruction(&I))) 811206c3fb27SDimitry Andric return replaceOperand(I, 1, ConstantFP::getZero(OpType)); 81130b57cec5SDimitry Andric } 81140b57cec5SDimitry Andric 81150b57cec5SDimitry Andric // fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y 81160b57cec5SDimitry Andric Value *X, *Y; 81170b57cec5SDimitry Andric if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) 81180b57cec5SDimitry Andric return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I); 81190b57cec5SDimitry Andric 812081ad6265SDimitry Andric if (Instruction *R = foldFCmpFNegCommonOp(I)) 812181ad6265SDimitry Andric return R; 812281ad6265SDimitry Andric 81230b57cec5SDimitry Andric // Test if the FCmpInst instruction is used exclusively by a select as 81240b57cec5SDimitry Andric // part of a minimum or maximum operation. If so, refrain from doing 81250b57cec5SDimitry Andric // any other folding. This helps out other analyses which understand 81260b57cec5SDimitry Andric // non-obfuscated minimum and maximum idioms, such as ScalarEvolution 81270b57cec5SDimitry Andric // and CodeGen. And in this case, at least one of the comparison 81280b57cec5SDimitry Andric // operands has at least one user besides the compare (the select), 81290b57cec5SDimitry Andric // which would often largely negate the benefit of folding anyway. 81300b57cec5SDimitry Andric if (I.hasOneUse()) 81310b57cec5SDimitry Andric if (SelectInst *SI = dyn_cast<SelectInst>(I.user_back())) { 81320b57cec5SDimitry Andric Value *A, *B; 81330b57cec5SDimitry Andric SelectPatternResult SPR = matchSelectPattern(SI, A, B); 81340b57cec5SDimitry Andric if (SPR.Flavor != SPF_UNKNOWN) 81350b57cec5SDimitry Andric return nullptr; 81360b57cec5SDimitry Andric } 81370b57cec5SDimitry Andric 81380b57cec5SDimitry Andric // The sign of 0.0 is ignored by fcmp, so canonicalize to +0.0: 81390b57cec5SDimitry Andric // fcmp Pred X, -0.0 --> fcmp Pred X, 0.0 81405ffd83dbSDimitry Andric if (match(Op1, m_AnyZeroFP()) && !match(Op1, m_PosZeroFP())) 814106c3fb27SDimitry Andric return replaceOperand(I, 1, ConstantFP::getZero(OpType)); 81420b57cec5SDimitry Andric 8143*0fca6ea1SDimitry Andric // Canonicalize: 8144*0fca6ea1SDimitry Andric // fcmp olt X, +inf -> fcmp one X, +inf 8145*0fca6ea1SDimitry Andric // fcmp ole X, +inf -> fcmp ord X, 0 8146*0fca6ea1SDimitry Andric // fcmp ogt X, +inf -> false 8147*0fca6ea1SDimitry Andric // fcmp oge X, +inf -> fcmp oeq X, +inf 8148*0fca6ea1SDimitry Andric // fcmp ult X, +inf -> fcmp une X, +inf 8149*0fca6ea1SDimitry Andric // fcmp ule X, +inf -> true 8150*0fca6ea1SDimitry Andric // fcmp ugt X, +inf -> fcmp uno X, 0 8151*0fca6ea1SDimitry Andric // fcmp uge X, +inf -> fcmp ueq X, +inf 8152*0fca6ea1SDimitry Andric // fcmp olt X, -inf -> false 8153*0fca6ea1SDimitry Andric // fcmp ole X, -inf -> fcmp oeq X, -inf 8154*0fca6ea1SDimitry Andric // fcmp ogt X, -inf -> fcmp one X, -inf 8155*0fca6ea1SDimitry Andric // fcmp oge X, -inf -> fcmp ord X, 0 8156*0fca6ea1SDimitry Andric // fcmp ult X, -inf -> fcmp uno X, 0 8157*0fca6ea1SDimitry Andric // fcmp ule X, -inf -> fcmp ueq X, -inf 8158*0fca6ea1SDimitry Andric // fcmp ugt X, -inf -> fcmp une X, -inf 8159*0fca6ea1SDimitry Andric // fcmp uge X, -inf -> true 8160*0fca6ea1SDimitry Andric const APFloat *C; 8161*0fca6ea1SDimitry Andric if (match(Op1, m_APFloat(C)) && C->isInfinity()) { 8162*0fca6ea1SDimitry Andric switch (C->isNegative() ? FCmpInst::getSwappedPredicate(Pred) : Pred) { 8163*0fca6ea1SDimitry Andric default: 8164*0fca6ea1SDimitry Andric break; 8165*0fca6ea1SDimitry Andric case FCmpInst::FCMP_ORD: 8166*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UNO: 8167*0fca6ea1SDimitry Andric case FCmpInst::FCMP_TRUE: 8168*0fca6ea1SDimitry Andric case FCmpInst::FCMP_FALSE: 8169*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OGT: 8170*0fca6ea1SDimitry Andric case FCmpInst::FCMP_ULE: 8171*0fca6ea1SDimitry Andric llvm_unreachable("Should be simplified by InstSimplify"); 8172*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OLT: 8173*0fca6ea1SDimitry Andric return new FCmpInst(FCmpInst::FCMP_ONE, Op0, Op1, "", &I); 8174*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OLE: 8175*0fca6ea1SDimitry Andric return new FCmpInst(FCmpInst::FCMP_ORD, Op0, ConstantFP::getZero(OpType), 8176*0fca6ea1SDimitry Andric "", &I); 8177*0fca6ea1SDimitry Andric case FCmpInst::FCMP_OGE: 8178*0fca6ea1SDimitry Andric return new FCmpInst(FCmpInst::FCMP_OEQ, Op0, Op1, "", &I); 8179*0fca6ea1SDimitry Andric case FCmpInst::FCMP_ULT: 8180*0fca6ea1SDimitry Andric return new FCmpInst(FCmpInst::FCMP_UNE, Op0, Op1, "", &I); 8181*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UGT: 8182*0fca6ea1SDimitry Andric return new FCmpInst(FCmpInst::FCMP_UNO, Op0, ConstantFP::getZero(OpType), 8183*0fca6ea1SDimitry Andric "", &I); 8184*0fca6ea1SDimitry Andric case FCmpInst::FCMP_UGE: 8185*0fca6ea1SDimitry Andric return new FCmpInst(FCmpInst::FCMP_UEQ, Op0, Op1, "", &I); 8186*0fca6ea1SDimitry Andric } 8187*0fca6ea1SDimitry Andric } 8188*0fca6ea1SDimitry Andric 8189bdd1243dSDimitry Andric // Ignore signbit of bitcasted int when comparing equality to FP 0.0: 8190bdd1243dSDimitry Andric // fcmp oeq/une (bitcast X), 0.0 --> (and X, SignMaskC) ==/!= 0 8191bdd1243dSDimitry Andric if (match(Op1, m_PosZeroFP()) && 8192*0fca6ea1SDimitry Andric match(Op0, m_OneUse(m_ElementWiseBitCast(m_Value(X))))) { 8193bdd1243dSDimitry Andric ICmpInst::Predicate IntPred = ICmpInst::BAD_ICMP_PREDICATE; 8194bdd1243dSDimitry Andric if (Pred == FCmpInst::FCMP_OEQ) 8195bdd1243dSDimitry Andric IntPred = ICmpInst::ICMP_EQ; 8196bdd1243dSDimitry Andric else if (Pred == FCmpInst::FCMP_UNE) 8197bdd1243dSDimitry Andric IntPred = ICmpInst::ICMP_NE; 8198bdd1243dSDimitry Andric 8199bdd1243dSDimitry Andric if (IntPred != ICmpInst::BAD_ICMP_PREDICATE) { 8200bdd1243dSDimitry Andric Type *IntTy = X->getType(); 8201bdd1243dSDimitry Andric const APInt &SignMask = ~APInt::getSignMask(IntTy->getScalarSizeInBits()); 8202bdd1243dSDimitry Andric Value *MaskX = Builder.CreateAnd(X, ConstantInt::get(IntTy, SignMask)); 8203bdd1243dSDimitry Andric return new ICmpInst(IntPred, MaskX, ConstantInt::getNullValue(IntTy)); 8204bdd1243dSDimitry Andric } 8205bdd1243dSDimitry Andric } 8206bdd1243dSDimitry Andric 82070b57cec5SDimitry Andric // Handle fcmp with instruction LHS and constant RHS. 82080b57cec5SDimitry Andric Instruction *LHSI; 82090b57cec5SDimitry Andric Constant *RHSC; 82100b57cec5SDimitry Andric if (match(Op0, m_Instruction(LHSI)) && match(Op1, m_Constant(RHSC))) { 82110b57cec5SDimitry Andric switch (LHSI->getOpcode()) { 8212*0fca6ea1SDimitry Andric case Instruction::Select: 8213*0fca6ea1SDimitry Andric // fcmp eq (cond ? x : -x), 0 --> fcmp eq x, 0 8214*0fca6ea1SDimitry Andric if (FCmpInst::isEquality(Pred) && match(RHSC, m_AnyZeroFP()) && 8215*0fca6ea1SDimitry Andric (match(LHSI, 8216*0fca6ea1SDimitry Andric m_Select(m_Value(), m_Value(X), m_FNeg(m_Deferred(X)))) || 8217*0fca6ea1SDimitry Andric match(LHSI, m_Select(m_Value(), m_FNeg(m_Value(X)), m_Deferred(X))))) 8218*0fca6ea1SDimitry Andric return replaceOperand(I, 0, X); 8219*0fca6ea1SDimitry Andric if (Instruction *NV = FoldOpIntoSelect(I, cast<SelectInst>(LHSI))) 8220*0fca6ea1SDimitry Andric return NV; 8221*0fca6ea1SDimitry Andric break; 8222*0fca6ea1SDimitry Andric case Instruction::FSub: 8223*0fca6ea1SDimitry Andric if (LHSI->hasOneUse()) 8224*0fca6ea1SDimitry Andric if (Instruction *NV = foldFCmpFSubIntoFCmp(I, LHSI, RHSC, *this)) 8225*0fca6ea1SDimitry Andric return NV; 8226*0fca6ea1SDimitry Andric break; 82270b57cec5SDimitry Andric case Instruction::PHI: 82280b57cec5SDimitry Andric if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI))) 82290b57cec5SDimitry Andric return NV; 82300b57cec5SDimitry Andric break; 82310b57cec5SDimitry Andric case Instruction::SIToFP: 82320b57cec5SDimitry Andric case Instruction::UIToFP: 82330b57cec5SDimitry Andric if (Instruction *NV = foldFCmpIntToFPConst(I, LHSI, RHSC)) 82340b57cec5SDimitry Andric return NV; 82350b57cec5SDimitry Andric break; 82360b57cec5SDimitry Andric case Instruction::FDiv: 82370b57cec5SDimitry Andric if (Instruction *NV = foldFCmpReciprocalAndZero(I, LHSI, RHSC)) 82380b57cec5SDimitry Andric return NV; 82390b57cec5SDimitry Andric break; 82400b57cec5SDimitry Andric case Instruction::Load: 82410b57cec5SDimitry Andric if (auto *GEP = dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) 82420b57cec5SDimitry Andric if (auto *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0))) 824381ad6265SDimitry Andric if (Instruction *Res = foldCmpLoadFromIndexedGlobal( 824481ad6265SDimitry Andric cast<LoadInst>(LHSI), GEP, GV, I)) 82450b57cec5SDimitry Andric return Res; 82460b57cec5SDimitry Andric break; 82470b57cec5SDimitry Andric } 82480b57cec5SDimitry Andric } 82490b57cec5SDimitry Andric 82505ffd83dbSDimitry Andric if (Instruction *R = foldFabsWithFcmpZero(I, *this)) 82510b57cec5SDimitry Andric return R; 82520b57cec5SDimitry Andric 82530b57cec5SDimitry Andric if (match(Op0, m_FNeg(m_Value(X)))) { 82540b57cec5SDimitry Andric // fcmp pred (fneg X), C --> fcmp swap(pred) X, -C 82550b57cec5SDimitry Andric Constant *C; 8256bdd1243dSDimitry Andric if (match(Op1, m_Constant(C))) 8257bdd1243dSDimitry Andric if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) 82580b57cec5SDimitry Andric return new FCmpInst(I.getSwappedPredicate(), X, NegC, "", &I); 82590b57cec5SDimitry Andric } 82600b57cec5SDimitry Andric 8261*0fca6ea1SDimitry Andric // fcmp (fadd X, 0.0), Y --> fcmp X, Y 8262*0fca6ea1SDimitry Andric if (match(Op0, m_FAdd(m_Value(X), m_AnyZeroFP()))) 8263*0fca6ea1SDimitry Andric return new FCmpInst(Pred, X, Op1, "", &I); 8264*0fca6ea1SDimitry Andric 8265*0fca6ea1SDimitry Andric // fcmp X, (fadd Y, 0.0) --> fcmp X, Y 8266*0fca6ea1SDimitry Andric if (match(Op1, m_FAdd(m_Value(Y), m_AnyZeroFP()))) 8267*0fca6ea1SDimitry Andric return new FCmpInst(Pred, Op0, Y, "", &I); 8268*0fca6ea1SDimitry Andric 82690b57cec5SDimitry Andric if (match(Op0, m_FPExt(m_Value(X)))) { 82700b57cec5SDimitry Andric // fcmp (fpext X), (fpext Y) -> fcmp X, Y 82710b57cec5SDimitry Andric if (match(Op1, m_FPExt(m_Value(Y))) && X->getType() == Y->getType()) 82720b57cec5SDimitry Andric return new FCmpInst(Pred, X, Y, "", &I); 82730b57cec5SDimitry Andric 82740b57cec5SDimitry Andric const APFloat *C; 82750b57cec5SDimitry Andric if (match(Op1, m_APFloat(C))) { 82760b57cec5SDimitry Andric const fltSemantics &FPSem = 82770b57cec5SDimitry Andric X->getType()->getScalarType()->getFltSemantics(); 82780b57cec5SDimitry Andric bool Lossy; 82790b57cec5SDimitry Andric APFloat TruncC = *C; 82800b57cec5SDimitry Andric TruncC.convert(FPSem, APFloat::rmNearestTiesToEven, &Lossy); 82810b57cec5SDimitry Andric 828281ad6265SDimitry Andric if (Lossy) { 828381ad6265SDimitry Andric // X can't possibly equal the higher-precision constant, so reduce any 828481ad6265SDimitry Andric // equality comparison. 828581ad6265SDimitry Andric // TODO: Other predicates can be handled via getFCmpCode(). 828681ad6265SDimitry Andric switch (Pred) { 828781ad6265SDimitry Andric case FCmpInst::FCMP_OEQ: 828881ad6265SDimitry Andric // X is ordered and equal to an impossible constant --> false 828981ad6265SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); 829081ad6265SDimitry Andric case FCmpInst::FCMP_ONE: 829181ad6265SDimitry Andric // X is ordered and not equal to an impossible constant --> ordered 829281ad6265SDimitry Andric return new FCmpInst(FCmpInst::FCMP_ORD, X, 829306c3fb27SDimitry Andric ConstantFP::getZero(X->getType())); 829481ad6265SDimitry Andric case FCmpInst::FCMP_UEQ: 829581ad6265SDimitry Andric // X is unordered or equal to an impossible constant --> unordered 829681ad6265SDimitry Andric return new FCmpInst(FCmpInst::FCMP_UNO, X, 829706c3fb27SDimitry Andric ConstantFP::getZero(X->getType())); 829881ad6265SDimitry Andric case FCmpInst::FCMP_UNE: 829981ad6265SDimitry Andric // X is unordered or not equal to an impossible constant --> true 830081ad6265SDimitry Andric return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); 830181ad6265SDimitry Andric default: 830281ad6265SDimitry Andric break; 830381ad6265SDimitry Andric } 830481ad6265SDimitry Andric } 830581ad6265SDimitry Andric 830681ad6265SDimitry Andric // fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless 83070b57cec5SDimitry Andric // Avoid lossy conversions and denormals. 83080b57cec5SDimitry Andric // Zero is a special case that's OK to convert. 83090b57cec5SDimitry Andric APFloat Fabs = TruncC; 83100b57cec5SDimitry Andric Fabs.clearSign(); 83110b57cec5SDimitry Andric if (!Lossy && 8312bdd1243dSDimitry Andric (Fabs.isZero() || !(Fabs < APFloat::getSmallestNormalized(FPSem)))) { 83130b57cec5SDimitry Andric Constant *NewC = ConstantFP::get(X->getType(), TruncC); 83140b57cec5SDimitry Andric return new FCmpInst(Pred, X, NewC, "", &I); 83150b57cec5SDimitry Andric } 83160b57cec5SDimitry Andric } 83170b57cec5SDimitry Andric } 83180b57cec5SDimitry Andric 8319fe6060f1SDimitry Andric // Convert a sign-bit test of an FP value into a cast and integer compare. 8320fe6060f1SDimitry Andric // TODO: Simplify if the copysign constant is 0.0 or NaN. 8321fe6060f1SDimitry Andric // TODO: Handle non-zero compare constants. 8322fe6060f1SDimitry Andric // TODO: Handle other predicates. 8323fe6060f1SDimitry Andric if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::copysign>(m_APFloat(C), 8324fe6060f1SDimitry Andric m_Value(X)))) && 8325fe6060f1SDimitry Andric match(Op1, m_AnyZeroFP()) && !C->isZero() && !C->isNaN()) { 8326fe6060f1SDimitry Andric Type *IntType = Builder.getIntNTy(X->getType()->getScalarSizeInBits()); 8327fe6060f1SDimitry Andric if (auto *VecTy = dyn_cast<VectorType>(OpType)) 8328fe6060f1SDimitry Andric IntType = VectorType::get(IntType, VecTy->getElementCount()); 8329fe6060f1SDimitry Andric 8330fe6060f1SDimitry Andric // copysign(non-zero constant, X) < 0.0 --> (bitcast X) < 0 8331fe6060f1SDimitry Andric if (Pred == FCmpInst::FCMP_OLT) { 8332fe6060f1SDimitry Andric Value *IntX = Builder.CreateBitCast(X, IntType); 8333fe6060f1SDimitry Andric return new ICmpInst(ICmpInst::ICMP_SLT, IntX, 8334fe6060f1SDimitry Andric ConstantInt::getNullValue(IntType)); 8335fe6060f1SDimitry Andric } 8336fe6060f1SDimitry Andric } 8337fe6060f1SDimitry Andric 8338bdd1243dSDimitry Andric { 8339bdd1243dSDimitry Andric Value *CanonLHS = nullptr, *CanonRHS = nullptr; 8340bdd1243dSDimitry Andric match(Op0, m_Intrinsic<Intrinsic::canonicalize>(m_Value(CanonLHS))); 8341bdd1243dSDimitry Andric match(Op1, m_Intrinsic<Intrinsic::canonicalize>(m_Value(CanonRHS))); 8342bdd1243dSDimitry Andric 8343bdd1243dSDimitry Andric // (canonicalize(x) == x) => (x == x) 8344bdd1243dSDimitry Andric if (CanonLHS == Op1) 8345bdd1243dSDimitry Andric return new FCmpInst(Pred, Op1, Op1, "", &I); 8346bdd1243dSDimitry Andric 8347bdd1243dSDimitry Andric // (x == canonicalize(x)) => (x == x) 8348bdd1243dSDimitry Andric if (CanonRHS == Op0) 8349bdd1243dSDimitry Andric return new FCmpInst(Pred, Op0, Op0, "", &I); 8350bdd1243dSDimitry Andric 8351bdd1243dSDimitry Andric // (canonicalize(x) == canonicalize(y)) => (x == y) 8352bdd1243dSDimitry Andric if (CanonLHS && CanonRHS) 8353bdd1243dSDimitry Andric return new FCmpInst(Pred, CanonLHS, CanonRHS, "", &I); 8354bdd1243dSDimitry Andric } 8355bdd1243dSDimitry Andric 83560b57cec5SDimitry Andric if (I.getType()->isVectorTy()) 83570b57cec5SDimitry Andric if (Instruction *Res = foldVectorCmp(I, Builder)) 83580b57cec5SDimitry Andric return Res; 83590b57cec5SDimitry Andric 83600b57cec5SDimitry Andric return Changed ? &I : nullptr; 83610b57cec5SDimitry Andric } 8362