xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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